Commit 7b764153 authored by Russell King's avatar Russell King

Merge branch 'zImage_fixes' of git://git.linaro.org/people/nico/linux into devel-stable

parents c93212f3 8d7e4cc2
...@@ -74,7 +74,7 @@ ZTEXTADDR := $(CONFIG_ZBOOT_ROM_TEXT) ...@@ -74,7 +74,7 @@ ZTEXTADDR := $(CONFIG_ZBOOT_ROM_TEXT)
ZBSSADDR := $(CONFIG_ZBOOT_ROM_BSS) ZBSSADDR := $(CONFIG_ZBOOT_ROM_BSS)
else else
ZTEXTADDR := 0 ZTEXTADDR := 0
ZBSSADDR := ALIGN(4) ZBSSADDR := ALIGN(8)
endif endif
SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/ SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
...@@ -98,8 +98,6 @@ endif ...@@ -98,8 +98,6 @@ endif
ccflags-y := -fpic -fno-builtin ccflags-y := -fpic -fno-builtin
asflags-y := -Wa,-march=all 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. # Supply ZRELADDR to the decompressor via a linker symbol.
ifneq ($(CONFIG_AUTO_ZRELADDR),y) ifneq ($(CONFIG_AUTO_ZRELADDR),y)
LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR) LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR)
...@@ -122,10 +120,23 @@ lib1funcs = $(obj)/lib1funcs.o ...@@ -122,10 +120,23 @@ lib1funcs = $(obj)/lib1funcs.o
$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE $(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE
$(call cmd,shipped) $(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 \ $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE
$(call if_changed,ld) $(call if_changed,ld)
@: @$(check_for_bad_syms)
$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE $(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE
$(call if_changed,$(suffix_y)) $(call if_changed,$(suffix_y))
......
...@@ -44,7 +44,7 @@ extern void error(char *); ...@@ -44,7 +44,7 @@ extern void error(char *);
#include "../../../../lib/decompress_unlzma.c" #include "../../../../lib/decompress_unlzma.c"
#endif #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);
} }
...@@ -179,16 +179,29 @@ not_angel: ...@@ -179,16 +179,29 @@ not_angel:
bl cache_on bl cache_on
restart: adr r0, LC0 restart: adr r0, LC0
ldmia r0, {r1, r2, r3, r5, r6, r9, r11, r12} ldmia r0, {r1, r2, r3, r6, r10, r11, r12}
ldr sp, [r0, #32] ldr sp, [r0, #28]
/* /*
* We might be running at a different address. We need * We might be running at a different address. We need
* to fix up various pointers. * to fix up various pointers.
*/ */
sub r0, r0, r1 @ calculate the delta offset sub r0, r0, r1 @ calculate the delta offset
add r5, r5, r0 @ _start
add r6, r6, r0 @ _edata 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 #ifndef CONFIG_ZBOOT_ROM
/* malloc space is above the relocated stack (64k max) */ /* malloc space is above the relocated stack (64k max) */
...@@ -206,31 +219,40 @@ restart: adr r0, LC0 ...@@ -206,31 +219,40 @@ restart: adr r0, LC0
/* /*
* Check to see if we will overwrite ourselves. * Check to see if we will overwrite ourselves.
* r4 = final kernel address * r4 = final kernel address
* r5 = start of this image
* r9 = size of decompressed image * r9 = size of decompressed image
* r10 = end of this image, including bss/stack/malloc space if non XIP * r10 = end of this image, including bss/stack/malloc space if non XIP
* We basically want: * We basically want:
* r4 >= r10 -> OK * r4 - 16k page directory >= r10 -> OK
* r4 + image length <= r5 -> OK * r4 + image length <= current position (pc) -> OK
*/ */
add r10, r10, #16384
cmp r4, r10 cmp r4, r10
bhs wont_overwrite bhs wont_overwrite
add r10, r4, r9 add r10, r4, r9
cmp r10, r5 ARM( cmp r10, pc )
THUMB( mov lr, pc )
THUMB( cmp r10, lr )
bls wont_overwrite bls wont_overwrite
/* /*
* Relocate ourselves past the end of the decompressed kernel. * Relocate ourselves past the end of the decompressed kernel.
* r5 = start of this image
* r6 = _edata * r6 = _edata
* r10 = end of the decompressed kernel * r10 = end of the decompressed kernel
* Because we always copy ahead, we need to do it from the end and go * Because we always copy ahead, we need to do it from the end and go
* backward in case the source and destination overlap. * 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 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 sub r9, r6, r5 @ size to copy
add r9, r9, #31 @ rounded up to a multiple add r9, r9, #31 @ rounded up to a multiple
bic r9, r9, #31 @ ... of 32 bytes bic r9, r9, #31 @ ... of 32 bytes
...@@ -245,6 +267,11 @@ restart: adr r0, LC0 ...@@ -245,6 +267,11 @@ restart: adr r0, LC0
/* Preserve offset to relocated code. */ /* Preserve offset to relocated code. */
sub r6, r9, r6 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 bl cache_clean_flush
adr r0, BSYM(restart) adr r0, BSYM(restart)
...@@ -333,12 +360,11 @@ not_relocated: mov r0, #0 ...@@ -333,12 +360,11 @@ not_relocated: mov r0, #0
LC0: .word LC0 @ r1 LC0: .word LC0 @ r1
.word __bss_start @ r2 .word __bss_start @ r2
.word _end @ r3 .word _end @ r3
.word _start @ r5
.word _edata @ r6 .word _edata @ r6
.word _image_size @ r9 .word input_data_end - 4 @ r10 (inflated size location)
.word _got_start @ r11 .word _got_start @ r11
.word _got_end @ ip .word _got_end @ ip
.word user_stack_end @ sp .word .L_user_stack_end @ sp
.size LC0, . - LC0 .size LC0, . - LC0
#ifdef CONFIG_ARCH_RPC #ifdef CONFIG_ARCH_RPC
...@@ -1056,8 +1082,9 @@ memdump: mov r12, r0 ...@@ -1056,8 +1082,9 @@ memdump: mov r12, r0
#endif #endif
.ltorg .ltorg
reloc_code_end:
.align .align
.section ".stack", "aw", %nobits .section ".stack", "aw", %nobits
user_stack: .space 4096 .L_user_stack: .space 4096
user_stack_end: .L_user_stack_end:
...@@ -26,8 +26,6 @@ unsigned int __machine_arch_type; ...@@ -26,8 +26,6 @@ unsigned int __machine_arch_type;
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/string.h> #include <asm/string.h>
#include <asm/unaligned.h>
static void putstr(const char *ptr); static void putstr(const char *ptr);
extern void error(char *x); extern void error(char *x);
...@@ -139,13 +137,12 @@ void *memcpy(void *__dest, __const void *__src, size_t __n) ...@@ -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[];
extern char input_data_end[]; extern char input_data_end[];
unsigned char *output_data; unsigned char *output_data;
unsigned long output_ptr;
unsigned long free_mem_ptr; unsigned long free_mem_ptr;
unsigned long free_mem_end_ptr; unsigned long free_mem_end_ptr;
...@@ -170,15 +167,15 @@ asmlinkage void __div0(void) ...@@ -170,15 +167,15 @@ asmlinkage void __div0(void)
error("Attempting division by 0!"); 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, decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
unsigned long free_mem_ptr_end_p, unsigned long free_mem_ptr_end_p,
int arch_id) int arch_id)
{ {
unsigned char *tmp; int ret;
output_data = (unsigned char *)output_start; output_data = (unsigned char *)output_start;
free_mem_ptr = free_mem_ptr_p; free_mem_ptr = free_mem_ptr_p;
...@@ -187,12 +184,11 @@ decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, ...@@ -187,12 +184,11 @@ decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
arch_decomp_setup(); arch_decomp_setup();
tmp = (unsigned char *) (((unsigned long)input_data_end) - 4);
output_ptr = get_unaligned_le32(tmp);
putstr("Uncompressing Linux..."); 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); output_data, error);
putstr(" done, booting the kernel.\n"); if (ret)
return output_ptr; error("decompressor returned an error");
else
putstr(" done, booting the kernel.\n");
} }
...@@ -54,6 +54,7 @@ SECTIONS ...@@ -54,6 +54,7 @@ SECTIONS
.bss : { *(.bss) } .bss : { *(.bss) }
_end = .; _end = .;
. = ALIGN(8); /* the stack must be 64-bit aligned */
.stack : { *(.stack) } .stack : { *(.stack) }
.stab 0 : { *(.stab) } .stab 0 : { *(.stab) }
......
...@@ -25,8 +25,7 @@ ...@@ -25,8 +25,7 @@
#include <mach/serial.h> #include <mach/serial.h>
static u32 *uart; u32 *uart;
static u32 *uart_info = (u32 *)(DAVINCI_UART_INFO);
/* PORT_16C550A, in polled non-fifo mode */ /* PORT_16C550A, in polled non-fifo mode */
static void putc(char c) static void putc(char c)
...@@ -44,6 +43,8 @@ static inline void flush(void) ...@@ -44,6 +43,8 @@ static inline void flush(void)
static inline void set_uart_info(u32 phys, void * __iomem virt) static inline void set_uart_info(u32 phys, void * __iomem virt)
{ {
u32 *uart_info = (u32 *)(DAVINCI_UART_INFO);
uart = (u32 *)phys; uart = (u32 *)phys;
uart_info[0] = phys; uart_info[0] = phys;
uart_info[1] = (u32)virt; uart_info[1] = (u32)virt;
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include <linux/serial_reg.h> #include <linux/serial_reg.h>
#include <mach/hardware.h> #include <mach/hardware.h>
static volatile unsigned long *UART = (unsigned long *)GEMINI_UART_BASE; static volatile unsigned long * const UART = (unsigned long *)GEMINI_UART_BASE;
/* /*
* The following code assumes the serial port has already been * The following code assumes the serial port has already been
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include <linux/serial_reg.h> #include <linux/serial_reg.h>
#include <mach/hardware.h> #include <mach/hardware.h>
static volatile u8 *uart_base; volatile u8 *uart_base;
#define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE) #define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE)
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include <linux/serial_reg.h> #include <linux/serial_reg.h>
#include <mach/hardware.h> #include <mach/hardware.h>
static volatile u32 *uart_base; volatile u32 *uart_base;
#define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE) #define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE)
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#define TX_DONE (UART_LSR_TEMT|UART_LSR_THRE) #define TX_DONE (UART_LSR_TEMT|UART_LSR_THRE)
static volatile u32* uart_base; volatile u32* uart_base;
static inline void putc(int c) static inline void putc(int c)
{ {
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#define UART2_BASE (APB_PHYS_BASE + 0x17000) #define UART2_BASE (APB_PHYS_BASE + 0x17000)
#define UART3_BASE (APB_PHYS_BASE + 0x18000) #define UART3_BASE (APB_PHYS_BASE + 0x18000)
static volatile unsigned long *UART; volatile unsigned long *UART;
static inline void putc(char c) static inline void putc(char c)
{ {
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include <asm/mach-types.h> #include <asm/mach-types.h>
static unsigned long mxs_duart_base; unsigned long mxs_duart_base;
#define MXS_DUART(x) (*(volatile unsigned long *)(mxs_duart_base + (x))) #define MXS_DUART(x) (*(volatile unsigned long *)(mxs_duart_base + (x)))
......
...@@ -20,7 +20,7 @@ static void putc_dummy(char c, void __iomem *base) ...@@ -20,7 +20,7 @@ static void putc_dummy(char c, void __iomem *base)
/* nothing */ /* nothing */
} }
static int timeout; int timeout;
static void putc_ns9360(char c, void __iomem *base) static void putc_ns9360(char c, void __iomem *base)
{ {
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#define arch_decomp_wdog() #define arch_decomp_wdog()
#define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE) #define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE)
static u32 * uart_base = (u32 *)UART0_PA; static u32 * const uart_base = (u32 *)UART0_PA;
static void putc(int ch) static void putc(int ch)
{ {
......
...@@ -16,9 +16,9 @@ ...@@ -16,9 +16,9 @@
#define BTUART_BASE (0x40200000) #define BTUART_BASE (0x40200000)
#define STUART_BASE (0x40700000) #define STUART_BASE (0x40700000)
static unsigned long uart_base; unsigned long uart_base;
static unsigned int uart_shift; unsigned int uart_shift;
static unsigned int uart_is_pxa; unsigned int uart_is_pxa;
static inline unsigned char uart_read(int offset) static inline unsigned char uart_read(int offset)
{ {
......
...@@ -66,12 +66,12 @@ extern __attribute__((pure)) struct param_struct *params(void); ...@@ -66,12 +66,12 @@ extern __attribute__((pure)) struct param_struct *params(void);
#define params (params()) #define params (params())
#ifndef STANDALONE_DEBUG #ifndef STANDALONE_DEBUG
static unsigned long video_num_cols; unsigned long video_num_cols;
static unsigned long video_num_rows; unsigned long video_num_rows;
static unsigned long video_x; unsigned long video_x;
static unsigned long video_y; unsigned long video_y;
static unsigned char bytes_per_char_v; unsigned char bytes_per_char_v;
static int white; int white;
/* /*
* This does not append a newline * This does not append a newline
......
...@@ -24,8 +24,8 @@ typedef unsigned int upf_t; /* cannot include linux/serial_core.h */ ...@@ -24,8 +24,8 @@ typedef unsigned int upf_t; /* cannot include linux/serial_core.h */
/* uart setup */ /* uart setup */
static unsigned int fifo_mask; unsigned int fifo_mask;
static unsigned int fifo_max; unsigned int fifo_max;
/* forward declerations */ /* forward declerations */
...@@ -43,7 +43,7 @@ static void arch_detect_cpu(void); ...@@ -43,7 +43,7 @@ static void arch_detect_cpu(void);
/* how many bytes we allow into the FIFO at a time in FIFO mode */ /* how many bytes we allow into the FIFO at a time in FIFO mode */
#define FIFO_MAX (14) #define FIFO_MAX (14)
static unsigned long uart_base; unsigned long uart_base;
static __inline__ void get_uart_base(void) static __inline__ void get_uart_base(void)
{ {
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include <linux/amba/serial.h> #include <linux/amba/serial.h>
#include <mach/hardware.h> #include <mach/hardware.h>
static u32 ux500_uart_base; u32 ux500_uart_base;
static void putc(const char c) static void putc(const char c)
{ {
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#define arch_decomp_wdog() #define arch_decomp_wdog()
#define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE) #define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE)
static volatile u32 * uart_base = (u32 *)UART0_PA; static volatile u32 * const uart_base = (u32 *)UART0_PA;
static void putc(int ch) static void putc(int ch)
{ {
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include <asm/mach-types.h> #include <asm/mach-types.h>
static unsigned long uart_base; unsigned long uart_base;
#define UART(x) (*(volatile unsigned long *)(uart_base + (x))) #define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
......
...@@ -27,8 +27,8 @@ ...@@ -27,8 +27,8 @@
#define MDR1_MODE_MASK 0x07 #define MDR1_MODE_MASK 0x07
static volatile u8 *uart_base; volatile u8 *uart_base;
static int uart_shift; int uart_shift;
/* /*
* Store the DEBUG_LL uart number into memory. * Store the DEBUG_LL uart number into memory.
......
...@@ -18,8 +18,8 @@ typedef unsigned int upf_t; /* cannot include linux/serial_core.h */ ...@@ -18,8 +18,8 @@ typedef unsigned int upf_t; /* cannot include linux/serial_core.h */
/* uart setup */ /* uart setup */
static unsigned int fifo_mask; unsigned int fifo_mask;
static unsigned int fifo_max; unsigned int fifo_max;
/* forward declerations */ /* forward declerations */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment