relocate_kernel.S 1.3 KB

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