aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/kernel/relocate_kernel.S29
-rw-r--r--arch/arm/kernel/setup.c30
-rw-r--r--include/asm-arm/kexec.h2
3 files changed, 60 insertions, 1 deletions
diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S
index 7baadae7cb2..062c111c572 100644
--- a/arch/arm/kernel/relocate_kernel.S
+++ b/arch/arm/kernel/relocate_kernel.S
@@ -7,6 +7,23 @@
7 .globl relocate_new_kernel 7 .globl relocate_new_kernel
8relocate_new_kernel: 8relocate_new_kernel:
9 9
10 /* Move boot params back to where the kernel expects them */
11
12 ldr r0,kexec_boot_params_address
13 teq r0,#0
14 beq 8f
15
16 ldr r1,kexec_boot_params_copy
17 mov r6,#KEXEC_BOOT_PARAMS_SIZE/4
187:
19 ldr r5,[r1],#4
20 str r5,[r0],#4
21 subs r6,r6,#1
22 bne 7b
23
248:
25 /* Boot params moved, now go on with the kernel */
26
10 ldr r0,kexec_indirection_page 27 ldr r0,kexec_indirection_page
11 ldr r1,kexec_start_address 28 ldr r1,kexec_start_address
12 29
@@ -50,7 +67,7 @@ relocate_new_kernel:
50 mov lr,r1 67 mov lr,r1
51 mov r0,#0 68 mov r0,#0
52 ldr r1,kexec_mach_type 69 ldr r1,kexec_mach_type
53 mov r2,#0 70 ldr r2,kexec_boot_params_address
54 mov pc,lr 71 mov pc,lr
55 72
56 .globl kexec_start_address 73 .globl kexec_start_address
@@ -65,6 +82,16 @@ kexec_indirection_page:
65kexec_mach_type: 82kexec_mach_type:
66 .long 0x0 83 .long 0x0
67 84
85 /* phy addr where new kernel will expect to find boot params */
86 .globl kexec_boot_params_address
87kexec_boot_params_address:
88 .long 0x0
89
90 /* phy addr where old kernel put a copy of orig boot params */
91 .globl kexec_boot_params_copy
92kexec_boot_params_copy:
93 .long 0x0
94
68relocate_new_kernel_end: 95relocate_new_kernel_end:
69 96
70 .globl relocate_new_kernel_size 97 .globl relocate_new_kernel_size
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index efac7df72d6..bf56eb337df 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -24,6 +24,7 @@
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/smp.h> 25#include <linux/smp.h>
26#include <linux/fs.h> 26#include <linux/fs.h>
27#include <linux/kexec.h>
27 28
28#include <asm/cpu.h> 29#include <asm/cpu.h>
29#include <asm/elf.h> 30#include <asm/elf.h>
@@ -783,6 +784,23 @@ static int __init customize_machine(void)
783} 784}
784arch_initcall(customize_machine); 785arch_initcall(customize_machine);
785 786
787#ifdef CONFIG_KEXEC
788
789/* Physical addr of where the boot params should be for this machine */
790extern unsigned long kexec_boot_params_address;
791
792/* Physical addr of the buffer into which the boot params are copied */
793extern unsigned long kexec_boot_params_copy;
794
795/* Pointer to the boot params buffer, for manipulation and display */
796unsigned long kexec_boot_params;
797EXPORT_SYMBOL(kexec_boot_params);
798
799/* The buffer itself - make sure it is sized correctly */
800static unsigned long kexec_boot_params_buf[(KEXEC_BOOT_PARAMS_SIZE + 3) / 4];
801
802#endif
803
786void __init setup_arch(char **cmdline_p) 804void __init setup_arch(char **cmdline_p)
787{ 805{
788 struct tag *tags = (struct tag *)&init_tags; 806 struct tag *tags = (struct tag *)&init_tags;
@@ -801,6 +819,18 @@ void __init setup_arch(char **cmdline_p)
801 else if (mdesc->boot_params) 819 else if (mdesc->boot_params)
802 tags = phys_to_virt(mdesc->boot_params); 820 tags = phys_to_virt(mdesc->boot_params);
803 821
822#ifdef CONFIG_KEXEC
823 kexec_boot_params_copy = virt_to_phys(kexec_boot_params_buf);
824 kexec_boot_params = (unsigned long)kexec_boot_params_buf;
825 if (__atags_pointer) {
826 kexec_boot_params_address = __atags_pointer;
827 memcpy((void *)kexec_boot_params, tags, KEXEC_BOOT_PARAMS_SIZE);
828 } else if (mdesc->boot_params) {
829 kexec_boot_params_address = mdesc->boot_params;
830 memcpy((void *)kexec_boot_params, tags, KEXEC_BOOT_PARAMS_SIZE);
831 }
832#endif
833
804 /* 834 /*
805 * If we have the old style parameters, convert them to 835 * If we have the old style parameters, convert them to
806 * a tag list. 836 * a tag list.
diff --git a/include/asm-arm/kexec.h b/include/asm-arm/kexec.h
index b5b030ef633..46dcc4d0b9b 100644
--- a/include/asm-arm/kexec.h
+++ b/include/asm-arm/kexec.h
@@ -14,6 +14,8 @@
14 14
15#define KEXEC_ARCH KEXEC_ARCH_ARM 15#define KEXEC_ARCH KEXEC_ARCH_ARM
16 16
17#define KEXEC_BOOT_PARAMS_SIZE 1536
18
17#ifndef __ASSEMBLY__ 19#ifndef __ASSEMBLY__
18 20
19struct kimage; 21struct kimage;