aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2007-02-22 10:18:09 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-02-25 11:41:38 -0500
commite98ff7f6d8164c5636538998fb7d1e08b1fbbddd (patch)
treeaa5448d3b8c293e7e0df786669092e6cac55c068
parent0ebffe39f8ec8b5b126d9505852a396371014555 (diff)
[ARM] 4224/2: allow XIP kernel to boot again
Since commit 2552fc27ff79b10b9678d92bcaef21df38bb7bb6 XIP kernels failed to boot because (_end - PAGE_OFFSET - 1) is much smaller than the size of the kernel text and data in the XIP case, causing the kernel not to be entirely mapped. Even in the non-XIP case, the use of (_end - PAGE_OFFSET - 1) is wrong because it produces a too large value if TEXT_OFFSET is larger than 1MB. Finally the original code was performing one loop too many. Let's break the loop when the section pointer has passed the last byte of the kernel instead. Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/kernel/head.S25
-rw-r--r--arch/arm/kernel/vmlinux.lds.S1
2 files changed, 14 insertions, 12 deletions
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index cf495a3084b3..c5f0c52660b2 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -48,9 +48,11 @@
48 .endm 48 .endm
49 49
50#ifdef CONFIG_XIP_KERNEL 50#ifdef CONFIG_XIP_KERNEL
51#define TEXTADDR XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR) 51#define KERNEL_START XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
52#define KERNEL_END _edata_loc
52#else 53#else
53#define TEXTADDR KERNEL_RAM_VADDR 54#define KERNEL_START KERNEL_RAM_VADDR
55#define KERNEL_END _end
54#endif 56#endif
55 57
56/* 58/*
@@ -240,16 +242,15 @@ __create_page_tables:
240 * Now setup the pagetables for our kernel direct 242 * Now setup the pagetables for our kernel direct
241 * mapped region. 243 * mapped region.
242 */ 244 */
243 add r0, r4, #(TEXTADDR & 0xff000000) >> 18 @ start of kernel 245 add r0, r4, #(KERNEL_START & 0xff000000) >> 18
244 str r3, [r0, #(TEXTADDR & 0x00f00000) >> 18]! 246 str r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
245 247 ldr r6, =(KERNEL_END - 1)
246 ldr r6, =(_end - PAGE_OFFSET - 1) @ r6 = number of sections 248 add r0, r0, #4
247 mov r6, r6, lsr #20 @ needed for kernel minus 1 249 add r6, r4, r6, lsr #18
248 2501: cmp r0, r6
2491: add r3, r3, #1 << 20 251 add r3, r3, #1 << 20
250 str r3, [r0, #4]! 252 strls r3, [r0], #4
251 subs r6, r6, #1 253 bls 1b
252 bgt 1b
253 254
254 /* 255 /*
255 * Then map first 1MB of ram in case it contains our boot params. 256 * Then map first 1MB of ram in case it contains our boot params.
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index b929a60f7547..ddbdad48f5b2 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -156,6 +156,7 @@ SECTIONS
156 156
157 _edata = .; 157 _edata = .;
158 } 158 }
159 _edata_loc = __data_loc + SIZEOF(.data);
159 160
160 .bss : { 161 .bss : {
161 __bss_start = .; /* BSS */ 162 __bss_start = .; /* BSS */