aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Pitre <nicolas.pitre@linaro.org>2011-06-12 01:07:33 -0400
committerNicolas Pitre <nico@fluxnic.net>2011-09-14 13:51:57 -0400
commit5ffb04f6690d71fab241b3562ebf52b893ac4ff1 (patch)
tree69897c130b7f3ff06d54d35eb3c92a8baea57119
parente2a6a3aafa9862c4a4b59f2a59b8f923d64a680e (diff)
ARM: zImage: make sure appended DTB doesn't get overwritten by kernel .bss
The appended DTB gets relocated with the decompressor code to get out of the way of the decompressed kernel. However the kernel's .bss section may be larger than the relocated code and data, and then the DTB gets overwritten. Let's make sure the relocation takes care of moving zImage far enough so no such conflict with .bss occurs. Thanks to Tony Lindgren <tony@atomide.com> for figuring out this issue. While at it, let's clean up the code a bit so that the wont_overwrite symbol is used while determining if a conflict exists, making the above change more precise as well as eliminating some ARM/THUMB alternates. Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org> Acked-by: Tony Lindgren <tony@atomide.com> Tested-by: Shawn Guo <shawn.guo@linaro.org> Tested-by: Dave Martin <dave.martin@linaro.org> Tested-by: Thomas Abraham <thomas.abraham@linaro.org>
-rw-r--r--arch/arm/boot/compressed/Makefile3
-rw-r--r--arch/arm/boot/compressed/head.S19
2 files changed, 18 insertions, 4 deletions
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 0c74a6fab952..4867647b9796 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -104,6 +104,9 @@ endif
104ccflags-y := -fpic -fno-builtin 104ccflags-y := -fpic -fno-builtin
105asflags-y := -Wa,-march=all 105asflags-y := -Wa,-march=all
106 106
107# Supply kernel BSS size to the decompressor via a linker symbol.
108KBSS_SZ = $(shell size $(obj)/../../../../vmlinux | awk 'END{print $$3}')
109LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)
107# Supply ZRELADDR to the decompressor via a linker symbol. 110# Supply ZRELADDR to the decompressor via a linker symbol.
108ifneq ($(CONFIG_AUTO_ZRELADDR),y) 111ifneq ($(CONFIG_AUTO_ZRELADDR),y)
109LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR) 112LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR)
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 3ce5738ddb98..ba5c552f8c69 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -248,6 +248,18 @@ restart: adr r0, LC0
248 248
249 mov r8, r6 @ use the appended device tree 249 mov r8, r6 @ use the appended device tree
250 250
251 /*
252 * Make sure that the DTB doesn't end up in the final
253 * kernel's .bss area. To do so, we adjust the decompressed
254 * kernel size to compensate if that .bss size is larger
255 * than the relocated code.
256 */
257 ldr r5, =_kernel_bss_size
258 adr r1, wont_overwrite
259 sub r1, r6, r1
260 subs r1, r5, r1
261 addhi r9, r9, r1
262
251 /* Get the dtb's size */ 263 /* Get the dtb's size */
252 ldr r5, [r6, #4] 264 ldr r5, [r6, #4]
253#ifndef __ARMEB__ 265#ifndef __ARMEB__
@@ -276,15 +288,14 @@ dtb_check_done:
276 * r10 = end of this image, including bss/stack/malloc space if non XIP 288 * r10 = end of this image, including bss/stack/malloc space if non XIP
277 * We basically want: 289 * We basically want:
278 * r4 - 16k page directory >= r10 -> OK 290 * r4 - 16k page directory >= r10 -> OK
279 * r4 + image length <= current position (pc) -> OK 291 * r4 + image length <= address of wont_overwrite -> OK
280 */ 292 */
281 add r10, r10, #16384 293 add r10, r10, #16384
282 cmp r4, r10 294 cmp r4, r10
283 bhs wont_overwrite 295 bhs wont_overwrite
284 add r10, r4, r9 296 add r10, r4, r9
285 ARM( cmp r10, pc ) 297 adr r9, wont_overwrite
286 THUMB( mov lr, pc ) 298 cmp r10, r9
287 THUMB( cmp r10, lr )
288 bls wont_overwrite 299 bls wont_overwrite
289 300
290/* 301/*