diff options
Diffstat (limited to 'arch/arm/boot/compressed/misc.c')
| -rw-r--r-- | arch/arm/boot/compressed/misc.c | 129 |
1 files changed, 46 insertions, 83 deletions
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index 17153b54613b..56a0d116d271 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c | |||
| @@ -18,10 +18,15 @@ | |||
| 18 | 18 | ||
| 19 | unsigned int __machine_arch_type; | 19 | unsigned int __machine_arch_type; |
| 20 | 20 | ||
| 21 | #define _LINUX_STRING_H_ | ||
| 22 | |||
| 21 | #include <linux/compiler.h> /* for inline */ | 23 | #include <linux/compiler.h> /* for inline */ |
| 22 | #include <linux/types.h> /* for size_t */ | 24 | #include <linux/types.h> /* for size_t */ |
| 23 | #include <linux/stddef.h> /* for NULL */ | 25 | #include <linux/stddef.h> /* for NULL */ |
| 24 | #include <asm/string.h> | 26 | #include <asm/string.h> |
| 27 | #include <linux/linkage.h> | ||
| 28 | |||
| 29 | #include <asm/unaligned.h> | ||
| 25 | 30 | ||
| 26 | #ifdef STANDALONE_DEBUG | 31 | #ifdef STANDALONE_DEBUG |
| 27 | #define putstr printf | 32 | #define putstr printf |
| @@ -48,6 +53,18 @@ static void icedcc_putc(int ch) | |||
| 48 | 53 | ||
| 49 | asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch)); | 54 | asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch)); |
| 50 | } | 55 | } |
| 56 | |||
| 57 | #elif defined(CONFIG_CPU_V7) | ||
| 58 | |||
| 59 | static void icedcc_putc(int ch) | ||
| 60 | { | ||
| 61 | asm( | ||
| 62 | "wait: mrc p14, 0, pc, c0, c1, 0 \n\ | ||
| 63 | bcs wait \n\ | ||
| 64 | mcr p14, 0, %0, c0, c5, 0 " | ||
| 65 | : : "r" (ch)); | ||
| 66 | } | ||
| 67 | |||
| 51 | #elif defined(CONFIG_CPU_XSCALE) | 68 | #elif defined(CONFIG_CPU_XSCALE) |
| 52 | 69 | ||
| 53 | static void icedcc_putc(int ch) | 70 | static void icedcc_putc(int ch) |
| @@ -83,7 +100,6 @@ static void icedcc_putc(int ch) | |||
| 83 | #endif | 100 | #endif |
| 84 | 101 | ||
| 85 | #define putc(ch) icedcc_putc(ch) | 102 | #define putc(ch) icedcc_putc(ch) |
| 86 | #define flush() do { } while (0) | ||
| 87 | #endif | 103 | #endif |
| 88 | 104 | ||
| 89 | static void putstr(const char *ptr) | 105 | static void putstr(const char *ptr) |
| @@ -188,34 +204,8 @@ static inline __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src, | |||
| 188 | /* | 204 | /* |
| 189 | * gzip delarations | 205 | * gzip delarations |
| 190 | */ | 206 | */ |
| 191 | #define OF(args) args | ||
| 192 | #define STATIC static | 207 | #define STATIC static |
| 193 | 208 | ||
| 194 | typedef unsigned char uch; | ||
| 195 | typedef unsigned short ush; | ||
| 196 | typedef unsigned long ulg; | ||
| 197 | |||
| 198 | #define WSIZE 0x8000 /* Window size must be at least 32k, */ | ||
| 199 | /* and a power of two */ | ||
| 200 | |||
| 201 | static uch *inbuf; /* input buffer */ | ||
| 202 | static uch window[WSIZE]; /* Sliding window buffer */ | ||
| 203 | |||
| 204 | static unsigned insize; /* valid bytes in inbuf */ | ||
| 205 | static unsigned inptr; /* index of next byte to be processed in inbuf */ | ||
| 206 | static unsigned outcnt; /* bytes in output buffer */ | ||
| 207 | |||
| 208 | /* gzip flag byte */ | ||
| 209 | #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ | ||
| 210 | #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ | ||
| 211 | #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ | ||
| 212 | #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ | ||
| 213 | #define COMMENT 0x10 /* bit 4 set: file comment present */ | ||
| 214 | #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ | ||
| 215 | #define RESERVED 0xC0 /* bit 6,7: reserved */ | ||
| 216 | |||
| 217 | #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) | ||
| 218 | |||
| 219 | /* Diagnostic functions */ | 209 | /* Diagnostic functions */ |
| 220 | #ifdef DEBUG | 210 | #ifdef DEBUG |
| 221 | # define Assert(cond,msg) {if(!(cond)) error(msg);} | 211 | # define Assert(cond,msg) {if(!(cond)) error(msg);} |
| @@ -233,24 +223,20 @@ static unsigned outcnt; /* bytes in output buffer */ | |||
| 233 | # define Tracecv(c,x) | 223 | # define Tracecv(c,x) |
| 234 | #endif | 224 | #endif |
| 235 | 225 | ||
| 236 | static int fill_inbuf(void); | ||
| 237 | static void flush_window(void); | ||
| 238 | static void error(char *m); | 226 | static void error(char *m); |
| 239 | 227 | ||
| 240 | extern char input_data[]; | 228 | extern char input_data[]; |
| 241 | extern char input_data_end[]; | 229 | extern char input_data_end[]; |
| 242 | 230 | ||
| 243 | static uch *output_data; | 231 | static unsigned char *output_data; |
| 244 | static ulg output_ptr; | 232 | static unsigned long output_ptr; |
| 245 | static ulg bytes_out; | ||
| 246 | 233 | ||
| 247 | static void error(char *m); | 234 | static void error(char *m); |
| 248 | 235 | ||
| 249 | static void putstr(const char *); | 236 | static void putstr(const char *); |
| 250 | 237 | ||
| 251 | extern int end; | 238 | static unsigned long free_mem_ptr; |
| 252 | static ulg free_mem_ptr; | 239 | static unsigned long free_mem_end_ptr; |
| 253 | static ulg free_mem_end_ptr; | ||
| 254 | 240 | ||
| 255 | #ifdef STANDALONE_DEBUG | 241 | #ifdef STANDALONE_DEBUG |
| 256 | #define NO_INFLATE_MALLOC | 242 | #define NO_INFLATE_MALLOC |
| @@ -258,46 +244,13 @@ static ulg free_mem_end_ptr; | |||
| 258 | 244 | ||
| 259 | #define ARCH_HAS_DECOMP_WDOG | 245 | #define ARCH_HAS_DECOMP_WDOG |
| 260 | 246 | ||
| 261 | #include "../../../../lib/inflate.c" | 247 | #ifdef CONFIG_KERNEL_GZIP |
| 262 | 248 | #include "../../../../lib/decompress_inflate.c" | |
| 263 | /* =========================================================================== | 249 | #endif |
| 264 | * Fill the input buffer. This is called only when the buffer is empty | ||
| 265 | * and at least one byte is really needed. | ||
| 266 | */ | ||
| 267 | int fill_inbuf(void) | ||
| 268 | { | ||
| 269 | if (insize != 0) | ||
| 270 | error("ran out of input data"); | ||
| 271 | |||
| 272 | inbuf = input_data; | ||
| 273 | insize = &input_data_end[0] - &input_data[0]; | ||
| 274 | |||
| 275 | inptr = 1; | ||
| 276 | return inbuf[0]; | ||
| 277 | } | ||
| 278 | 250 | ||
| 279 | /* =========================================================================== | 251 | #ifdef CONFIG_KERNEL_LZO |
| 280 | * Write the output window window[0..outcnt-1] and update crc and bytes_out. | 252 | #include "../../../../lib/decompress_unlzo.c" |
| 281 | * (Used for the decompressed data only.) | 253 | #endif |
| 282 | */ | ||
| 283 | void flush_window(void) | ||
| 284 | { | ||
| 285 | ulg c = crc; | ||
| 286 | unsigned n; | ||
| 287 | uch *in, *out, ch; | ||
| 288 | |||
| 289 | in = window; | ||
| 290 | out = &output_data[output_ptr]; | ||
| 291 | for (n = 0; n < outcnt; n++) { | ||
| 292 | ch = *out++ = *in++; | ||
| 293 | c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); | ||
| 294 | } | ||
| 295 | crc = c; | ||
| 296 | bytes_out += (ulg)outcnt; | ||
| 297 | output_ptr += (ulg)outcnt; | ||
| 298 | outcnt = 0; | ||
| 299 | putstr("."); | ||
| 300 | } | ||
| 301 | 254 | ||
| 302 | #ifndef arch_error | 255 | #ifndef arch_error |
| 303 | #define arch_error(x) | 256 | #define arch_error(x) |
| @@ -314,22 +267,33 @@ static void error(char *x) | |||
| 314 | while(1); /* Halt */ | 267 | while(1); /* Halt */ |
| 315 | } | 268 | } |
| 316 | 269 | ||
| 270 | asmlinkage void __div0(void) | ||
| 271 | { | ||
| 272 | error("Attempting division by 0!"); | ||
| 273 | } | ||
| 274 | |||
| 317 | #ifndef STANDALONE_DEBUG | 275 | #ifndef STANDALONE_DEBUG |
| 318 | 276 | ||
| 319 | ulg | 277 | unsigned long |
| 320 | decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p, | 278 | decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, |
| 321 | int arch_id) | 279 | unsigned long free_mem_ptr_end_p, |
| 280 | int arch_id) | ||
| 322 | { | 281 | { |
| 323 | output_data = (uch *)output_start; /* Points to kernel start */ | 282 | unsigned char *tmp; |
| 283 | |||
| 284 | output_data = (unsigned char *)output_start; | ||
| 324 | free_mem_ptr = free_mem_ptr_p; | 285 | free_mem_ptr = free_mem_ptr_p; |
| 325 | free_mem_end_ptr = free_mem_ptr_end_p; | 286 | free_mem_end_ptr = free_mem_ptr_end_p; |
| 326 | __machine_arch_type = arch_id; | 287 | __machine_arch_type = arch_id; |
| 327 | 288 | ||
| 328 | arch_decomp_setup(); | 289 | arch_decomp_setup(); |
| 329 | 290 | ||
| 330 | makecrc(); | 291 | tmp = (unsigned char *) (((unsigned long)input_data_end) - 4); |
| 292 | output_ptr = get_unaligned_le32(tmp); | ||
| 293 | |||
| 331 | putstr("Uncompressing Linux..."); | 294 | putstr("Uncompressing Linux..."); |
| 332 | gunzip(); | 295 | decompress(input_data, input_data_end - input_data, |
| 296 | NULL, NULL, output_data, NULL, error); | ||
| 333 | putstr(" done, booting the kernel.\n"); | 297 | putstr(" done, booting the kernel.\n"); |
| 334 | return output_ptr; | 298 | return output_ptr; |
| 335 | } | 299 | } |
| @@ -341,11 +305,10 @@ int main() | |||
| 341 | { | 305 | { |
| 342 | output_data = output_buffer; | 306 | output_data = output_buffer; |
| 343 | 307 | ||
| 344 | makecrc(); | ||
| 345 | putstr("Uncompressing Linux..."); | 308 | putstr("Uncompressing Linux..."); |
| 346 | gunzip(); | 309 | decompress(input_data, input_data_end - input_data, |
| 310 | NULL, NULL, output_data, NULL, error); | ||
| 347 | putstr("done.\n"); | 311 | putstr("done.\n"); |
| 348 | return 0; | 312 | return 0; |
| 349 | } | 313 | } |
| 350 | #endif | 314 | #endif |
| 351 | |||
