blob: 4f76e80b20f1a68c1463757a0be65c89cc84f26a [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2011-2012
* Pali Rohár <pali@kernel.org>
*/
#include <config.h>
relocaddr: /* address of this relocaddr section after coping */
.word . /* address of section (calculated at compile time) */
startaddr: /* address of u-boot after copying */
.word CONFIG_SYS_TEXT_BASE
kernaddr: /* address of kernel after copying */
.word KERNEL_ADDRESS
kernsize: /* maximal size of kernel image */
.word KERNEL_MAXSIZE
kernoffs: /* offset of kernel image in loaded u-boot */
.word KERNEL_OFFSET
imagesize: /* maximal size of image */
.word IMAGE_MAXSIZE
ih_magic: /* IH_MAGIC in big endian from include/image.h */
.word 0x56190527
z_magic: /* LINUX_ARM_ZIMAGE_MAGIC */
.word 0x016f2818
/*
* Routine: save_boot_params (called after reset from start.S)
* Description: Copy attached kernel to address KERNEL_ADDRESS
*/
.global save_boot_params
save_boot_params:
/*
* Copy valid attached kernel to absolute address KERNEL_ADDRESS
*
* Nokia X-Loader is loading secondary image to address 0x80400000.
* NOLO is loading boot image to random place, so it doesn't really
* matter what is set in CONFIG_SYS_TEXT_BASE. We have to detect
* KERNEL_OFFSET from the current execution address and copy it to
* absolute address KERNEL_ADDRESS.
*
* Note that U-Boot has to be compiled with CONFIG_POSITION_INDEPENDENT
* because it is loaded at random address and not to the fixed address
* (CONFIG_SYS_TEXT_BASE).
*/
copy_kernel_start:
adr r0, relocaddr /* r0 - address of section relocaddr */
ldr r1, relocaddr /* r1 - address of relocaddr after relocation */
/* r4 - calculated offset */
sub r4, r0, r1
/* r0 - start of kernel before */
ldr r0, startaddr
add r0, r0, r4
ldr r1, kernoffs
add r0, r0, r1
/* r3 - start of kernel after */
ldr r3, kernaddr
/* r2 - end of kernel after */
ldr r1, kernsize
add r2, r3, r1
/* r1 - end of kernel before */
add r1, r0, r1
/* remove header in target kernel */
mov r5, #0
str r5, [r3] /* remove 4 bytes header of kernel uImage */
str r5, [r3, #36] /* remove 4 bytes header of kernel zImage */
/* check for valid kernel uImage */
ldr r4, [r0] /* r4 - 4 bytes header of kernel */
ldr r5, ih_magic /* r5 - IH_MAGIC */
cmp r4, r5
beq copy_kernel_loop
/* check for valid kernel zImage */
ldr r4, [r0, #36] /* r4 - 4 bytes header of kernel at offset 36 */
ldr r5, z_magic /* r5 - LINUX_ARM_ZIMAGE_MAGIC */
cmp r4, r5
bne copy_kernel_end /* skip if invalid image */
copy_kernel_loop:
ldmdb r1!, {r3 - r10}
stmdb r2!, {r3 - r10}
cmp r1, r0
bhi copy_kernel_loop
copy_kernel_end:
/* remove header in source kernel image */
mov r5, #0
str r5, [r0] /* remove 4 bytes header of kernel uImage */
str r5, [r0, #36] /* remove 4 bytes header of kernel zImage */
/* Returns */
b save_boot_params_ret