aboutsummaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
Diffstat (limited to 'init')
-rw-r--r--init/Kconfig60
-rw-r--r--init/do_mounts_rd.c174
-rw-r--r--init/initramfs.c101
3 files changed, 124 insertions, 211 deletions
diff --git a/init/Kconfig b/init/Kconfig
index a724a149bf3f..a3e3bf548046 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -101,6 +101,66 @@ config LOCALVERSION_AUTO
101 101
102 which is done within the script "scripts/setlocalversion".) 102 which is done within the script "scripts/setlocalversion".)
103 103
104config HAVE_KERNEL_GZIP
105 bool
106
107config HAVE_KERNEL_BZIP2
108 bool
109
110config HAVE_KERNEL_LZMA
111 bool
112
113choice
114 prompt "Kernel compression mode"
115 default KERNEL_GZIP
116 depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA
117 help
118 The linux kernel is a kind of self-extracting executable.
119 Several compression algorithms are available, which differ
120 in efficiency, compression and decompression speed.
121 Compression speed is only relevant when building a kernel.
122 Decompression speed is relevant at each boot.
123
124 If you have any problems with bzip2 or lzma compressed
125 kernels, mail me (Alain Knaff) <alain@knaff.lu>. (An older
126 version of this functionality (bzip2 only), for 2.4, was
127 supplied by Christian Ludwig)
128
129 High compression options are mostly useful for users, who
130 are low on disk space (embedded systems), but for whom ram
131 size matters less.
132
133 If in doubt, select 'gzip'
134
135config KERNEL_GZIP
136 bool "Gzip"
137 depends on HAVE_KERNEL_GZIP
138 help
139 The old and tried gzip compression. Its compression ratio is
140 the poorest among the 3 choices; however its speed (both
141 compression and decompression) is the fastest.
142
143config KERNEL_BZIP2
144 bool "Bzip2"
145 depends on HAVE_KERNEL_BZIP2
146 help
147 Its compression ratio and speed is intermediate.
148 Decompression speed is slowest among the three. The kernel
149 size is about 10% smaller with bzip2, in comparison to gzip.
150 Bzip2 uses a large amount of memory. For modern kernels you
151 will need at least 8MB RAM or more for booting.
152
153config KERNEL_LZMA
154 bool "LZMA"
155 depends on HAVE_KERNEL_LZMA
156 help
157 The most recent compression algorithm.
158 Its ratio is best, decompression speed is between the other
159 two. Compression is slowest. The kernel size is about 33%
160 smaller with LZMA in comparison to gzip.
161
162endchoice
163
104config SWAP 164config SWAP
105 bool "Support for paging of anonymous memory (swap)" 165 bool "Support for paging of anonymous memory (swap)"
106 depends on MMU && BLOCK 166 depends on MMU && BLOCK
diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c
index 0f0f0cf3ba9a..a015e267fd17 100644
--- a/init/do_mounts_rd.c
+++ b/init/do_mounts_rd.c
@@ -11,6 +11,9 @@
11#include "do_mounts.h" 11#include "do_mounts.h"
12#include "../fs/squashfs/squashfs_fs.h" 12#include "../fs/squashfs/squashfs_fs.h"
13 13
14#include <linux/decompress/generic.h>
15
16
14int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */ 17int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */
15 18
16static int __init prompt_ramdisk(char *str) 19static int __init prompt_ramdisk(char *str)
@@ -29,7 +32,7 @@ static int __init ramdisk_start_setup(char *str)
29} 32}
30__setup("ramdisk_start=", ramdisk_start_setup); 33__setup("ramdisk_start=", ramdisk_start_setup);
31 34
32static int __init crd_load(int in_fd, int out_fd); 35static int __init crd_load(int in_fd, int out_fd, decompress_fn deco);
33 36
34/* 37/*
35 * This routine tries to find a RAM disk image to load, and returns the 38 * This routine tries to find a RAM disk image to load, and returns the
@@ -38,15 +41,15 @@ static int __init crd_load(int in_fd, int out_fd);
38 * numbers could not be found. 41 * numbers could not be found.
39 * 42 *
40 * We currently check for the following magic numbers: 43 * We currently check for the following magic numbers:
41 * minix 44 * minix
42 * ext2 45 * ext2
43 * romfs 46 * romfs
44 * cramfs 47 * cramfs
45 * squashfs 48 * squashfs
46 * gzip 49 * gzip
47 */ 50 */
48static int __init 51static int __init
49identify_ramdisk_image(int fd, int start_block) 52identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor)
50{ 53{
51 const int size = 512; 54 const int size = 512;
52 struct minix_super_block *minixsb; 55 struct minix_super_block *minixsb;
@@ -56,6 +59,7 @@ identify_ramdisk_image(int fd, int start_block)
56 struct squashfs_super_block *squashfsb; 59 struct squashfs_super_block *squashfsb;
57 int nblocks = -1; 60 int nblocks = -1;
58 unsigned char *buf; 61 unsigned char *buf;
62 const char *compress_name;
59 63
60 buf = kmalloc(size, GFP_KERNEL); 64 buf = kmalloc(size, GFP_KERNEL);
61 if (!buf) 65 if (!buf)
@@ -69,18 +73,15 @@ identify_ramdisk_image(int fd, int start_block)
69 memset(buf, 0xe5, size); 73 memset(buf, 0xe5, size);
70 74
71 /* 75 /*
72 * Read block 0 to test for gzipped kernel 76 * Read block 0 to test for compressed kernel
73 */ 77 */
74 sys_lseek(fd, start_block * BLOCK_SIZE, 0); 78 sys_lseek(fd, start_block * BLOCK_SIZE, 0);
75 sys_read(fd, buf, size); 79 sys_read(fd, buf, size);
76 80
77 /* 81 *decompressor = decompress_method(buf, size, &compress_name);
78 * If it matches the gzip magic numbers, return 0 82 if (*decompressor) {
79 */ 83 printk(KERN_NOTICE "RAMDISK: %s image found at block %d\n",
80 if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) { 84 compress_name, start_block);
81 printk(KERN_NOTICE
82 "RAMDISK: Compressed image found at block %d\n",
83 start_block);
84 nblocks = 0; 85 nblocks = 0;
85 goto done; 86 goto done;
86 } 87 }
@@ -142,7 +143,7 @@ identify_ramdisk_image(int fd, int start_block)
142 printk(KERN_NOTICE 143 printk(KERN_NOTICE
143 "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n", 144 "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
144 start_block); 145 start_block);
145 146
146done: 147done:
147 sys_lseek(fd, start_block * BLOCK_SIZE, 0); 148 sys_lseek(fd, start_block * BLOCK_SIZE, 0);
148 kfree(buf); 149 kfree(buf);
@@ -157,6 +158,7 @@ int __init rd_load_image(char *from)
157 int nblocks, i, disk; 158 int nblocks, i, disk;
158 char *buf = NULL; 159 char *buf = NULL;
159 unsigned short rotate = 0; 160 unsigned short rotate = 0;
161 decompress_fn decompressor = NULL;
160#if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES) 162#if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES)
161 char rotator[4] = { '|' , '/' , '-' , '\\' }; 163 char rotator[4] = { '|' , '/' , '-' , '\\' };
162#endif 164#endif
@@ -169,12 +171,12 @@ int __init rd_load_image(char *from)
169 if (in_fd < 0) 171 if (in_fd < 0)
170 goto noclose_input; 172 goto noclose_input;
171 173
172 nblocks = identify_ramdisk_image(in_fd, rd_image_start); 174 nblocks = identify_ramdisk_image(in_fd, rd_image_start, &decompressor);
173 if (nblocks < 0) 175 if (nblocks < 0)
174 goto done; 176 goto done;
175 177
176 if (nblocks == 0) { 178 if (nblocks == 0) {
177 if (crd_load(in_fd, out_fd) == 0) 179 if (crd_load(in_fd, out_fd, decompressor) == 0)
178 goto successful_load; 180 goto successful_load;
179 goto done; 181 goto done;
180 } 182 }
@@ -200,7 +202,7 @@ int __init rd_load_image(char *from)
200 nblocks, rd_blocks); 202 nblocks, rd_blocks);
201 goto done; 203 goto done;
202 } 204 }
203 205
204 /* 206 /*
205 * OK, time to copy in the data 207 * OK, time to copy in the data
206 */ 208 */
@@ -273,138 +275,48 @@ int __init rd_load_disk(int n)
273 return rd_load_image("/dev/root"); 275 return rd_load_image("/dev/root");
274} 276}
275 277
276/*
277 * gzip declarations
278 */
279
280#define OF(args) args
281
282#ifndef memzero
283#define memzero(s, n) memset ((s), 0, (n))
284#endif
285
286typedef unsigned char uch;
287typedef unsigned short ush;
288typedef unsigned long ulg;
289
290#define INBUFSIZ 4096
291#define WSIZE 0x8000 /* window size--must be a power of two, and */
292 /* at least 32K for zip's deflate method */
293
294static uch *inbuf;
295static uch *window;
296
297static unsigned insize; /* valid bytes in inbuf */
298static unsigned inptr; /* index of next byte to be processed in inbuf */
299static unsigned outcnt; /* bytes in output buffer */
300static int exit_code; 278static int exit_code;
301static int unzip_error; 279static int decompress_error;
302static long bytes_out;
303static int crd_infd, crd_outfd; 280static int crd_infd, crd_outfd;
304 281
305#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) 282static int __init compr_fill(void *buf, unsigned int len)
306
307/* Diagnostic functions (stubbed out) */
308#define Assert(cond,msg)
309#define Trace(x)
310#define Tracev(x)
311#define Tracevv(x)
312#define Tracec(c,x)
313#define Tracecv(c,x)
314
315#define STATIC static
316#define INIT __init
317
318static int __init fill_inbuf(void);
319static void __init flush_window(void);
320static void __init error(char *m);
321
322#define NO_INFLATE_MALLOC
323
324#include "../lib/inflate.c"
325
326/* ===========================================================================
327 * Fill the input buffer. This is called only when the buffer is empty
328 * and at least one byte is really needed.
329 * Returning -1 does not guarantee that gunzip() will ever return.
330 */
331static int __init fill_inbuf(void)
332{ 283{
333 if (exit_code) return -1; 284 int r = sys_read(crd_infd, buf, len);
334 285 if (r < 0)
335 insize = sys_read(crd_infd, inbuf, INBUFSIZ); 286 printk(KERN_ERR "RAMDISK: error while reading compressed data");
336 if (insize == 0) { 287 else if (r == 0)
337 error("RAMDISK: ran out of compressed data"); 288 printk(KERN_ERR "RAMDISK: EOF while reading compressed data");
338 return -1; 289 return r;
339 }
340
341 inptr = 1;
342
343 return inbuf[0];
344} 290}
345 291
346/* =========================================================================== 292static int __init compr_flush(void *window, unsigned int outcnt)
347 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
348 * (Used for the decompressed data only.)
349 */
350static void __init flush_window(void)
351{ 293{
352 ulg c = crc; /* temporary variable */ 294 int written = sys_write(crd_outfd, window, outcnt);
353 unsigned n, written; 295 if (written != outcnt) {
354 uch *in, ch; 296 if (decompress_error == 0)
355 297 printk(KERN_ERR
356 written = sys_write(crd_outfd, window, outcnt); 298 "RAMDISK: incomplete write (%d != %d)\n",
357 if (written != outcnt && unzip_error == 0) { 299 written, outcnt);
358 printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n", 300 decompress_error = 1;
359 written, outcnt, bytes_out); 301 return -1;
360 unzip_error = 1; 302 }
361 } 303 return outcnt;
362 in = window;
363 for (n = 0; n < outcnt; n++) {
364 ch = *in++;
365 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
366 }
367 crc = c;
368 bytes_out += (ulg)outcnt;
369 outcnt = 0;
370} 304}
371 305
372static void __init error(char *x) 306static void __init error(char *x)
373{ 307{
374 printk(KERN_ERR "%s\n", x); 308 printk(KERN_ERR "%s\n", x);
375 exit_code = 1; 309 exit_code = 1;
376 unzip_error = 1; 310 decompress_error = 1;
377} 311}
378 312
379static int __init crd_load(int in_fd, int out_fd) 313static int __init crd_load(int in_fd, int out_fd, decompress_fn deco)
380{ 314{
381 int result; 315 int result;
382
383 insize = 0; /* valid bytes in inbuf */
384 inptr = 0; /* index of next byte to be processed in inbuf */
385 outcnt = 0; /* bytes in output buffer */
386 exit_code = 0;
387 bytes_out = 0;
388 crc = (ulg)0xffffffffL; /* shift register contents */
389
390 crd_infd = in_fd; 316 crd_infd = in_fd;
391 crd_outfd = out_fd; 317 crd_outfd = out_fd;
392 inbuf = kmalloc(INBUFSIZ, GFP_KERNEL); 318 result = deco(NULL, 0, compr_fill, compr_flush, NULL, NULL, error);
393 if (!inbuf) { 319 if (decompress_error)
394 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
395 return -1;
396 }
397 window = kmalloc(WSIZE, GFP_KERNEL);
398 if (!window) {
399 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
400 kfree(inbuf);
401 return -1;
402 }
403 makecrc();
404 result = gunzip();
405 if (unzip_error)
406 result = 1; 320 result = 1;
407 kfree(inbuf);
408 kfree(window);
409 return result; 321 return result;
410} 322}
diff --git a/init/initramfs.c b/init/initramfs.c
index d9c941c0c3ca..f8241e832aa3 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -390,11 +390,14 @@ static int __init write_buffer(char *buf, unsigned len)
390 return len - count; 390 return len - count;
391} 391}
392 392
393static void __init flush_buffer(char *buf, unsigned len) 393#if defined CONFIG_RD_GZIP || defined CONFIG_RD_BZIP2 || defined CONFIG_RD_LZMA
394static int __init flush_buffer(void *bufv, unsigned len)
394{ 395{
396 char *buf = (char *) bufv;
395 int written; 397 int written;
398 int origLen = len;
396 if (message) 399 if (message)
397 return; 400 return -1;
398 while ((written = write_buffer(buf, len)) < len && !message) { 401 while ((written = write_buffer(buf, len)) < len && !message) {
399 char c = buf[written]; 402 char c = buf[written];
400 if (c == '0') { 403 if (c == '0') {
@@ -408,84 +411,27 @@ static void __init flush_buffer(char *buf, unsigned len)
408 } else 411 } else
409 error("junk in compressed archive"); 412 error("junk in compressed archive");
410 } 413 }
414 return origLen;
411} 415}
412
413/*
414 * gzip declarations
415 */
416
417#define OF(args) args
418
419#ifndef memzero
420#define memzero(s, n) memset ((s), 0, (n))
421#endif 416#endif
422 417
423typedef unsigned char uch; 418static unsigned my_inptr; /* index of next byte to be processed in inbuf */
424typedef unsigned short ush;
425typedef unsigned long ulg;
426
427#define WSIZE 0x8000 /* window size--must be a power of two, and */
428 /* at least 32K for zip's deflate method */
429
430static uch *inbuf;
431static uch *window;
432
433static unsigned insize; /* valid bytes in inbuf */
434static unsigned inptr; /* index of next byte to be processed in inbuf */
435static unsigned outcnt; /* bytes in output buffer */
436static long bytes_out;
437
438#define get_byte() (inptr < insize ? inbuf[inptr++] : -1)
439
440/* Diagnostic functions (stubbed out) */
441#define Assert(cond,msg)
442#define Trace(x)
443#define Tracev(x)
444#define Tracevv(x)
445#define Tracec(c,x)
446#define Tracecv(c,x)
447
448#define STATIC static
449#define INIT __init
450
451static void __init flush_window(void);
452static void __init error(char *m);
453 419
454#define NO_INFLATE_MALLOC 420#include <linux/decompress/generic.h>
455
456#include "../lib/inflate.c"
457
458/* ===========================================================================
459 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
460 * (Used for the decompressed data only.)
461 */
462static void __init flush_window(void)
463{
464 ulg c = crc; /* temporary variable */
465 unsigned n;
466 uch *in, ch;
467
468 flush_buffer(window, outcnt);
469 in = window;
470 for (n = 0; n < outcnt; n++) {
471 ch = *in++;
472 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
473 }
474 crc = c;
475 bytes_out += (ulg)outcnt;
476 outcnt = 0;
477}
478 421
479static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) 422static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
480{ 423{
481 int written; 424 int written;
425 decompress_fn decompress;
426
482 dry_run = check_only; 427 dry_run = check_only;
483 header_buf = kmalloc(110, GFP_KERNEL); 428 header_buf = kmalloc(110, GFP_KERNEL);
484 symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL); 429 symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
485 name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL); 430 name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL);
486 window = kmalloc(WSIZE, GFP_KERNEL); 431
487 if (!window || !header_buf || !symlink_buf || !name_buf) 432 if (!header_buf || !symlink_buf || !name_buf)
488 panic("can't allocate buffers"); 433 panic("can't allocate buffers");
434
489 state = Start; 435 state = Start;
490 this_header = 0; 436 this_header = 0;
491 message = NULL; 437 message = NULL;
@@ -505,22 +451,17 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
505 continue; 451 continue;
506 } 452 }
507 this_header = 0; 453 this_header = 0;
508 insize = len; 454 decompress = decompress_method(buf, len, NULL);
509 inbuf = buf; 455 if (decompress)
510 inptr = 0; 456 decompress(buf, len, NULL, flush_buffer, NULL,
511 outcnt = 0; /* bytes in output buffer */ 457 &my_inptr, error);
512 bytes_out = 0;
513 crc = (ulg)0xffffffffL; /* shift register contents */
514 makecrc();
515 gunzip();
516 if (state != Reset) 458 if (state != Reset)
517 error("junk in gzipped archive"); 459 error("junk in compressed archive");
518 this_header = saved_offset + inptr; 460 this_header = saved_offset + my_inptr;
519 buf += inptr; 461 buf += my_inptr;
520 len -= inptr; 462 len -= my_inptr;
521 } 463 }
522 dir_utime(); 464 dir_utime();
523 kfree(window);
524 kfree(name_buf); 465 kfree(name_buf);
525 kfree(symlink_buf); 466 kfree(symlink_buf);
526 kfree(header_buf); 467 kfree(header_buf);