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.c178
-rw-r--r--init/initramfs.c122
3 files changed, 144 insertions, 216 deletions
diff --git a/init/Kconfig b/init/Kconfig
index f068071fcc5d..95a66131403a 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..027a402708de 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,19 @@ 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 (compress_name) {
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 85 if (!*decompressor)
82 "RAMDISK: Compressed image found at block %d\n", 86 printk(KERN_EMERG
83 start_block); 87 "RAMDISK: %s decompressor not configured!\n",
88 compress_name);
84 nblocks = 0; 89 nblocks = 0;
85 goto done; 90 goto done;
86 } 91 }
@@ -142,7 +147,7 @@ identify_ramdisk_image(int fd, int start_block)
142 printk(KERN_NOTICE 147 printk(KERN_NOTICE
143 "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n", 148 "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
144 start_block); 149 start_block);
145 150
146done: 151done:
147 sys_lseek(fd, start_block * BLOCK_SIZE, 0); 152 sys_lseek(fd, start_block * BLOCK_SIZE, 0);
148 kfree(buf); 153 kfree(buf);
@@ -157,6 +162,7 @@ int __init rd_load_image(char *from)
157 int nblocks, i, disk; 162 int nblocks, i, disk;
158 char *buf = NULL; 163 char *buf = NULL;
159 unsigned short rotate = 0; 164 unsigned short rotate = 0;
165 decompress_fn decompressor = NULL;
160#if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES) 166#if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES)
161 char rotator[4] = { '|' , '/' , '-' , '\\' }; 167 char rotator[4] = { '|' , '/' , '-' , '\\' };
162#endif 168#endif
@@ -169,12 +175,12 @@ int __init rd_load_image(char *from)
169 if (in_fd < 0) 175 if (in_fd < 0)
170 goto noclose_input; 176 goto noclose_input;
171 177
172 nblocks = identify_ramdisk_image(in_fd, rd_image_start); 178 nblocks = identify_ramdisk_image(in_fd, rd_image_start, &decompressor);
173 if (nblocks < 0) 179 if (nblocks < 0)
174 goto done; 180 goto done;
175 181
176 if (nblocks == 0) { 182 if (nblocks == 0) {
177 if (crd_load(in_fd, out_fd) == 0) 183 if (crd_load(in_fd, out_fd, decompressor) == 0)
178 goto successful_load; 184 goto successful_load;
179 goto done; 185 goto done;
180 } 186 }
@@ -200,7 +206,7 @@ int __init rd_load_image(char *from)
200 nblocks, rd_blocks); 206 nblocks, rd_blocks);
201 goto done; 207 goto done;
202 } 208 }
203 209
204 /* 210 /*
205 * OK, time to copy in the data 211 * OK, time to copy in the data
206 */ 212 */
@@ -273,138 +279,48 @@ int __init rd_load_disk(int n)
273 return rd_load_image("/dev/root"); 279 return rd_load_image("/dev/root");
274} 280}
275 281
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; 282static int exit_code;
301static int unzip_error; 283static int decompress_error;
302static long bytes_out;
303static int crd_infd, crd_outfd; 284static int crd_infd, crd_outfd;
304 285
305#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) 286static 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{ 287{
333 if (exit_code) return -1; 288 int r = sys_read(crd_infd, buf, len);
334 289 if (r < 0)
335 insize = sys_read(crd_infd, inbuf, INBUFSIZ); 290 printk(KERN_ERR "RAMDISK: error while reading compressed data");
336 if (insize == 0) { 291 else if (r == 0)
337 error("RAMDISK: ran out of compressed data"); 292 printk(KERN_ERR "RAMDISK: EOF while reading compressed data");
338 return -1; 293 return r;
339 }
340
341 inptr = 1;
342
343 return inbuf[0];
344} 294}
345 295
346/* =========================================================================== 296static 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{ 297{
352 ulg c = crc; /* temporary variable */ 298 int written = sys_write(crd_outfd, window, outcnt);
353 unsigned n, written; 299 if (written != outcnt) {
354 uch *in, ch; 300 if (decompress_error == 0)
355 301 printk(KERN_ERR
356 written = sys_write(crd_outfd, window, outcnt); 302 "RAMDISK: incomplete write (%d != %d)\n",
357 if (written != outcnt && unzip_error == 0) { 303 written, outcnt);
358 printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n", 304 decompress_error = 1;
359 written, outcnt, bytes_out); 305 return -1;
360 unzip_error = 1; 306 }
361 } 307 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} 308}
371 309
372static void __init error(char *x) 310static void __init error(char *x)
373{ 311{
374 printk(KERN_ERR "%s\n", x); 312 printk(KERN_ERR "%s\n", x);
375 exit_code = 1; 313 exit_code = 1;
376 unzip_error = 1; 314 decompress_error = 1;
377} 315}
378 316
379static int __init crd_load(int in_fd, int out_fd) 317static int __init crd_load(int in_fd, int out_fd, decompress_fn deco)
380{ 318{
381 int result; 319 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; 320 crd_infd = in_fd;
391 crd_outfd = out_fd; 321 crd_outfd = out_fd;
392 inbuf = kmalloc(INBUFSIZ, GFP_KERNEL); 322 result = deco(NULL, 0, compr_fill, compr_flush, NULL, NULL, error);
393 if (!inbuf) { 323 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; 324 result = 1;
407 kfree(inbuf);
408 kfree(window);
409 return result; 325 return result;
410} 326}
diff --git a/init/initramfs.c b/init/initramfs.c
index d9c941c0c3ca..7dcde7ea6603 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -390,11 +390,13 @@ 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) 393static int __init flush_buffer(void *bufv, unsigned len)
394{ 394{
395 char *buf = (char *) bufv;
395 int written; 396 int written;
397 int origLen = len;
396 if (message) 398 if (message)
397 return; 399 return -1;
398 while ((written = write_buffer(buf, len)) < len && !message) { 400 while ((written = write_buffer(buf, len)) < len && !message) {
399 char c = buf[written]; 401 char c = buf[written];
400 if (c == '0') { 402 if (c == '0') {
@@ -408,84 +410,28 @@ static void __init flush_buffer(char *buf, unsigned len)
408 } else 410 } else
409 error("junk in compressed archive"); 411 error("junk in compressed archive");
410 } 412 }
413 return origLen;
411} 414}
412 415
413/* 416static unsigned my_inptr; /* index of next byte to be processed in inbuf */
414 * gzip declarations
415 */
416 417
417#define OF(args) args 418#include <linux/decompress/generic.h>
418
419#ifndef memzero
420#define memzero(s, n) memset ((s), 0, (n))
421#endif
422
423typedef unsigned char uch;
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
454#define NO_INFLATE_MALLOC
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 419
479static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) 420static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
480{ 421{
481 int written; 422 int written;
423 decompress_fn decompress;
424 const char *compress_name;
425 static __initdata char msg_buf[64];
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,25 @@ 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, &compress_name);
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; 458 else if (compress_name) {
513 crc = (ulg)0xffffffffL; /* shift register contents */ 459 if (!message) {
514 makecrc(); 460 snprintf(msg_buf, sizeof msg_buf,
515 gunzip(); 461 "compression method %s not configured",
462 compress_name);
463 message = msg_buf;
464 }
465 }
516 if (state != Reset) 466 if (state != Reset)
517 error("junk in gzipped archive"); 467 error("junk in compressed archive");
518 this_header = saved_offset + inptr; 468 this_header = saved_offset + my_inptr;
519 buf += inptr; 469 buf += my_inptr;
520 len -= inptr; 470 len -= my_inptr;
521 } 471 }
522 dir_utime(); 472 dir_utime();
523 kfree(window);
524 kfree(name_buf); 473 kfree(name_buf);
525 kfree(symlink_buf); 474 kfree(symlink_buf);
526 kfree(header_buf); 475 kfree(header_buf);
@@ -579,7 +528,7 @@ static int __init populate_rootfs(void)
579 char *err = unpack_to_rootfs(__initramfs_start, 528 char *err = unpack_to_rootfs(__initramfs_start,
580 __initramfs_end - __initramfs_start, 0); 529 __initramfs_end - __initramfs_start, 0);
581 if (err) 530 if (err)
582 panic(err); 531 panic(err); /* Failed to decompress INTERNAL initramfs */
583 if (initrd_start) { 532 if (initrd_start) {
584#ifdef CONFIG_BLK_DEV_RAM 533#ifdef CONFIG_BLK_DEV_RAM
585 int fd; 534 int fd;
@@ -605,9 +554,12 @@ static int __init populate_rootfs(void)
605 printk(KERN_INFO "Unpacking initramfs..."); 554 printk(KERN_INFO "Unpacking initramfs...");
606 err = unpack_to_rootfs((char *)initrd_start, 555 err = unpack_to_rootfs((char *)initrd_start,
607 initrd_end - initrd_start, 0); 556 initrd_end - initrd_start, 0);
608 if (err) 557 if (err) {
609 panic(err); 558 printk(" failed!\n");
610 printk(" done\n"); 559 printk(KERN_EMERG "%s\n", err);
560 } else {
561 printk(" done\n");
562 }
611 free_initrd(); 563 free_initrd();
612#endif 564#endif
613 } 565 }