1/* 2 * relocate_kernel.S - put the kernel image in place to boot 3 */ 4 5#include <linux/linkage.h> 6#include <asm/assembler.h> 7#include <asm/kexec.h> 8 9 .align 3 /* not needed for this code, but keeps fncpy() happy */ 10 11ENTRY(relocate_new_kernel) 12 13 ldr r0,kexec_indirection_page 14 ldr r1,kexec_start_address 15 16 /* 17 * If there is no indirection page (we are doing crashdumps) 18 * skip any relocation. 19 */ 20 cmp r0, #0 21 beq 2f 22 230: /* top, read another word for the indirection page */ 24 ldr r3, [r0],#4 25 26 /* Is it a destination page. Put destination address to r4 */ 27 tst r3,#1,0 28 beq 1f 29 bic r4,r3,#1 30 b 0b 311: 32 /* Is it an indirection page */ 33 tst r3,#2,0 34 beq 1f 35 bic r0,r3,#2 36 b 0b 371: 38 39 /* are we done ? */ 40 tst r3,#4,0 41 beq 1f 42 b 2f 43 441: 45 /* is it source ? */ 46 tst r3,#8,0 47 beq 0b 48 bic r3,r3,#8 49 mov r6,#1024 509: 51 ldr r5,[r3],#4 52 str r5,[r4],#4 53 subs r6,r6,#1 54 bne 9b 55 b 0b 56 572: 58 /* Jump to relocated kernel */ 59 mov lr,r1 60 mov r0,#0 61 ldr r1,kexec_mach_type 62 ldr r2,kexec_boot_atags 63 ARM( ret lr ) 64 THUMB( bx lr ) 65 66 .align 67 68 .globl kexec_start_address 69kexec_start_address: 70 .long 0x0 71 72 .globl kexec_indirection_page 73kexec_indirection_page: 74 .long 0x0 75 76 .globl kexec_mach_type 77kexec_mach_type: 78 .long 0x0 79 80 /* phy addr of the atags for the new kernel */ 81 .globl kexec_boot_atags 82kexec_boot_atags: 83 .long 0x0 84 85ENDPROC(relocate_new_kernel) 86 87relocate_new_kernel_end: 88 89 .globl relocate_new_kernel_size 90relocate_new_kernel_size: 91 .long relocate_new_kernel_end - relocate_new_kernel 92 93 94