relocate_kernel.S 1.4 KB

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