102 lines
1.6 KiB
ArmAsm
102 lines
1.6 KiB
ArmAsm
/*
|
|
* relocate_kernel.S - put the kernel image in place to boot
|
|
*/
|
|
|
|
#include <asm/kexec.h>
|
|
|
|
.globl relocate_new_kernel
|
|
relocate_new_kernel:
|
|
|
|
/* Move boot params back to where the kernel expects them */
|
|
|
|
ldr r0,kexec_boot_params_address
|
|
teq r0,#0
|
|
beq 8f
|
|
|
|
ldr r1,kexec_boot_params_copy
|
|
mov r6,#KEXEC_BOOT_PARAMS_SIZE/4
|
|
7:
|
|
ldr r5,[r1],#4
|
|
str r5,[r0],#4
|
|
subs r6,r6,#1
|
|
bne 7b
|
|
|
|
8:
|
|
/* Boot params moved, now go on with the kernel */
|
|
|
|
ldr r0,kexec_indirection_page
|
|
ldr r1,kexec_start_address
|
|
|
|
|
|
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_params_address
|
|
mov pc,lr
|
|
|
|
.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 where new kernel will expect to find boot params */
|
|
.globl kexec_boot_params_address
|
|
kexec_boot_params_address:
|
|
.long 0x0
|
|
|
|
/* phy addr where old kernel put a copy of orig boot params */
|
|
.globl kexec_boot_params_copy
|
|
kexec_boot_params_copy:
|
|
.long 0x0
|
|
|
|
relocate_new_kernel_end:
|
|
|
|
.globl relocate_new_kernel_size
|
|
relocate_new_kernel_size:
|
|
.long relocate_new_kernel_end - relocate_new_kernel
|
|
|
|
|