diff options
Diffstat (limited to 'arch/arm/boot/compressed/misc.c')
| -rw-r--r-- | arch/arm/boot/compressed/misc.c | 325 |
1 files changed, 58 insertions, 267 deletions
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index 9b444022cb9..d4f891f5699 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c @@ -18,20 +18,18 @@ unsigned int __machine_arch_type; -#include <linux/string.h> - -#ifdef STANDALONE_DEBUG -#define putstr printf -#else +#include <linux/compiler.h> /* for inline */ +#include <linux/types.h> +#include <linux/linkage.h> static void putstr(const char *ptr); +extern void error(char *x); -#include <linux/compiler.h> -#include <asm/arch/uncompress.h> +#include CONFIG_UNCOMPRESS_INCLUDE #ifdef CONFIG_DEBUG_ICEDCC -#ifdef CONFIG_CPU_V6 +#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7) static void icedcc_putc(int ch) { @@ -47,6 +45,23 @@ static void icedcc_putc(int ch) asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch)); } + +#elif defined(CONFIG_CPU_XSCALE) + +static void icedcc_putc(int ch) +{ + int status, i = 0x4000000; + + do { + if (--i < 0) + return; + + asm volatile ("mrc p14, 0, %0, c14, c0, 0" : "=r" (status)); + } while (status & (1 << 28)); + + asm("mcr p14, 0, %0, c8, c0, 0" : : "r" (ch)); +} + #else static void icedcc_putc(int ch) @@ -66,7 +81,6 @@ static void icedcc_putc(int ch) #endif #define putc(ch) icedcc_putc(ch) -#define flush() do { } while (0) #endif static void putstr(const char *ptr) @@ -82,296 +96,73 @@ static void putstr(const char *ptr) flush(); } -#endif - -#define __ptr_t void * - /* - * Optimised C version of memzero for the ARM. + * gzip declarations */ -void __memzero (__ptr_t s, size_t n) -{ - union { void *vp; unsigned long *ulp; unsigned char *ucp; } u; - int i; - - u.vp = s; - - for (i = n >> 5; i > 0; i--) { - *u.ulp++ = 0; - *u.ulp++ = 0; - *u.ulp++ = 0; - *u.ulp++ = 0; - *u.ulp++ = 0; - *u.ulp++ = 0; - *u.ulp++ = 0; - *u.ulp++ = 0; - } - - if (n & 1 << 4) { - *u.ulp++ = 0; - *u.ulp++ = 0; - *u.ulp++ = 0; - *u.ulp++ = 0; - } - - if (n & 1 << 3) { - *u.ulp++ = 0; - *u.ulp++ = 0; - } - - if (n & 1 << 2) - *u.ulp++ = 0; - - if (n & 1 << 1) { - *u.ucp++ = 0; - *u.ucp++ = 0; - } - - if (n & 1) - *u.ucp++ = 0; -} - -static inline __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src, - size_t __n) -{ - int i = 0; - unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src; - - for (i = __n >> 3; i > 0; i--) { - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - } - - if (__n & 1 << 2) { - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - } - - if (__n & 1 << 1) { - *d++ = *s++; - *d++ = *s++; - } - - if (__n & 1) - *d++ = *s++; - - return __dest; -} - -/* - * gzip delarations - */ -#define OF(args) args -#define STATIC static - -typedef unsigned char uch; -typedef unsigned short ush; -typedef unsigned long ulg; - -#define WSIZE 0x8000 /* Window size must be at least 32k, */ - /* and a power of two */ - -static uch *inbuf; /* input buffer */ -static uch window[WSIZE]; /* Sliding window buffer */ - -static unsigned insize; /* valid bytes in inbuf */ -static unsigned inptr; /* index of next byte to be processed in inbuf */ -static unsigned outcnt; /* bytes in output buffer */ - -/* gzip flag byte */ -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ -#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ -#define COMMENT 0x10 /* bit 4 set: file comment present */ -#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ -#define RESERVED 0xC0 /* bit 6,7: reserved */ - -#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) - -/* Diagnostic functions */ -#ifdef DEBUG -# define Assert(cond,msg) {if(!(cond)) error(msg);} -# define Trace(x) fprintf x -# define Tracev(x) {if (verbose) fprintf x ;} -# define Tracevv(x) {if (verbose>1) fprintf x ;} -# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} -# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - -static int fill_inbuf(void); -static void flush_window(void); -static void error(char *m); -static void gzip_mark(void **); -static void gzip_release(void **); - extern char input_data[]; extern char input_data_end[]; -static uch *output_data; -static ulg output_ptr; -static ulg bytes_out; - -static void *malloc(int size); -static void free(void *where); -static void error(char *m); -static void gzip_mark(void **); -static void gzip_release(void **); +unsigned char *output_data; -static void putstr(const char *); +unsigned long free_mem_ptr; +unsigned long free_mem_end_ptr; -extern int end; -static ulg free_mem_ptr; -static ulg free_mem_ptr_end; - -#define HEAP_SIZE 0x3000 - -#include "../../../../lib/inflate.c" +#ifndef arch_error +#define arch_error(x) +#endif -#ifndef STANDALONE_DEBUG -static void *malloc(int size) +void error(char *x) { - void *p; - - if (size <0) error("Malloc error"); - if (free_mem_ptr <= 0) error("Memory error"); - - free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ - - p = (void *)free_mem_ptr; - free_mem_ptr += size; + arch_error(x); - if (free_mem_ptr >= free_mem_ptr_end) - error("Out of memory"); - return p; -} + putstr("\n\n"); + putstr(x); + putstr("\n\n -- System halted"); -static void free(void *where) -{ /* gzip_mark & gzip_release do the free */ + while(1); /* Halt */ } -static void gzip_mark(void **ptr) +asmlinkage void __div0(void) { - arch_decomp_wdog(); - *ptr = (void *) free_mem_ptr; + error("Attempting division by 0!"); } -static void gzip_release(void **ptr) -{ - arch_decomp_wdog(); - free_mem_ptr = (long) *ptr; -} -#else -static void gzip_mark(void **ptr) -{ -} +unsigned long __stack_chk_guard; -static void gzip_release(void **ptr) +void __stack_chk_guard_setup(void) { + __stack_chk_guard = 0x000a0dff; } -#endif -/* =========================================================================== - * Fill the input buffer. This is called only when the buffer is empty - * and at least one byte is really needed. - */ -int fill_inbuf(void) +void __stack_chk_fail(void) { - if (insize != 0) - error("ran out of input data"); - - inbuf = input_data; - insize = &input_data_end[0] - &input_data[0]; - - inptr = 1; - return inbuf[0]; + error("stack-protector: Kernel stack is corrupted\n"); } -/* =========================================================================== - * Write the output window window[0..outcnt-1] and update crc and bytes_out. - * (Used for the decompressed data only.) - */ -void flush_window(void) -{ - ulg c = crc; - unsigned n; - uch *in, *out, ch; - - in = window; - out = &output_data[output_ptr]; - for (n = 0; n < outcnt; n++) { - ch = *out++ = *in++; - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); - } - crc = c; - bytes_out += (ulg)outcnt; - output_ptr += (ulg)outcnt; - outcnt = 0; - putstr("."); -} +extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)); -#ifndef arch_error -#define arch_error(x) -#endif -static void error(char *x) +void +decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, + unsigned long free_mem_ptr_end_p, + int arch_id) { - arch_error(x); + int ret; - putstr("\n\n"); - putstr(x); - putstr("\n\n -- System halted"); + __stack_chk_guard_setup(); - while(1); /* Halt */ -} - -#ifndef STANDALONE_DEBUG - -ulg -decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p, - int arch_id) -{ - output_data = (uch *)output_start; /* Points to kernel start */ + output_data = (unsigned char *)output_start; free_mem_ptr = free_mem_ptr_p; - free_mem_ptr_end = free_mem_ptr_end_p; + free_mem_end_ptr = free_mem_ptr_end_p; __machine_arch_type = arch_id; arch_decomp_setup(); - makecrc(); putstr("Uncompressing Linux..."); - gunzip(); - putstr(" done, booting the kernel.\n"); - return output_ptr; + 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"); } -#else - -char output_buffer[1500*1024]; - -int main() -{ - output_data = output_buffer; - - makecrc(); - putstr("Uncompressing Linux..."); - gunzip(); - putstr("done.\n"); - return 0; -} -#endif - |
