1/* SPDX-License-Identifier: GPL-2.0+ */ 2/* 3 * (C) Copyright 2011-2012 4 * Pali Rohár <pali@kernel.org> 5 */ 6 7#include <config.h> 8#include <linux/linkage.h> 9 10kernoffs: /* offset of kernel image from this address */ 11 .word . - CONFIG_TEXT_BASE - KERNEL_OFFSET 12 13kernaddr: /* address of kernel after copying */ 14 .word KERNEL_ADDRESS 15 16kernsize: /* maximal size of kernel image */ 17 .word KERNEL_MAXSIZE 18 19imagesize: /* maximal size of image */ 20 .word IMAGE_MAXSIZE 21 22ih_magic: /* IH_MAGIC in big endian from include/image.h */ 23 .word 0x56190527 24 25z_magic: /* LINUX_ARM_ZIMAGE_MAGIC */ 26 .word 0x016f2818 27 28/* 29 * Routine: save_boot_params (called after reset from start.S) 30 * Description: Copy attached kernel to address KERNEL_ADDRESS 31 */ 32 33ENTRY(save_boot_params) 34 35/* 36 * Copy valid attached kernel to absolute address KERNEL_ADDRESS 37 * 38 * Nokia X-Loader is loading secondary image to address 0x80400000. 39 * NOLO is loading boot image to random place, so it doesn't really 40 * matter what is set in CONFIG_TEXT_BASE. We have to detect 41 * KERNEL_OFFSET from the current execution address and copy it to 42 * absolute address KERNEL_ADDRESS. 43 * 44 * Note that U-Boot has to be compiled with CONFIG_POSITION_INDEPENDENT 45 * because it is loaded at random address and not to the fixed address 46 * (CONFIG_TEXT_BASE). 47 */ 48 49 /* r0 - start of kernel before */ 50 adr r0, kernoffs /* r0 - current address of kernoffs section */ 51 ldr r1, kernoffs /* r1 - offset of kernel image from kernoffs section */ 52 sub r0, r0, r1 53 54 /* r3 - start of kernel after */ 55 ldr r3, kernaddr 56 57 /* r2 - end of kernel after */ 58 ldr r1, kernsize 59 add r2, r3, r1 60 61 /* r1 - end of kernel before */ 62 add r1, r0, r1 63 64 /* remove header in target kernel */ 65 mov r5, #0 66 str r5, [r3] /* remove 4 bytes header of kernel uImage */ 67 str r5, [r3, #36] /* remove 4 bytes header of kernel zImage */ 68 69 /* check for valid kernel uImage */ 70 ldr r4, [r0] /* r4 - 4 bytes header of kernel */ 71 ldr r5, ih_magic /* r5 - IH_MAGIC */ 72 cmp r4, r5 73 beq copy_kernel_loop 74 75 /* check for valid kernel zImage */ 76 ldr r4, [r0, #36] /* r4 - 4 bytes header of kernel at offset 36 */ 77 ldr r5, z_magic /* r5 - LINUX_ARM_ZIMAGE_MAGIC */ 78 cmp r4, r5 79 bne skip_copy /* skip if invalid image */ 80 81copy_kernel_loop: 82 ldmdb r1!, {r3 - r10} 83 stmdb r2!, {r3 - r10} 84 cmp r1, r0 85 bhi copy_kernel_loop 86 87 /* remove header in source kernel image */ 88 mov r5, #0 89 str r5, [r0] /* remove 4 bytes header of kernel uImage */ 90 str r5, [r0, #36] /* remove 4 bytes header of kernel zImage */ 91 92skip_copy: 93 94 /* Returns */ 95 b save_boot_params_ret 96 97ENDPROC(save_boot_params) 98