Loading arch/arm/boot/compressed/Makefile +15 −4 Original line number Diff line number Diff line Loading @@ -74,7 +74,7 @@ ZTEXTADDR := $(CONFIG_ZBOOT_ROM_TEXT) ZBSSADDR := $(CONFIG_ZBOOT_ROM_BSS) else ZTEXTADDR := 0 ZBSSADDR := ALIGN(4) ZBSSADDR := ALIGN(8) endif SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/ Loading @@ -98,8 +98,6 @@ endif ccflags-y := -fpic -fno-builtin asflags-y := -Wa,-march=all # Provide size of uncompressed kernel to the decompressor via a linker symbol. LDFLAGS_vmlinux = --defsym _image_size=$(shell stat -c "%s" $(obj)/../Image) # Supply ZRELADDR to the decompressor via a linker symbol. ifneq ($(CONFIG_AUTO_ZRELADDR),y) LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR) Loading @@ -122,10 +120,23 @@ lib1funcs = $(obj)/lib1funcs.o $(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE $(call cmd,shipped) # We need to prevent any GOTOFF relocs being used with references # to symbols in the .bss section since we cannot relocate them # independently from the rest at run time. This can be achieved by # ensuring that no private .bss symbols exist, as global symbols # always have a GOT entry which is what we need. # The .data section is already discarded by the linker script so no need # to bother about it here. check_for_bad_syms = \ bad_syms=$$($(CROSS_COMPILE)nm $@ | sed -n 's/^.\{8\} [bc] \(.*\)/\1/p') && \ [ -z "$$bad_syms" ] || \ ( echo "following symbols must have non local/private scope:" >&2; \ echo "$$bad_syms" >&2; rm -f $@; false ) $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \ $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE $(call if_changed,ld) @: @$(check_for_bad_syms) $(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE $(call if_changed,$(suffix_y)) Loading arch/arm/boot/compressed/decompress.c +2 −2 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ extern void error(char *); #include "../../../../lib/decompress_unlzma.c" #endif void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)) int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)) { decompress(input, len, NULL, NULL, output, NULL, error); return decompress(input, len, NULL, NULL, output, NULL, error); } arch/arm/boot/compressed/head.S +42 −15 Original line number Diff line number Diff line Loading @@ -179,16 +179,29 @@ not_angel: bl cache_on restart: adr r0, LC0 ldmia r0, {r1, r2, r3, r5, r6, r9, r11, r12} ldr sp, [r0, #32] ldmia r0, {r1, r2, r3, r6, r10, r11, r12} ldr sp, [r0, #28] /* * We might be running at a different address. We need * to fix up various pointers. */ sub r0, r0, r1 @ calculate the delta offset add r5, r5, r0 @ _start add r6, r6, r0 @ _edata add r10, r10, r0 @ inflated kernel size location /* * The kernel build system appends the size of the * decompressed kernel at the end of the compressed data * in little-endian form. */ ldrb r9, [r10, #0] ldrb lr, [r10, #1] orr r9, r9, lr, lsl #8 ldrb lr, [r10, #2] ldrb r10, [r10, #3] orr r9, r9, lr, lsl #16 orr r9, r9, r10, lsl #24 #ifndef CONFIG_ZBOOT_ROM /* malloc space is above the relocated stack (64k max) */ Loading @@ -206,31 +219,40 @@ restart: adr r0, LC0 /* * Check to see if we will overwrite ourselves. * r4 = final kernel address * r5 = start of this image * r9 = size of decompressed image * r10 = end of this image, including bss/stack/malloc space if non XIP * We basically want: * r4 >= r10 -> OK * r4 + image length <= r5 -> OK * r4 - 16k page directory >= r10 -> OK * r4 + image length <= current position (pc) -> OK */ add r10, r10, #16384 cmp r4, r10 bhs wont_overwrite add r10, r4, r9 cmp r10, r5 ARM( cmp r10, pc ) THUMB( mov lr, pc ) THUMB( cmp r10, lr ) bls wont_overwrite /* * Relocate ourselves past the end of the decompressed kernel. * r5 = start of this image * r6 = _edata * r10 = end of the decompressed kernel * Because we always copy ahead, we need to do it from the end and go * backward in case the source and destination overlap. */ /* Round up to next 256-byte boundary. */ add r10, r10, #256 /* * Bump to the next 256-byte boundary with the size of * the relocation code added. This avoids overwriting * ourself when the offset is small. */ add r10, r10, #((reloc_code_end - restart + 256) & ~255) bic r10, r10, #255 /* Get start of code we want to copy and align it down. */ adr r5, restart bic r5, r5, #31 sub r9, r6, r5 @ size to copy add r9, r9, #31 @ rounded up to a multiple bic r9, r9, #31 @ ... of 32 bytes Loading @@ -245,6 +267,11 @@ restart: adr r0, LC0 /* Preserve offset to relocated code. */ sub r6, r9, r6 #ifndef CONFIG_ZBOOT_ROM /* cache_clean_flush may use the stack, so relocate it */ add sp, sp, r6 #endif bl cache_clean_flush adr r0, BSYM(restart) Loading Loading @@ -333,12 +360,11 @@ not_relocated: mov r0, #0 LC0: .word LC0 @ r1 .word __bss_start @ r2 .word _end @ r3 .word _start @ r5 .word _edata @ r6 .word _image_size @ r9 .word input_data_end - 4 @ r10 (inflated size location) .word _got_start @ r11 .word _got_end @ ip .word user_stack_end @ sp .word .L_user_stack_end @ sp .size LC0, . - LC0 #ifdef CONFIG_ARCH_RPC Loading Loading @@ -1056,8 +1082,9 @@ memdump: mov r12, r0 #endif .ltorg reloc_code_end: .align .section ".stack", "aw", %nobits user_stack: .space 4096 user_stack_end: .L_user_stack: .space 4096 .L_user_stack_end: arch/arm/boot/compressed/misc.c +10 −14 Original line number Diff line number Diff line Loading @@ -26,8 +26,6 @@ unsigned int __machine_arch_type; #include <linux/linkage.h> #include <asm/string.h> #include <asm/unaligned.h> static void putstr(const char *ptr); extern void error(char *x); Loading Loading @@ -139,13 +137,12 @@ void *memcpy(void *__dest, __const void *__src, size_t __n) } /* * gzip delarations * gzip declarations */ extern char input_data[]; extern char input_data_end[]; unsigned char *output_data; unsigned long output_ptr; unsigned long free_mem_ptr; unsigned long free_mem_end_ptr; Loading @@ -170,15 +167,15 @@ asmlinkage void __div0(void) error("Attempting division by 0!"); } extern void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)); extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)); unsigned long void decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, unsigned long free_mem_ptr_end_p, int arch_id) { unsigned char *tmp; int ret; output_data = (unsigned char *)output_start; free_mem_ptr = free_mem_ptr_p; Loading @@ -187,12 +184,11 @@ decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, arch_decomp_setup(); tmp = (unsigned char *) (((unsigned long)input_data_end) - 4); output_ptr = get_unaligned_le32(tmp); putstr("Uncompressing Linux..."); do_decompress(input_data, input_data_end - input_data, ret = do_decompress(input_data, input_data_end - input_data, output_data, error); if (ret) error("decompressor returned an error"); else putstr(" done, booting the kernel.\n"); return output_ptr; } arch/arm/boot/compressed/vmlinux.lds.in +1 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ SECTIONS .bss : { *(.bss) } _end = .; . = ALIGN(8); /* the stack must be 64-bit aligned */ .stack : { *(.stack) } .stab 0 : { *(.stab) } Loading Loading
arch/arm/boot/compressed/Makefile +15 −4 Original line number Diff line number Diff line Loading @@ -74,7 +74,7 @@ ZTEXTADDR := $(CONFIG_ZBOOT_ROM_TEXT) ZBSSADDR := $(CONFIG_ZBOOT_ROM_BSS) else ZTEXTADDR := 0 ZBSSADDR := ALIGN(4) ZBSSADDR := ALIGN(8) endif SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/ Loading @@ -98,8 +98,6 @@ endif ccflags-y := -fpic -fno-builtin asflags-y := -Wa,-march=all # Provide size of uncompressed kernel to the decompressor via a linker symbol. LDFLAGS_vmlinux = --defsym _image_size=$(shell stat -c "%s" $(obj)/../Image) # Supply ZRELADDR to the decompressor via a linker symbol. ifneq ($(CONFIG_AUTO_ZRELADDR),y) LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR) Loading @@ -122,10 +120,23 @@ lib1funcs = $(obj)/lib1funcs.o $(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE $(call cmd,shipped) # We need to prevent any GOTOFF relocs being used with references # to symbols in the .bss section since we cannot relocate them # independently from the rest at run time. This can be achieved by # ensuring that no private .bss symbols exist, as global symbols # always have a GOT entry which is what we need. # The .data section is already discarded by the linker script so no need # to bother about it here. check_for_bad_syms = \ bad_syms=$$($(CROSS_COMPILE)nm $@ | sed -n 's/^.\{8\} [bc] \(.*\)/\1/p') && \ [ -z "$$bad_syms" ] || \ ( echo "following symbols must have non local/private scope:" >&2; \ echo "$$bad_syms" >&2; rm -f $@; false ) $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \ $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE $(call if_changed,ld) @: @$(check_for_bad_syms) $(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE $(call if_changed,$(suffix_y)) Loading
arch/arm/boot/compressed/decompress.c +2 −2 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ extern void error(char *); #include "../../../../lib/decompress_unlzma.c" #endif void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)) int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)) { decompress(input, len, NULL, NULL, output, NULL, error); return decompress(input, len, NULL, NULL, output, NULL, error); }
arch/arm/boot/compressed/head.S +42 −15 Original line number Diff line number Diff line Loading @@ -179,16 +179,29 @@ not_angel: bl cache_on restart: adr r0, LC0 ldmia r0, {r1, r2, r3, r5, r6, r9, r11, r12} ldr sp, [r0, #32] ldmia r0, {r1, r2, r3, r6, r10, r11, r12} ldr sp, [r0, #28] /* * We might be running at a different address. We need * to fix up various pointers. */ sub r0, r0, r1 @ calculate the delta offset add r5, r5, r0 @ _start add r6, r6, r0 @ _edata add r10, r10, r0 @ inflated kernel size location /* * The kernel build system appends the size of the * decompressed kernel at the end of the compressed data * in little-endian form. */ ldrb r9, [r10, #0] ldrb lr, [r10, #1] orr r9, r9, lr, lsl #8 ldrb lr, [r10, #2] ldrb r10, [r10, #3] orr r9, r9, lr, lsl #16 orr r9, r9, r10, lsl #24 #ifndef CONFIG_ZBOOT_ROM /* malloc space is above the relocated stack (64k max) */ Loading @@ -206,31 +219,40 @@ restart: adr r0, LC0 /* * Check to see if we will overwrite ourselves. * r4 = final kernel address * r5 = start of this image * r9 = size of decompressed image * r10 = end of this image, including bss/stack/malloc space if non XIP * We basically want: * r4 >= r10 -> OK * r4 + image length <= r5 -> OK * r4 - 16k page directory >= r10 -> OK * r4 + image length <= current position (pc) -> OK */ add r10, r10, #16384 cmp r4, r10 bhs wont_overwrite add r10, r4, r9 cmp r10, r5 ARM( cmp r10, pc ) THUMB( mov lr, pc ) THUMB( cmp r10, lr ) bls wont_overwrite /* * Relocate ourselves past the end of the decompressed kernel. * r5 = start of this image * r6 = _edata * r10 = end of the decompressed kernel * Because we always copy ahead, we need to do it from the end and go * backward in case the source and destination overlap. */ /* Round up to next 256-byte boundary. */ add r10, r10, #256 /* * Bump to the next 256-byte boundary with the size of * the relocation code added. This avoids overwriting * ourself when the offset is small. */ add r10, r10, #((reloc_code_end - restart + 256) & ~255) bic r10, r10, #255 /* Get start of code we want to copy and align it down. */ adr r5, restart bic r5, r5, #31 sub r9, r6, r5 @ size to copy add r9, r9, #31 @ rounded up to a multiple bic r9, r9, #31 @ ... of 32 bytes Loading @@ -245,6 +267,11 @@ restart: adr r0, LC0 /* Preserve offset to relocated code. */ sub r6, r9, r6 #ifndef CONFIG_ZBOOT_ROM /* cache_clean_flush may use the stack, so relocate it */ add sp, sp, r6 #endif bl cache_clean_flush adr r0, BSYM(restart) Loading Loading @@ -333,12 +360,11 @@ not_relocated: mov r0, #0 LC0: .word LC0 @ r1 .word __bss_start @ r2 .word _end @ r3 .word _start @ r5 .word _edata @ r6 .word _image_size @ r9 .word input_data_end - 4 @ r10 (inflated size location) .word _got_start @ r11 .word _got_end @ ip .word user_stack_end @ sp .word .L_user_stack_end @ sp .size LC0, . - LC0 #ifdef CONFIG_ARCH_RPC Loading Loading @@ -1056,8 +1082,9 @@ memdump: mov r12, r0 #endif .ltorg reloc_code_end: .align .section ".stack", "aw", %nobits user_stack: .space 4096 user_stack_end: .L_user_stack: .space 4096 .L_user_stack_end:
arch/arm/boot/compressed/misc.c +10 −14 Original line number Diff line number Diff line Loading @@ -26,8 +26,6 @@ unsigned int __machine_arch_type; #include <linux/linkage.h> #include <asm/string.h> #include <asm/unaligned.h> static void putstr(const char *ptr); extern void error(char *x); Loading Loading @@ -139,13 +137,12 @@ void *memcpy(void *__dest, __const void *__src, size_t __n) } /* * gzip delarations * gzip declarations */ extern char input_data[]; extern char input_data_end[]; unsigned char *output_data; unsigned long output_ptr; unsigned long free_mem_ptr; unsigned long free_mem_end_ptr; Loading @@ -170,15 +167,15 @@ asmlinkage void __div0(void) error("Attempting division by 0!"); } extern void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)); extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)); unsigned long void decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, unsigned long free_mem_ptr_end_p, int arch_id) { unsigned char *tmp; int ret; output_data = (unsigned char *)output_start; free_mem_ptr = free_mem_ptr_p; Loading @@ -187,12 +184,11 @@ decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, arch_decomp_setup(); tmp = (unsigned char *) (((unsigned long)input_data_end) - 4); output_ptr = get_unaligned_le32(tmp); putstr("Uncompressing Linux..."); do_decompress(input_data, input_data_end - input_data, ret = do_decompress(input_data, input_data_end - input_data, output_data, error); if (ret) error("decompressor returned an error"); else putstr(" done, booting the kernel.\n"); return output_ptr; }
arch/arm/boot/compressed/vmlinux.lds.in +1 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ SECTIONS .bss : { *(.bss) } _end = .; . = ALIGN(8); /* the stack must be 64-bit aligned */ .stack : { *(.stack) } .stab 0 : { *(.stab) } Loading