diff options
Diffstat (limited to 'arch/arm/boot')
-rw-r--r-- | arch/arm/boot/compressed/Makefile | 17 | ||||
-rw-r--r-- | arch/arm/boot/compressed/decompress.c | 4 | ||||
-rw-r--r-- | arch/arm/boot/compressed/head.S | 46 | ||||
-rw-r--r-- | arch/arm/boot/compressed/misc.c | 24 |
4 files changed, 61 insertions, 30 deletions
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 0c6852d93506..23aad0722303 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile | |||
@@ -98,8 +98,6 @@ endif | |||
98 | ccflags-y := -fpic -fno-builtin | 98 | ccflags-y := -fpic -fno-builtin |
99 | asflags-y := -Wa,-march=all | 99 | asflags-y := -Wa,-march=all |
100 | 100 | ||
101 | # Provide size of uncompressed kernel to the decompressor via a linker symbol. | ||
102 | LDFLAGS_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. |
104 | ifneq ($(CONFIG_AUTO_ZRELADDR),y) | 102 | ifneq ($(CONFIG_AUTO_ZRELADDR),y) |
105 | LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR) | 103 | LDFLAGS_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. | ||
130 | check_for_bad_syms = \ | ||
131 | bad_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 | ||
47 | void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)) | 47 | int 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 49f5b2eaaa87..f9da41921c52 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
@@ -179,7 +179,7 @@ not_angel: | |||
179 | bl cache_on | 179 | bl cache_on |
180 | 180 | ||
181 | restart: adr r0, LC0 | 181 | restart: adr r0, LC0 |
182 | ldmia r0, {r1, r2, r3, r6, r9, r11, r12} | 182 | ldmia r0, {r1, r2, r3, r6, r10, r11, r12} |
183 | ldr sp, [r0, #28] | 183 | ldr sp, [r0, #28] |
184 | 184 | ||
185 | /* | 185 | /* |
@@ -188,6 +188,20 @@ restart: adr r0, LC0 | |||
188 | */ | 188 | */ |
189 | sub r0, r0, r1 @ calculate the delta offset | 189 | sub r0, r0, r1 @ calculate the delta offset |
190 | 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 | ||
191 | 205 | ||
192 | #ifndef CONFIG_ZBOOT_ROM | 206 | #ifndef CONFIG_ZBOOT_ROM |
193 | /* malloc space is above the relocated stack (64k max) */ | 207 | /* malloc space is above the relocated stack (64k max) */ |
@@ -347,10 +361,10 @@ LC0: .word LC0 @ r1 | |||
347 | .word __bss_start @ r2 | 361 | .word __bss_start @ r2 |
348 | .word _end @ r3 | 362 | .word _end @ r3 |
349 | .word _edata @ r6 | 363 | .word _edata @ r6 |
350 | .word _image_size @ r9 | 364 | .word input_data_end - 4 @ r10 (inflated size location) |
351 | .word _got_start @ r11 | 365 | .word _got_start @ r11 |
352 | .word _got_end @ ip | 366 | .word _got_end @ ip |
353 | .word user_stack_end @ sp | 367 | .word .L_user_stack_end @ sp |
354 | .size LC0, . - LC0 | 368 | .size LC0, . - LC0 |
355 | 369 | ||
356 | #ifdef CONFIG_ARCH_RPC | 370 | #ifdef CONFIG_ARCH_RPC |
@@ -459,7 +473,11 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size | |||
459 | orr r1, r1, #3 << 10 | 473 | orr r1, r1, #3 << 10 |
460 | add r2, r3, #16384 | 474 | add r2, r3, #16384 |
461 | 1: cmp r1, r9 @ if virt > start of RAM | 475 | 1: cmp r1, r9 @ if virt > start of RAM |
476 | #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH | ||
477 | orrhs r1, r1, #0x08 @ set cacheable | ||
478 | #else | ||
462 | orrhs r1, r1, #0x0c @ set cacheable, bufferable | 479 | orrhs r1, r1, #0x0c @ set cacheable, bufferable |
480 | #endif | ||
463 | cmp r1, r10 @ if virt > end of RAM | 481 | cmp r1, r10 @ if virt > end of RAM |
464 | bichs r1, r1, #0x0c @ clear cacheable, bufferable | 482 | bichs r1, r1, #0x0c @ clear cacheable, bufferable |
465 | str r1, [r0], #4 @ 1:1 mapping | 483 | str r1, [r0], #4 @ 1:1 mapping |
@@ -484,6 +502,12 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size | |||
484 | mov pc, lr | 502 | mov pc, lr |
485 | ENDPROC(__setup_mmu) | 503 | ENDPROC(__setup_mmu) |
486 | 504 | ||
505 | __arm926ejs_mmu_cache_on: | ||
506 | #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH | ||
507 | mov r0, #4 @ put dcache in WT mode | ||
508 | mcr p15, 7, r0, c15, c0, 0 | ||
509 | #endif | ||
510 | |||
487 | __armv4_mmu_cache_on: | 511 | __armv4_mmu_cache_on: |
488 | mov r12, lr | 512 | mov r12, lr |
489 | #ifdef CONFIG_MMU | 513 | #ifdef CONFIG_MMU |
@@ -665,6 +689,12 @@ proc_types: | |||
665 | W(b) __armv4_mpu_cache_off | 689 | W(b) __armv4_mpu_cache_off |
666 | W(b) __armv4_mpu_cache_flush | 690 | W(b) __armv4_mpu_cache_flush |
667 | 691 | ||
692 | .word 0x41069260 @ ARM926EJ-S (v5TEJ) | ||
693 | .word 0xff0ffff0 | ||
694 | b __arm926ejs_mmu_cache_on | ||
695 | b __armv4_mmu_cache_off | ||
696 | b __armv5tej_mmu_cache_flush | ||
697 | |||
668 | .word 0x00007000 @ ARM7 IDs | 698 | .word 0x00007000 @ ARM7 IDs |
669 | .word 0x0000f000 | 699 | .word 0x0000f000 |
670 | mov pc, lr | 700 | mov pc, lr |
@@ -747,12 +777,6 @@ proc_types: | |||
747 | W(b) __armv4_mmu_cache_off | 777 | W(b) __armv4_mmu_cache_off |
748 | W(b) __armv6_mmu_cache_flush | 778 | W(b) __armv6_mmu_cache_flush |
749 | 779 | ||
750 | .word 0x560f5810 @ Marvell PJ4 ARMv6 | ||
751 | .word 0xff0ffff0 | ||
752 | W(b) __armv4_mmu_cache_on | ||
753 | W(b) __armv4_mmu_cache_off | ||
754 | W(b) __armv6_mmu_cache_flush | ||
755 | |||
756 | .word 0x000f0000 @ new CPU Id | 780 | .word 0x000f0000 @ new CPU Id |
757 | .word 0x000f0000 | 781 | .word 0x000f0000 |
758 | W(b) __armv7_mmu_cache_on | 782 | W(b) __armv7_mmu_cache_on |
@@ -1078,5 +1102,5 @@ reloc_code_end: | |||
1078 | 1102 | ||
1079 | .align | 1103 | .align |
1080 | .section ".stack", "aw", %nobits | 1104 | .section ".stack", "aw", %nobits |
1081 | user_stack: .space 4096 | 1105 | .L_user_stack: .space 4096 |
1082 | user_stack_end: | 1106 | .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 | ||
32 | static void putstr(const char *ptr); | 30 | static void putstr(const char *ptr); |
33 | extern void error(char *x); | 31 | extern 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 | */ |
144 | extern char input_data[]; | 142 | extern char input_data[]; |
145 | extern char input_data_end[]; | 143 | extern char input_data_end[]; |
146 | 144 | ||
147 | unsigned char *output_data; | 145 | unsigned char *output_data; |
148 | unsigned long output_ptr; | ||
149 | 146 | ||
150 | unsigned long free_mem_ptr; | 147 | unsigned long free_mem_ptr; |
151 | unsigned long free_mem_end_ptr; | 148 | unsigned 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 | ||
173 | extern void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)); | 170 | extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)); |
174 | 171 | ||
175 | 172 | ||
176 | unsigned long | 173 | void |
177 | decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, | 174 | decompress_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 | } |