/* | |
* relocate_kernel.S - put the kernel image in place to boot | |
*/ | |
#include <asm/kexec.h> | |
.globl relocate_new_kernel | |
relocate_new_kernel: | |
ldr r0,kexec_indirection_page | |
ldr r1,kexec_start_address | |
/* | |
* If there is no indirection page (we are doing crashdumps) | |
* skip any relocation. | |
*/ | |
cmp r0, #0 | |
beq 2f | |
0: /* top, read another word for the indirection page */ | |
ldr r3, [r0],#4 | |
/* Is it a destination page. Put destination address to r4 */ | |
tst r3,#1,0 | |
beq 1f | |
bic r4,r3,#1 | |
b 0b | |
1: | |
/* Is it an indirection page */ | |
tst r3,#2,0 | |
beq 1f | |
bic r0,r3,#2 | |
b 0b | |
1: | |
/* are we done ? */ | |
tst r3,#4,0 | |
beq 1f | |
b 2f | |
1: | |
/* is it source ? */ | |
tst r3,#8,0 | |
beq 0b | |
bic r3,r3,#8 | |
mov r6,#1024 | |
9: | |
ldr r5,[r3],#4 | |
str r5,[r4],#4 | |
subs r6,r6,#1 | |
bne 9b | |
b 0b | |
2: | |
/* Jump to relocated kernel */ | |
mov lr,r1 | |
mov r0,#0 | |
ldr r1,kexec_mach_type | |
ldr r2,kexec_boot_atags | |
ARM( mov pc, lr ) | |
THUMB( bx lr ) | |
.align | |
.globl kexec_start_address | |
kexec_start_address: | |
.long 0x0 | |
.globl kexec_indirection_page | |
kexec_indirection_page: | |
.long 0x0 | |
.globl kexec_mach_type | |
kexec_mach_type: | |
.long 0x0 | |
/* phy addr of the atags for the new kernel */ | |
.globl kexec_boot_atags | |
kexec_boot_atags: | |
.long 0x0 | |
relocate_new_kernel_end: | |
.globl relocate_new_kernel_size | |
relocate_new_kernel_size: | |
.long relocate_new_kernel_end - relocate_new_kernel | |