relocate_kernel.S 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. * relocate_kernel.S - put the kernel image in place to boot
  3. */
  4. #include <linux/linkage.h>
  5. #include <asm/assembler.h>
  6. #include <asm/kexec.h>
  7. .align 3 /* not needed for this code, but keeps fncpy() happy */
  8. ENTRY(relocate_new_kernel)
  9. ldr r0,kexec_indirection_page
  10. ldr r1,kexec_start_address
  11. /*
  12. * If there is no indirection page (we are doing crashdumps)
  13. * skip any relocation.
  14. */
  15. cmp r0, #0
  16. beq 2f
  17. 0: /* top, read another word for the indirection page */
  18. ldr r3, [r0],#4
  19. /* Is it a destination page. Put destination address to r4 */
  20. tst r3,#1,0
  21. beq 1f
  22. bic r4,r3,#1
  23. b 0b
  24. 1:
  25. /* Is it an indirection page */
  26. tst r3,#2,0
  27. beq 1f
  28. bic r0,r3,#2
  29. b 0b
  30. 1:
  31. /* are we done ? */
  32. tst r3,#4,0
  33. beq 1f
  34. b 2f
  35. 1:
  36. /* is it source ? */
  37. tst r3,#8,0
  38. beq 0b
  39. bic r3,r3,#8
  40. mov r6,#1024
  41. 9:
  42. ldr r5,[r3],#4
  43. str r5,[r4],#4
  44. subs r6,r6,#1
  45. bne 9b
  46. b 0b
  47. 2:
  48. /* Jump to relocated kernel */
  49. mov lr,r1
  50. mov r0,#0
  51. ldr r1,kexec_mach_type
  52. ldr r2,kexec_boot_atags
  53. ARM( ret lr )
  54. THUMB( bx lr )
  55. .align
  56. .globl kexec_start_address
  57. kexec_start_address:
  58. .long 0x0
  59. .globl kexec_indirection_page
  60. kexec_indirection_page:
  61. .long 0x0
  62. .globl kexec_mach_type
  63. kexec_mach_type:
  64. .long 0x0
  65. /* phy addr of the atags for the new kernel */
  66. .globl kexec_boot_atags
  67. kexec_boot_atags:
  68. .long 0x0
  69. ENDPROC(relocate_new_kernel)
  70. relocate_new_kernel_end:
  71. .globl relocate_new_kernel_size
  72. relocate_new_kernel_size:
  73. .long relocate_new_kernel_end - relocate_new_kernel