aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/boot
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2011-05-07 03:34:02 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-05-07 03:34:02 -0400
commit7b76415375ba91f5a06f8d5179278c03d6151d16 (patch)
tree11f156309efb05174906954efc5159a15b202437 /arch/arm/boot
parentc93212f387fdf5180d9d13cc207419abd5b3ec17 (diff)
parent8d7e4cc2c8ea1d180d32d902eb899f27d3ee53d7 (diff)
Merge branch 'zImage_fixes' of git://git.linaro.org/people/nico/linux into devel-stable
Diffstat (limited to 'arch/arm/boot')
-rw-r--r--arch/arm/boot/compressed/Makefile19
-rw-r--r--arch/arm/boot/compressed/decompress.c4
-rw-r--r--arch/arm/boot/compressed/head.S57
-rw-r--r--arch/arm/boot/compressed/misc.c24
-rw-r--r--arch/arm/boot/compressed/vmlinux.lds.in1
5 files changed, 70 insertions, 35 deletions
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 8ebbb511c783..23aad0722303 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -74,7 +74,7 @@ ZTEXTADDR := $(CONFIG_ZBOOT_ROM_TEXT)
74ZBSSADDR := $(CONFIG_ZBOOT_ROM_BSS) 74ZBSSADDR := $(CONFIG_ZBOOT_ROM_BSS)
75else 75else
76ZTEXTADDR := 0 76ZTEXTADDR := 0
77ZBSSADDR := ALIGN(4) 77ZBSSADDR := ALIGN(8)
78endif 78endif
79 79
80SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/ 80SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
@@ -98,8 +98,6 @@ endif
98ccflags-y := -fpic -fno-builtin 98ccflags-y := -fpic -fno-builtin
99asflags-y := -Wa,-march=all 99asflags-y := -Wa,-march=all
100 100
101# Provide size of uncompressed kernel to the decompressor via a linker symbol.
102LDFLAGS_vmlinux = --defsym _image_size=$(shell stat -c "%s" $(obj)/../Image)
103# Supply ZRELADDR to the decompressor via a linker symbol. 101# Supply ZRELADDR to the decompressor via a linker symbol.
104ifneq ($(CONFIG_AUTO_ZRELADDR),y) 102ifneq ($(CONFIG_AUTO_ZRELADDR),y)
105LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR) 103LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR)
@@ -122,10 +120,23 @@ lib1funcs = $(obj)/lib1funcs.o
122$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE 120$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE
123 $(call cmd,shipped) 121 $(call cmd,shipped)
124 122
123# We need to prevent any GOTOFF relocs being used with references
124# to symbols in the .bss section since we cannot relocate them
125# independently from the rest at run time. This can be achieved by
126# ensuring that no private .bss symbols exist, as global symbols
127# always have a GOT entry which is what we need.
128# The .data section is already discarded by the linker script so no need
129# to bother about it here.
130check_for_bad_syms = \
131bad_syms=$$($(CROSS_COMPILE)nm $@ | sed -n 's/^.\{8\} [bc] \(.*\)/\1/p') && \
132[ -z "$$bad_syms" ] || \
133 ( echo "following symbols must have non local/private scope:" >&2; \
134 echo "$$bad_syms" >&2; rm -f $@; false )
135
125$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \ 136$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
126 $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE 137 $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE
127 $(call if_changed,ld) 138 $(call if_changed,ld)
128 @: 139 @$(check_for_bad_syms)
129 140
130$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE 141$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE
131 $(call if_changed,$(suffix_y)) 142 $(call if_changed,$(suffix_y))
diff --git a/arch/arm/boot/compressed/decompress.c b/arch/arm/boot/compressed/decompress.c
index 4c72a97bc3e1..07be5a2f8302 100644
--- a/arch/arm/boot/compressed/decompress.c
+++ b/arch/arm/boot/compressed/decompress.c
@@ -44,7 +44,7 @@ extern void error(char *);
44#include "../../../../lib/decompress_unlzma.c" 44#include "../../../../lib/decompress_unlzma.c"
45#endif 45#endif
46 46
47void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)) 47int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x))
48{ 48{
49 decompress(input, len, NULL, NULL, output, NULL, error); 49 return decompress(input, len, NULL, NULL, output, NULL, error);
50} 50}
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index a36f4526689b..c363458a4e63 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -179,16 +179,29 @@ not_angel:
179 bl cache_on 179 bl cache_on
180 180
181restart: adr r0, LC0 181restart: adr r0, LC0
182 ldmia r0, {r1, r2, r3, r5, r6, r9, r11, r12} 182 ldmia r0, {r1, r2, r3, r6, r10, r11, r12}
183 ldr sp, [r0, #32] 183 ldr sp, [r0, #28]
184 184
185 /* 185 /*
186 * We might be running at a different address. We need 186 * We might be running at a different address. We need
187 * to fix up various pointers. 187 * to fix up various pointers.
188 */ 188 */
189 sub r0, r0, r1 @ calculate the delta offset 189 sub r0, r0, r1 @ calculate the delta offset
190 add r5, r5, r0 @ _start
191 add r6, r6, r0 @ _edata 190 add r6, r6, r0 @ _edata
191 add r10, r10, r0 @ inflated kernel size location
192
193 /*
194 * The kernel build system appends the size of the
195 * decompressed kernel at the end of the compressed data
196 * in little-endian form.
197 */
198 ldrb r9, [r10, #0]
199 ldrb lr, [r10, #1]
200 orr r9, r9, lr, lsl #8
201 ldrb lr, [r10, #2]
202 ldrb r10, [r10, #3]
203 orr r9, r9, lr, lsl #16
204 orr r9, r9, r10, lsl #24
192 205
193#ifndef CONFIG_ZBOOT_ROM 206#ifndef CONFIG_ZBOOT_ROM
194 /* malloc space is above the relocated stack (64k max) */ 207 /* malloc space is above the relocated stack (64k max) */
@@ -206,31 +219,40 @@ restart: adr r0, LC0
206/* 219/*
207 * Check to see if we will overwrite ourselves. 220 * Check to see if we will overwrite ourselves.
208 * r4 = final kernel address 221 * r4 = final kernel address
209 * r5 = start of this image
210 * r9 = size of decompressed image 222 * r9 = size of decompressed image
211 * r10 = end of this image, including bss/stack/malloc space if non XIP 223 * r10 = end of this image, including bss/stack/malloc space if non XIP
212 * We basically want: 224 * We basically want:
213 * r4 >= r10 -> OK 225 * r4 - 16k page directory >= r10 -> OK
214 * r4 + image length <= r5 -> OK 226 * r4 + image length <= current position (pc) -> OK
215 */ 227 */
228 add r10, r10, #16384
216 cmp r4, r10 229 cmp r4, r10
217 bhs wont_overwrite 230 bhs wont_overwrite
218 add r10, r4, r9 231 add r10, r4, r9
219 cmp r10, r5 232 ARM( cmp r10, pc )
233 THUMB( mov lr, pc )
234 THUMB( cmp r10, lr )
220 bls wont_overwrite 235 bls wont_overwrite
221 236
222/* 237/*
223 * Relocate ourselves past the end of the decompressed kernel. 238 * Relocate ourselves past the end of the decompressed kernel.
224 * r5 = start of this image
225 * r6 = _edata 239 * r6 = _edata
226 * r10 = end of the decompressed kernel 240 * r10 = end of the decompressed kernel
227 * Because we always copy ahead, we need to do it from the end and go 241 * Because we always copy ahead, we need to do it from the end and go
228 * backward in case the source and destination overlap. 242 * backward in case the source and destination overlap.
229 */ 243 */
230 /* Round up to next 256-byte boundary. */ 244 /*
231 add r10, r10, #256 245 * Bump to the next 256-byte boundary with the size of
246 * the relocation code added. This avoids overwriting
247 * ourself when the offset is small.
248 */
249 add r10, r10, #((reloc_code_end - restart + 256) & ~255)
232 bic r10, r10, #255 250 bic r10, r10, #255
233 251
252 /* Get start of code we want to copy and align it down. */
253 adr r5, restart
254 bic r5, r5, #31
255
234 sub r9, r6, r5 @ size to copy 256 sub r9, r6, r5 @ size to copy
235 add r9, r9, #31 @ rounded up to a multiple 257 add r9, r9, #31 @ rounded up to a multiple
236 bic r9, r9, #31 @ ... of 32 bytes 258 bic r9, r9, #31 @ ... of 32 bytes
@@ -245,6 +267,11 @@ restart: adr r0, LC0
245 /* Preserve offset to relocated code. */ 267 /* Preserve offset to relocated code. */
246 sub r6, r9, r6 268 sub r6, r9, r6
247 269
270#ifndef CONFIG_ZBOOT_ROM
271 /* cache_clean_flush may use the stack, so relocate it */
272 add sp, sp, r6
273#endif
274
248 bl cache_clean_flush 275 bl cache_clean_flush
249 276
250 adr r0, BSYM(restart) 277 adr r0, BSYM(restart)
@@ -333,12 +360,11 @@ not_relocated: mov r0, #0
333LC0: .word LC0 @ r1 360LC0: .word LC0 @ r1
334 .word __bss_start @ r2 361 .word __bss_start @ r2
335 .word _end @ r3 362 .word _end @ r3
336 .word _start @ r5
337 .word _edata @ r6 363 .word _edata @ r6
338 .word _image_size @ r9 364 .word input_data_end - 4 @ r10 (inflated size location)
339 .word _got_start @ r11 365 .word _got_start @ r11
340 .word _got_end @ ip 366 .word _got_end @ ip
341 .word user_stack_end @ sp 367 .word .L_user_stack_end @ sp
342 .size LC0, . - LC0 368 .size LC0, . - LC0
343 369
344#ifdef CONFIG_ARCH_RPC 370#ifdef CONFIG_ARCH_RPC
@@ -1056,8 +1082,9 @@ memdump: mov r12, r0
1056#endif 1082#endif
1057 1083
1058 .ltorg 1084 .ltorg
1085reloc_code_end:
1059 1086
1060 .align 1087 .align
1061 .section ".stack", "aw", %nobits 1088 .section ".stack", "aw", %nobits
1062user_stack: .space 4096 1089.L_user_stack: .space 4096
1063user_stack_end: 1090.L_user_stack_end:
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
index 2df38263124c..832d37236c59 100644
--- a/arch/arm/boot/compressed/misc.c
+++ b/arch/arm/boot/compressed/misc.c
@@ -26,8 +26,6 @@ unsigned int __machine_arch_type;
26#include <linux/linkage.h> 26#include <linux/linkage.h>
27#include <asm/string.h> 27#include <asm/string.h>
28 28
29#include <asm/unaligned.h>
30
31 29
32static void putstr(const char *ptr); 30static void putstr(const char *ptr);
33extern void error(char *x); 31extern void error(char *x);
@@ -139,13 +137,12 @@ void *memcpy(void *__dest, __const void *__src, size_t __n)
139} 137}
140 138
141/* 139/*
142 * gzip delarations 140 * gzip declarations
143 */ 141 */
144extern char input_data[]; 142extern char input_data[];
145extern char input_data_end[]; 143extern char input_data_end[];
146 144
147unsigned char *output_data; 145unsigned char *output_data;
148unsigned long output_ptr;
149 146
150unsigned long free_mem_ptr; 147unsigned long free_mem_ptr;
151unsigned long free_mem_end_ptr; 148unsigned long free_mem_end_ptr;
@@ -170,15 +167,15 @@ asmlinkage void __div0(void)
170 error("Attempting division by 0!"); 167 error("Attempting division by 0!");
171} 168}
172 169
173extern void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)); 170extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x));
174 171
175 172
176unsigned long 173void
177decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, 174decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
178 unsigned long free_mem_ptr_end_p, 175 unsigned long free_mem_ptr_end_p,
179 int arch_id) 176 int arch_id)
180{ 177{
181 unsigned char *tmp; 178 int ret;
182 179
183 output_data = (unsigned char *)output_start; 180 output_data = (unsigned char *)output_start;
184 free_mem_ptr = free_mem_ptr_p; 181 free_mem_ptr = free_mem_ptr_p;
@@ -187,12 +184,11 @@ decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
187 184
188 arch_decomp_setup(); 185 arch_decomp_setup();
189 186
190 tmp = (unsigned char *) (((unsigned long)input_data_end) - 4);
191 output_ptr = get_unaligned_le32(tmp);
192
193 putstr("Uncompressing Linux..."); 187 putstr("Uncompressing Linux...");
194 do_decompress(input_data, input_data_end - input_data, 188 ret = do_decompress(input_data, input_data_end - input_data,
195 output_data, error); 189 output_data, error);
196 putstr(" done, booting the kernel.\n"); 190 if (ret)
197 return output_ptr; 191 error("decompressor returned an error");
192 else
193 putstr(" done, booting the kernel.\n");
198} 194}
diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in
index 5309909d7282..ea80abe78844 100644
--- a/arch/arm/boot/compressed/vmlinux.lds.in
+++ b/arch/arm/boot/compressed/vmlinux.lds.in
@@ -54,6 +54,7 @@ SECTIONS
54 .bss : { *(.bss) } 54 .bss : { *(.bss) }
55 _end = .; 55 _end = .;
56 56
57 . = ALIGN(8); /* the stack must be 64-bit aligned */
57 .stack : { *(.stack) } 58 .stack : { *(.stack) }
58 59
59 .stab 0 : { *(.stab) } 60 .stab 0 : { *(.stab) }