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. mov pc,lr
  52. .align
  53. .globl kexec_start_address
  54. kexec_start_address:
  55. .long 0x0
  56. .globl kexec_indirection_page
  57. kexec_indirection_page:
  58. .long 0x0
  59. .globl kexec_mach_type
  60. kexec_mach_type:
  61. .long 0x0
  62. /* phy addr of the atags for the new kernel */
  63. .globl kexec_boot_atags
  64. kexec_boot_atags:
  65. .long 0x0
  66. relocate_new_kernel_end:
  67. .globl relocate_new_kernel_size
  68. relocate_new_kernel_size:
  69. .long relocate_new_kernel_end - relocate_new_kernel