3 Please pull the latest bzip2-lzma-for-linus git tree from:
5 git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git bzip2-lzma-for-linus
7 We are sending this as a separate tree as it affects generic
12 - Add kernel image compression mode config options:
14 Kernel compression mode
15 > 1. Gzip (KERNEL_GZIP) (NEW)
16 2. Bzip2 (KERNEL_BZIP2) (NEW)
17 3. LZMA (KERNEL_LZMA) (NEW)
19 Initial ramdisk compressed using gzip (RD_GZIP) [Y/n/?] (NEW)
20 Initial ramdisk compressed using bzip2 (RD_BZIP2) [N/y/?] (NEW)
21 Initial ramdisk compressed using lzma (RD_LZMA) [N/y/?] (NEW)
23 Built-in initramfs compression mode
24 > 1. None (INITRAMFS_COMPRESSION_NONE) (NEW)
25 2. Gzip (INITRAMFS_COMPRESSION_GZIP) (NEW)
28 ... and matching compression and decompression implementations.
32 - This has been a historically problematic topic thus we skipped
33 the v2.6.28 and v2.6.29 merge windows with it. Boot failures,
34 panics, initrd decompression problems have been observed and
37 - On x86 we switch over from lib/inflate.c to zlib - same
38 functionality but different library. Other architectures are not
39 affected by that, use of this new facility is opt-in. (This was
40 the last in-kernel user of lib/inflate.c on x86.)
42 - To build a kernel with a different compressor the 'bzip2' or 'lzma'
43 tools are needed. If the kernel is built with CONFIG_KERNEL_LZMA=y
44 and the tool is not available the kernel build will fail with a clear
45 message. This tool is available in all major kernel distros, but
46 it is not generally a default-installed package. bzip2 is generally
49 - There are no known regressions.
57 bzip2/lzma: library support for gzip, bzip2 and lzma decompression
58 bzip2/lzma: config and initramfs support for bzip2/lzma decompression
59 bzip2/lzma: x86 kernel compression support
60 bzip2/lzma: fix built-in initramfs vs CONFIG_RD_GZIP
61 bzip2/lzma: fix decompress_inflate.c vs multi-block-with-embedded-filename
62 bzip2/lzma: don't stop search at first unconfigured compression
63 bzip2/lzma: don't leave empty files around on failure
64 bzip2/lzma: make internal initramfs compression configurable
67 x86: headers cleanup - boot.h
70 bzip2/lzma: use a table to search for initramfs compression formats
71 bzip2/lzma: handle failures from bzip2 and lzma correctly
72 bzip2/lzma: make config machinery an arch configurable
73 bzip2/lzma: proper Kconfig dependencies for the ramdisk options
74 bzip2/lzma: DECOMPRESS_GZIP should select ZLIB_INFLATE
75 bzip2/lzma: move initrd/ramfs options out of BLK_DEV
76 bzip2/lzma: fix constant in decompress_inflate
77 bzip2/lzma: centralize format detection
78 bzip2/lzma: comprehensible error messages for missing decompressor
79 init: make initrd/initramfs decompression failure a KERN_EMERG event
80 bzip2/lzma: update boot protocol specification
83 bzip2/lzma: make flush_buffer() unconditional
86 Documentation/x86/boot.txt | 5 +-
87 arch/x86/Kconfig | 3 +
88 arch/x86/boot/compressed/Makefile | 21 +-
89 arch/x86/boot/compressed/misc.c | 118 +-----
90 arch/x86/include/asm/boot.h | 16 +-
91 include/linux/decompress/bunzip2.h | 10 +
92 include/linux/decompress/generic.h | 33 ++
93 include/linux/decompress/inflate.h | 13 +
94 include/linux/decompress/mm.h | 87 +++++
95 include/linux/decompress/unlzma.h | 12 +
97 init/do_mounts_rd.c | 178 +++-------
98 init/initramfs.c | 122 ++-----
101 lib/decompress.c | 54 +++
102 lib/decompress_bunzip2.c | 735 ++++++++++++++++++++++++++++++++++++
103 lib/decompress_inflate.c | 167 ++++++++
104 lib/decompress_unlzma.c | 647 +++++++++++++++++++++++++++++++
105 lib/zlib_inflate/inflate.h | 4 +
106 lib/zlib_inflate/inftrees.h | 4 +
107 scripts/Makefile.lib | 14 +
108 scripts/bin_size | 10 +
109 scripts/gen_initramfs_list.sh | 18 +-
110 usr/Kconfig | 89 +++++
111 usr/Makefile | 36 ++-
112 usr/initramfs_data.S | 2 +-
113 usr/initramfs_data.bz2.S | 29 ++
114 usr/initramfs_data.gz.S | 29 ++
115 usr/initramfs_data.lzma.S | 29 ++
116 30 files changed, 2222 insertions(+), 344 deletions(-)
117 create mode 100644 include/linux/decompress/bunzip2.h
118 create mode 100644 include/linux/decompress/generic.h
119 create mode 100644 include/linux/decompress/inflate.h
120 create mode 100644 include/linux/decompress/mm.h
121 create mode 100644 include/linux/decompress/unlzma.h
122 create mode 100644 lib/decompress.c
123 create mode 100644 lib/decompress_bunzip2.c
124 create mode 100644 lib/decompress_inflate.c
125 create mode 100644 lib/decompress_unlzma.c
126 create mode 100644 scripts/bin_size
127 create mode 100644 usr/initramfs_data.bz2.S
128 create mode 100644 usr/initramfs_data.gz.S
129 create mode 100644 usr/initramfs_data.lzma.S
131 diff --git a/Documentation/x86/boot.txt b/Documentation/x86/boot.txt
132 index 7b4596a..d05730e 100644
133 --- a/Documentation/x86/boot.txt
134 +++ b/Documentation/x86/boot.txt
135 @@ -542,7 +542,10 @@ Protocol: 2.08+
137 The payload may be compressed. The format of both the compressed and
138 uncompressed data should be determined using the standard magic
139 - numbers. Currently only gzip compressed ELF is used.
140 + numbers. The currently supported compression formats are gzip
141 + (magic numbers 1F 8B or 1F 9E), bzip2 (magic number 42 5A) and LZMA
142 + (magic number 5D 00). The uncompressed payload is currently always ELF
143 + (magic number 7F 45 4C 46).
145 Field name: payload_length
147 diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
148 index bc2fbad..a233768 100644
149 --- a/arch/x86/Kconfig
150 +++ b/arch/x86/Kconfig
151 @@ -40,6 +40,9 @@ config X86
152 select HAVE_GENERIC_DMA_COHERENT if X86_32
153 select HAVE_EFFICIENT_UNALIGNED_ACCESS
154 select USER_STACKTRACE_SUPPORT
155 + select HAVE_KERNEL_GZIP
156 + select HAVE_KERNEL_BZIP2
157 + select HAVE_KERNEL_LZMA
159 config ARCH_DEFCONFIG
161 diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
162 index 1771c80..3ca4c19 100644
163 --- a/arch/x86/boot/compressed/Makefile
164 +++ b/arch/x86/boot/compressed/Makefile
166 # create a compressed vmlinux image from the original vmlinux
169 -targets := vmlinux vmlinux.bin vmlinux.bin.gz head_$(BITS).o misc.o piggy.o
170 +targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma head_$(BITS).o misc.o piggy.o
172 KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
173 KBUILD_CFLAGS += -fno-strict-aliasing -fPIC
174 @@ -47,18 +47,35 @@ ifeq ($(CONFIG_X86_32),y)
175 ifdef CONFIG_RELOCATABLE
176 $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin.all FORCE
177 $(call if_changed,gzip)
178 +$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin.all FORCE
179 + $(call if_changed,bzip2)
180 +$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin.all FORCE
181 + $(call if_changed,lzma)
183 $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
184 $(call if_changed,gzip)
185 +$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
186 + $(call if_changed,bzip2)
187 +$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
188 + $(call if_changed,lzma)
190 LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T
194 $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
195 $(call if_changed,gzip)
196 +$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
197 + $(call if_changed,bzip2)
198 +$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
199 + $(call if_changed,lzma)
201 LDFLAGS_piggy.o := -r --format binary --oformat elf64-x86-64 -T
204 -$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
205 +suffix_$(CONFIG_KERNEL_GZIP) = gz
206 +suffix_$(CONFIG_KERNEL_BZIP2) = bz2
207 +suffix_$(CONFIG_KERNEL_LZMA) = lzma
209 +$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix_y) FORCE
210 $(call if_changed,ld)
211 diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
212 index da06221..e45be73 100644
213 --- a/arch/x86/boot/compressed/misc.c
214 +++ b/arch/x86/boot/compressed/misc.c
215 @@ -116,71 +116,13 @@
220 -#define OF(args) args
221 #define STATIC static
225 #define memzero(s, n) memset((s), 0, (n))
227 -typedef unsigned char uch;
228 -typedef unsigned short ush;
229 -typedef unsigned long ulg;
232 - * Window size must be at least 32k, and a power of two.
233 - * We don't actually have a window just a huge output buffer,
234 - * so we report a 2G window size, as that should always be
235 - * larger than our output buffer:
237 -#define WSIZE 0x80000000
240 -static unsigned char *inbuf;
242 -/* Sliding window buffer (and final output buffer): */
243 -static unsigned char *window;
245 -/* Valid bytes in inbuf: */
246 -static unsigned insize;
248 -/* Index of next byte to be processed in inbuf: */
249 -static unsigned inptr;
251 -/* Bytes in output buffer: */
252 -static unsigned outcnt;
254 -/* gzip flag byte */
255 -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */
256 -#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gz file */
257 -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
258 -#define ORIG_NAM 0x08 /* bit 3 set: original file name present */
259 -#define COMMENT 0x10 /* bit 4 set: file comment present */
260 -#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
261 -#define RESERVED 0xC0 /* bit 6, 7: reserved */
263 -#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
265 -/* Diagnostic functions */
267 -# define Assert(cond, msg) do { if (!(cond)) error(msg); } while (0)
268 -# define Trace(x) do { fprintf x; } while (0)
269 -# define Tracev(x) do { if (verbose) fprintf x ; } while (0)
270 -# define Tracevv(x) do { if (verbose > 1) fprintf x ; } while (0)
271 -# define Tracec(c, x) do { if (verbose && (c)) fprintf x ; } while (0)
272 -# define Tracecv(c, x) do { if (verbose > 1 && (c)) fprintf x ; } while (0)
274 -# define Assert(cond, msg)
278 -# define Tracec(c, x)
279 -# define Tracecv(c, x)
282 -static int fill_inbuf(void);
283 -static void flush_window(void);
284 static void error(char *m);
287 @@ -189,13 +131,8 @@ static void error(char *m);
288 static struct boot_params *real_mode; /* Pointer to real-mode data */
291 -extern unsigned char input_data[];
292 -extern int input_len;
294 -static long bytes_out;
296 static void *memset(void *s, int c, unsigned n);
297 -static void *memcpy(void *dest, const void *src, unsigned n);
298 +void *memcpy(void *dest, const void *src, unsigned n);
300 static void __putstr(int, const char *);
301 #define putstr(__x) __putstr(0, __x)
302 @@ -213,7 +150,17 @@ static char *vidmem;
304 static int lines, cols;
306 -#include "../../../../lib/inflate.c"
307 +#ifdef CONFIG_KERNEL_GZIP
308 +#include "../../../../lib/decompress_inflate.c"
311 +#ifdef CONFIG_KERNEL_BZIP2
312 +#include "../../../../lib/decompress_bunzip2.c"
315 +#ifdef CONFIG_KERNEL_LZMA
316 +#include "../../../../lib/decompress_unlzma.c"
319 static void scroll(void)
321 @@ -282,7 +229,7 @@ static void *memset(void *s, int c, unsigned n)
325 -static void *memcpy(void *dest, const void *src, unsigned n)
326 +void *memcpy(void *dest, const void *src, unsigned n)
330 @@ -293,38 +240,6 @@ static void *memcpy(void *dest, const void *src, unsigned n)
334 -/* ===========================================================================
335 - * Fill the input buffer. This is called only when the buffer is empty
336 - * and at least one byte is really needed.
338 -static int fill_inbuf(void)
340 - error("ran out of input data");
344 -/* ===========================================================================
345 - * Write the output window window[0..outcnt-1] and update crc and bytes_out.
346 - * (Used for the decompressed data only.)
348 -static void flush_window(void)
350 - /* With my window equal to my output buffer
351 - * I only need to compute the crc here.
353 - unsigned long c = crc; /* temporary variable */
355 - unsigned char *in, ch;
358 - for (n = 0; n < outcnt; n++) {
360 - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
363 - bytes_out += (unsigned long)outcnt;
367 static void error(char *x)
369 @@ -407,12 +322,8 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,
370 lines = real_mode->screen_info.orig_video_lines;
371 cols = real_mode->screen_info.orig_video_cols;
373 - window = output; /* Output buffer (Normally at 1M) */
374 free_mem_ptr = heap; /* Heap */
375 free_mem_end_ptr = heap + BOOT_HEAP_SIZE;
376 - inbuf = input_data; /* Input buffer */
377 - insize = input_len;
381 if ((unsigned long)output & (__KERNEL_ALIGN - 1))
382 @@ -430,10 +341,9 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,
388 putstr("\nDecompressing Linux... ");
390 + decompress(input_data, input_len, NULL, NULL, output, NULL, error);
393 putstr("done.\nBooting the kernel.\n");
394 diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h
395 index dd61616..6526cf0 100644
396 --- a/arch/x86/include/asm/boot.h
397 +++ b/arch/x86/include/asm/boot.h
399 #define EXTENDED_VGA 0xfffe /* 80x50 mode */
400 #define ASK_VGA 0xfffd /* ask for it at bootup */
404 /* Physical address where kernel should be loaded. */
405 #define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
406 + (CONFIG_PHYSICAL_ALIGN - 1)) \
407 & ~(CONFIG_PHYSICAL_ALIGN - 1))
409 +#ifdef CONFIG_KERNEL_BZIP2
410 +#define BOOT_HEAP_SIZE 0x400000
411 +#else /* !CONFIG_KERNEL_BZIP2 */
414 #define BOOT_HEAP_SIZE 0x7000
415 -#define BOOT_STACK_SIZE 0x4000
417 #define BOOT_HEAP_SIZE 0x4000
420 +#endif /* !CONFIG_KERNEL_BZIP2 */
422 +#ifdef CONFIG_X86_64
423 +#define BOOT_STACK_SIZE 0x4000
425 #define BOOT_STACK_SIZE 0x1000
428 +#endif /* __KERNEL__ */
430 #endif /* _ASM_X86_BOOT_H */
431 diff --git a/include/linux/decompress/bunzip2.h b/include/linux/decompress/bunzip2.h
433 index 0000000..1152721
435 +++ b/include/linux/decompress/bunzip2.h
437 +#ifndef DECOMPRESS_BUNZIP2_H
438 +#define DECOMPRESS_BUNZIP2_H
440 +int bunzip2(unsigned char *inbuf, int len,
441 + int(*fill)(void*, unsigned int),
442 + int(*flush)(void*, unsigned int),
443 + unsigned char *output,
445 + void(*error)(char *x));
447 diff --git a/include/linux/decompress/generic.h b/include/linux/decompress/generic.h
449 index 0000000..6dfb856
451 +++ b/include/linux/decompress/generic.h
453 +#ifndef DECOMPRESS_GENERIC_H
454 +#define DECOMPRESS_GENERIC_H
456 +/* Minimal chunksize to be read.
457 + *Bzip2 prefers at least 4096
458 + *Lzma prefers 0x10000 */
459 +#define COMPR_IOBUF_SIZE 4096
461 +typedef int (*decompress_fn) (unsigned char *inbuf, int len,
462 + int(*fill)(void*, unsigned int),
463 + int(*writebb)(void*, unsigned int),
464 + unsigned char *output,
466 + void(*error)(char *x));
468 +/* inbuf - input buffer
469 + *len - len of pre-read data in inbuf
470 + *fill - function to fill inbuf if empty
471 + *writebb - function to write out outbug
472 + *posp - if non-null, input position (number of bytes read) will be
475 + *If len != 0, the inbuf is initialized (with as much data), and fill
476 + *should not be called
477 + *If len = 0, the inbuf is allocated, but empty. Its size is IOBUF_SIZE
478 + *fill should be called (repeatedly...) to read data, at most IOBUF_SIZE
481 +/* Utility routine to detect the decompression method */
482 +decompress_fn decompress_method(const unsigned char *inbuf, int len,
483 + const char **name);
486 diff --git a/include/linux/decompress/inflate.h b/include/linux/decompress/inflate.h
488 index 0000000..f9b06cc
490 +++ b/include/linux/decompress/inflate.h
495 +/* Other housekeeping constants */
496 +#define INBUFSIZ 4096
498 +int gunzip(unsigned char *inbuf, int len,
499 + int(*fill)(void*, unsigned int),
500 + int(*flush)(void*, unsigned int),
501 + unsigned char *output,
503 + void(*error_fn)(char *x));
505 diff --git a/include/linux/decompress/mm.h b/include/linux/decompress/mm.h
507 index 0000000..12ff8c3
509 +++ b/include/linux/decompress/mm.h
514 + * Memory management for pre-boot and ramdisk uncompressors
516 + * Authors: Alain Knaff <alain@knaff.lu>
520 +#ifndef DECOMPR_MM_H
521 +#define DECOMPR_MM_H
525 +/* Code active when included from pre-boot environment: */
527 +/* A trivial malloc implementation, adapted from
528 + * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
530 +static unsigned long malloc_ptr;
531 +static int malloc_count;
533 +static void *malloc(int size)
538 + error("Malloc error");
540 + malloc_ptr = free_mem_ptr;
542 + malloc_ptr = (malloc_ptr + 3) & ~3; /* Align */
544 + p = (void *)malloc_ptr;
545 + malloc_ptr += size;
547 + if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr)
548 + error("Out of memory");
554 +static void free(void *where)
558 + malloc_ptr = free_mem_ptr;
561 +#define large_malloc(a) malloc(a)
562 +#define large_free(a) free(a)
564 +#define set_error_fn(x)
570 +/* Code active when compiled standalone for use when loading ramdisk: */
572 +#include <linux/kernel.h>
573 +#include <linux/fs.h>
574 +#include <linux/string.h>
575 +#include <linux/vmalloc.h>
577 +/* Use defines rather than static inline in order to avoid spurious
578 + * warnings when not needed (indeed large_malloc / large_free are not
579 + * needed by inflate */
581 +#define malloc(a) kmalloc(a, GFP_KERNEL)
582 +#define free(a) kfree(a)
584 +#define large_malloc(a) vmalloc(a)
585 +#define large_free(a) vfree(a)
587 +static void(*error)(char *m);
588 +#define set_error_fn(x) error = x;
593 +#include <linux/init.h>
597 +#endif /* DECOMPR_MM_H */
598 diff --git a/include/linux/decompress/unlzma.h b/include/linux/decompress/unlzma.h
600 index 0000000..7796538
602 +++ b/include/linux/decompress/unlzma.h
604 +#ifndef DECOMPRESS_UNLZMA_H
605 +#define DECOMPRESS_UNLZMA_H
607 +int unlzma(unsigned char *, int,
608 + int(*fill)(void*, unsigned int),
609 + int(*flush)(void*, unsigned int),
610 + unsigned char *output,
612 + void(*error)(char *x)
616 diff --git a/init/Kconfig b/init/Kconfig
617 index 6a5c5fe..38396ec 100644
620 @@ -101,6 +101,66 @@ config LOCALVERSION_AUTO
622 which is done within the script "scripts/setlocalversion".)
624 +config HAVE_KERNEL_GZIP
627 +config HAVE_KERNEL_BZIP2
630 +config HAVE_KERNEL_LZMA
634 + prompt "Kernel compression mode"
635 + default KERNEL_GZIP
636 + depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA
638 + The linux kernel is a kind of self-extracting executable.
639 + Several compression algorithms are available, which differ
640 + in efficiency, compression and decompression speed.
641 + Compression speed is only relevant when building a kernel.
642 + Decompression speed is relevant at each boot.
644 + If you have any problems with bzip2 or lzma compressed
645 + kernels, mail me (Alain Knaff) <alain@knaff.lu>. (An older
646 + version of this functionality (bzip2 only), for 2.4, was
647 + supplied by Christian Ludwig)
649 + High compression options are mostly useful for users, who
650 + are low on disk space (embedded systems), but for whom ram
653 + If in doubt, select 'gzip'
657 + depends on HAVE_KERNEL_GZIP
659 + The old and tried gzip compression. Its compression ratio is
660 + the poorest among the 3 choices; however its speed (both
661 + compression and decompression) is the fastest.
665 + depends on HAVE_KERNEL_BZIP2
667 + Its compression ratio and speed is intermediate.
668 + Decompression speed is slowest among the three. The kernel
669 + size is about 10% smaller with bzip2, in comparison to gzip.
670 + Bzip2 uses a large amount of memory. For modern kernels you
671 + will need at least 8MB RAM or more for booting.
675 + depends on HAVE_KERNEL_LZMA
677 + The most recent compression algorithm.
678 + Its ratio is best, decompression speed is between the other
679 + two. Compression is slowest. The kernel size is about 33%
680 + smaller with LZMA in comparison to gzip.
685 bool "Support for paging of anonymous memory (swap)"
686 depends on MMU && BLOCK
687 diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c
688 index 0f0f0cf..027a402 100644
689 --- a/init/do_mounts_rd.c
690 +++ b/init/do_mounts_rd.c
692 #include "do_mounts.h"
693 #include "../fs/squashfs/squashfs_fs.h"
695 +#include <linux/decompress/generic.h>
698 int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */
700 static int __init prompt_ramdisk(char *str)
701 @@ -29,7 +32,7 @@ static int __init ramdisk_start_setup(char *str)
703 __setup("ramdisk_start=", ramdisk_start_setup);
705 -static int __init crd_load(int in_fd, int out_fd);
706 +static int __init crd_load(int in_fd, int out_fd, decompress_fn deco);
709 * This routine tries to find a RAM disk image to load, and returns the
710 @@ -38,15 +41,15 @@ static int __init crd_load(int in_fd, int out_fd);
711 * numbers could not be found.
713 * We currently check for the following magic numbers:
725 -identify_ramdisk_image(int fd, int start_block)
727 +identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor)
729 const int size = 512;
730 struct minix_super_block *minixsb;
731 @@ -56,6 +59,7 @@ identify_ramdisk_image(int fd, int start_block)
732 struct squashfs_super_block *squashfsb;
735 + const char *compress_name;
737 buf = kmalloc(size, GFP_KERNEL);
739 @@ -69,18 +73,19 @@ identify_ramdisk_image(int fd, int start_block)
740 memset(buf, 0xe5, size);
743 - * Read block 0 to test for gzipped kernel
744 + * Read block 0 to test for compressed kernel
746 sys_lseek(fd, start_block * BLOCK_SIZE, 0);
747 sys_read(fd, buf, size);
750 - * If it matches the gzip magic numbers, return 0
752 - if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
754 - "RAMDISK: Compressed image found at block %d\n",
756 + *decompressor = decompress_method(buf, size, &compress_name);
757 + if (compress_name) {
758 + printk(KERN_NOTICE "RAMDISK: %s image found at block %d\n",
759 + compress_name, start_block);
760 + if (!*decompressor)
762 + "RAMDISK: %s decompressor not configured!\n",
767 @@ -142,7 +147,7 @@ identify_ramdisk_image(int fd, int start_block)
769 "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
774 sys_lseek(fd, start_block * BLOCK_SIZE, 0);
776 @@ -157,6 +162,7 @@ int __init rd_load_image(char *from)
777 int nblocks, i, disk;
779 unsigned short rotate = 0;
780 + decompress_fn decompressor = NULL;
781 #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES)
782 char rotator[4] = { '|' , '/' , '-' , '\\' };
784 @@ -169,12 +175,12 @@ int __init rd_load_image(char *from)
788 - nblocks = identify_ramdisk_image(in_fd, rd_image_start);
789 + nblocks = identify_ramdisk_image(in_fd, rd_image_start, &decompressor);
794 - if (crd_load(in_fd, out_fd) == 0)
795 + if (crd_load(in_fd, out_fd, decompressor) == 0)
796 goto successful_load;
799 @@ -200,7 +206,7 @@ int __init rd_load_image(char *from)
806 * OK, time to copy in the data
808 @@ -273,138 +279,48 @@ int __init rd_load_disk(int n)
809 return rd_load_image("/dev/root");
813 - * gzip declarations
816 -#define OF(args) args
819 -#define memzero(s, n) memset ((s), 0, (n))
822 -typedef unsigned char uch;
823 -typedef unsigned short ush;
824 -typedef unsigned long ulg;
826 -#define INBUFSIZ 4096
827 -#define WSIZE 0x8000 /* window size--must be a power of two, and */
828 - /* at least 32K for zip's deflate method */
833 -static unsigned insize; /* valid bytes in inbuf */
834 -static unsigned inptr; /* index of next byte to be processed in inbuf */
835 -static unsigned outcnt; /* bytes in output buffer */
836 static int exit_code;
837 -static int unzip_error;
838 -static long bytes_out;
839 +static int decompress_error;
840 static int crd_infd, crd_outfd;
842 -#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
844 -/* Diagnostic functions (stubbed out) */
845 -#define Assert(cond,msg)
850 -#define Tracecv(c,x)
852 -#define STATIC static
855 -static int __init fill_inbuf(void);
856 -static void __init flush_window(void);
857 -static void __init error(char *m);
859 -#define NO_INFLATE_MALLOC
861 -#include "../lib/inflate.c"
863 -/* ===========================================================================
864 - * Fill the input buffer. This is called only when the buffer is empty
865 - * and at least one byte is really needed.
866 - * Returning -1 does not guarantee that gunzip() will ever return.
868 -static int __init fill_inbuf(void)
869 +static int __init compr_fill(void *buf, unsigned int len)
871 - if (exit_code) return -1;
873 - insize = sys_read(crd_infd, inbuf, INBUFSIZ);
875 - error("RAMDISK: ran out of compressed data");
882 + int r = sys_read(crd_infd, buf, len);
884 + printk(KERN_ERR "RAMDISK: error while reading compressed data");
886 + printk(KERN_ERR "RAMDISK: EOF while reading compressed data");
890 -/* ===========================================================================
891 - * Write the output window window[0..outcnt-1] and update crc and bytes_out.
892 - * (Used for the decompressed data only.)
894 -static void __init flush_window(void)
895 +static int __init compr_flush(void *window, unsigned int outcnt)
897 - ulg c = crc; /* temporary variable */
898 - unsigned n, written;
901 - written = sys_write(crd_outfd, window, outcnt);
902 - if (written != outcnt && unzip_error == 0) {
903 - printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n",
904 - written, outcnt, bytes_out);
908 - for (n = 0; n < outcnt; n++) {
910 - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
913 - bytes_out += (ulg)outcnt;
915 + int written = sys_write(crd_outfd, window, outcnt);
916 + if (written != outcnt) {
917 + if (decompress_error == 0)
919 + "RAMDISK: incomplete write (%d != %d)\n",
921 + decompress_error = 1;
927 static void __init error(char *x)
929 printk(KERN_ERR "%s\n", x);
932 + decompress_error = 1;
935 -static int __init crd_load(int in_fd, int out_fd)
936 +static int __init crd_load(int in_fd, int out_fd, decompress_fn deco)
940 - insize = 0; /* valid bytes in inbuf */
941 - inptr = 0; /* index of next byte to be processed in inbuf */
942 - outcnt = 0; /* bytes in output buffer */
945 - crc = (ulg)0xffffffffL; /* shift register contents */
949 - inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
951 - printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
954 - window = kmalloc(WSIZE, GFP_KERNEL);
956 - printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
963 + result = deco(NULL, 0, compr_fill, compr_flush, NULL, NULL, error);
964 + if (decompress_error)
970 diff --git a/init/initramfs.c b/init/initramfs.c
971 index d9c941c..7dcde7e 100644
972 --- a/init/initramfs.c
973 +++ b/init/initramfs.c
974 @@ -390,11 +390,13 @@ static int __init write_buffer(char *buf, unsigned len)
978 -static void __init flush_buffer(char *buf, unsigned len)
979 +static int __init flush_buffer(void *bufv, unsigned len)
981 + char *buf = (char *) bufv;
987 while ((written = write_buffer(buf, len)) < len && !message) {
988 char c = buf[written];
990 @@ -408,84 +410,28 @@ static void __init flush_buffer(char *buf, unsigned len)
992 error("junk in compressed archive");
998 - * gzip declarations
1000 +static unsigned my_inptr; /* index of next byte to be processed in inbuf */
1002 -#define OF(args) args
1005 -#define memzero(s, n) memset ((s), 0, (n))
1008 -typedef unsigned char uch;
1009 -typedef unsigned short ush;
1010 -typedef unsigned long ulg;
1012 -#define WSIZE 0x8000 /* window size--must be a power of two, and */
1013 - /* at least 32K for zip's deflate method */
1016 -static uch *window;
1018 -static unsigned insize; /* valid bytes in inbuf */
1019 -static unsigned inptr; /* index of next byte to be processed in inbuf */
1020 -static unsigned outcnt; /* bytes in output buffer */
1021 -static long bytes_out;
1023 -#define get_byte() (inptr < insize ? inbuf[inptr++] : -1)
1025 -/* Diagnostic functions (stubbed out) */
1026 -#define Assert(cond,msg)
1030 -#define Tracec(c,x)
1031 -#define Tracecv(c,x)
1033 -#define STATIC static
1034 -#define INIT __init
1036 -static void __init flush_window(void);
1037 -static void __init error(char *m);
1039 -#define NO_INFLATE_MALLOC
1041 -#include "../lib/inflate.c"
1043 -/* ===========================================================================
1044 - * Write the output window window[0..outcnt-1] and update crc and bytes_out.
1045 - * (Used for the decompressed data only.)
1047 -static void __init flush_window(void)
1049 - ulg c = crc; /* temporary variable */
1053 - flush_buffer(window, outcnt);
1055 - for (n = 0; n < outcnt; n++) {
1057 - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
1060 - bytes_out += (ulg)outcnt;
1063 +#include <linux/decompress/generic.h>
1065 static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
1068 + decompress_fn decompress;
1069 + const char *compress_name;
1070 + static __initdata char msg_buf[64];
1072 dry_run = check_only;
1073 header_buf = kmalloc(110, GFP_KERNEL);
1074 symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
1075 name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL);
1076 - window = kmalloc(WSIZE, GFP_KERNEL);
1077 - if (!window || !header_buf || !symlink_buf || !name_buf)
1079 + if (!header_buf || !symlink_buf || !name_buf)
1080 panic("can't allocate buffers");
1085 @@ -505,22 +451,25 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
1092 - outcnt = 0; /* bytes in output buffer */
1094 - crc = (ulg)0xffffffffL; /* shift register contents */
1097 + decompress = decompress_method(buf, len, &compress_name);
1099 + decompress(buf, len, NULL, flush_buffer, NULL,
1100 + &my_inptr, error);
1101 + else if (compress_name) {
1103 + snprintf(msg_buf, sizeof msg_buf,
1104 + "compression method %s not configured",
1106 + message = msg_buf;
1110 - error("junk in gzipped archive");
1111 - this_header = saved_offset + inptr;
1114 + error("junk in compressed archive");
1115 + this_header = saved_offset + my_inptr;
1124 @@ -579,7 +528,7 @@ static int __init populate_rootfs(void)
1125 char *err = unpack_to_rootfs(__initramfs_start,
1126 __initramfs_end - __initramfs_start, 0);
1129 + panic(err); /* Failed to decompress INTERNAL initramfs */
1131 #ifdef CONFIG_BLK_DEV_RAM
1133 @@ -605,9 +554,12 @@ static int __init populate_rootfs(void)
1134 printk(KERN_INFO "Unpacking initramfs...");
1135 err = unpack_to_rootfs((char *)initrd_start,
1136 initrd_end - initrd_start, 0);
1139 - printk(" done\n");
1141 + printk(" failed!\n");
1142 + printk(KERN_EMERG "%s\n", err);
1144 + printk(" done\n");
1149 diff --git a/lib/Kconfig b/lib/Kconfig
1150 index 03c2c24..daa4818 100644
1153 @@ -98,6 +98,20 @@ config LZO_DECOMPRESS
1157 +# These all provide a common interface (hence the apparent duplication with
1158 +# ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.)
1160 +config DECOMPRESS_GZIP
1161 + select ZLIB_INFLATE
1164 +config DECOMPRESS_BZIP2
1167 +config DECOMPRESS_LZMA
1171 # Generic allocator support is selected if needed
1173 config GENERIC_ALLOCATOR
1174 diff --git a/lib/Makefile b/lib/Makefile
1175 index 32b0e64..790de7c 100644
1178 @@ -11,7 +11,8 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
1179 rbtree.o radix-tree.o dump_stack.o \
1180 idr.o int_sqrt.o extable.o prio_tree.o \
1181 sha1.o irq_regs.o reciprocal_div.o argv_split.o \
1182 - proportions.o prio_heap.o ratelimit.o show_mem.o is_single_threaded.o
1183 + proportions.o prio_heap.o ratelimit.o show_mem.o \
1184 + is_single_threaded.o decompress.o
1186 lib-$(CONFIG_MMU) += ioremap.o
1187 lib-$(CONFIG_SMP) += cpumask.o
1188 @@ -65,6 +66,10 @@ obj-$(CONFIG_REED_SOLOMON) += reed_solomon/
1189 obj-$(CONFIG_LZO_COMPRESS) += lzo/
1190 obj-$(CONFIG_LZO_DECOMPRESS) += lzo/
1192 +lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o
1193 +lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o
1194 +lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o
1196 obj-$(CONFIG_TEXTSEARCH) += textsearch.o
1197 obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o
1198 obj-$(CONFIG_TEXTSEARCH_BM) += ts_bm.o
1199 diff --git a/lib/decompress.c b/lib/decompress.c
1200 new file mode 100644
1201 index 0000000..d2842f5
1203 +++ b/lib/decompress.c
1208 + * Detect the decompression method based on magic number
1211 +#include <linux/decompress/generic.h>
1213 +#include <linux/decompress/bunzip2.h>
1214 +#include <linux/decompress/unlzma.h>
1215 +#include <linux/decompress/inflate.h>
1217 +#include <linux/types.h>
1218 +#include <linux/string.h>
1220 +#ifndef CONFIG_DECOMPRESS_GZIP
1221 +# define gunzip NULL
1223 +#ifndef CONFIG_DECOMPRESS_BZIP2
1224 +# define bunzip2 NULL
1226 +#ifndef CONFIG_DECOMPRESS_LZMA
1227 +# define unlzma NULL
1230 +static const struct compress_format {
1231 + unsigned char magic[2];
1233 + decompress_fn decompressor;
1234 +} compressed_formats[] = {
1235 + { {037, 0213}, "gzip", gunzip },
1236 + { {037, 0236}, "gzip", gunzip },
1237 + { {0x42, 0x5a}, "bzip2", bunzip2 },
1238 + { {0x5d, 0x00}, "lzma", unlzma },
1239 + { {0, 0}, NULL, NULL }
1242 +decompress_fn decompress_method(const unsigned char *inbuf, int len,
1243 + const char **name)
1245 + const struct compress_format *cf;
1248 + return NULL; /* Need at least this much... */
1250 + for (cf = compressed_formats; cf->name; cf++) {
1251 + if (!memcmp(inbuf, cf->magic, 2))
1257 + return cf->decompressor;
1259 diff --git a/lib/decompress_bunzip2.c b/lib/decompress_bunzip2.c
1260 new file mode 100644
1261 index 0000000..5d3ddb5
1263 +++ b/lib/decompress_bunzip2.c
1265 +/* vi: set sw = 4 ts = 4: */
1266 +/* Small bzip2 deflate implementation, by Rob Landley (rob@landley.net).
1268 + Based on bzip2 decompression code by Julian R Seward (jseward@acm.org),
1269 + which also acknowledges contributions by Mike Burrows, David Wheeler,
1270 + Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten,
1271 + Robert Sedgewick, and Jon L. Bentley.
1273 + This code is licensed under the LGPLv2:
1274 + LGPL (http://www.gnu.org/copyleft/lgpl.html
1278 + Size and speed optimizations by Manuel Novoa III (mjn3@codepoet.org).
1280 + More efficient reading of Huffman codes, a streamlined read_bunzip()
1281 + function, and various other tweaks. In (limited) tests, approximately
1282 + 20% faster than bzcat on x86 and about 10% faster on arm.
1284 + Note that about 2/3 of the time is spent in read_unzip() reversing
1285 + the Burrows-Wheeler transformation. Much of that time is delay
1286 + resulting from cache misses.
1288 + I would ask that anyone benefiting from this work, especially those
1289 + using it in commercial products, consider making a donation to my local
1290 + non-profit hospice organization in the name of the woman I loved, who
1291 + passed away Feb. 12, 2003.
1293 + In memory of Toni W. Hagan
1295 + Hospice of Acadiana, Inc.
1296 + 2600 Johnston St., Suite 200
1297 + Lafayette, LA 70503-3240
1299 + Phone (337) 232-1234 or 1-800-738-2226
1300 + Fax (337) 232-1297
1302 + http://www.hospiceacadiana.com/
1308 + Made it fit for running in Linux Kernel by Alain Knaff (alain@knaff.lu)
1313 +#include <linux/decompress/bunzip2.h>
1314 +#endif /* !STATIC */
1316 +#include <linux/decompress/mm.h>
1319 +#define INT_MAX 0x7fffffff
1322 +/* Constants for Huffman coding */
1323 +#define MAX_GROUPS 6
1324 +#define GROUP_SIZE 50 /* 64 would have been more efficient */
1325 +#define MAX_HUFCODE_BITS 20 /* Longest Huffman code allowed */
1326 +#define MAX_SYMBOLS 258 /* 256 literals + RUNA + RUNB */
1327 +#define SYMBOL_RUNA 0
1328 +#define SYMBOL_RUNB 1
1330 +/* Status return values */
1331 +#define RETVAL_OK 0
1332 +#define RETVAL_LAST_BLOCK (-1)
1333 +#define RETVAL_NOT_BZIP_DATA (-2)
1334 +#define RETVAL_UNEXPECTED_INPUT_EOF (-3)
1335 +#define RETVAL_UNEXPECTED_OUTPUT_EOF (-4)
1336 +#define RETVAL_DATA_ERROR (-5)
1337 +#define RETVAL_OUT_OF_MEMORY (-6)
1338 +#define RETVAL_OBSOLETE_INPUT (-7)
1340 +/* Other housekeeping constants */
1341 +#define BZIP2_IOBUF_SIZE 4096
1343 +/* This is what we know about each Huffman coding group */
1344 +struct group_data {
1345 + /* We have an extra slot at the end of limit[] for a sentinal value. */
1346 + int limit[MAX_HUFCODE_BITS+1];
1347 + int base[MAX_HUFCODE_BITS];
1348 + int permute[MAX_SYMBOLS];
1349 + int minLen, maxLen;
1352 +/* Structure holding all the housekeeping data, including IO buffers and
1353 + memory that persists between calls to bunzip */
1354 +struct bunzip_data {
1355 + /* State for interrupting output loop */
1356 + int writeCopies, writePos, writeRunCountdown, writeCount, writeCurrent;
1357 + /* I/O tracking data (file handles, buffers, positions, etc.) */
1358 + int (*fill)(void*, unsigned int);
1359 + int inbufCount, inbufPos /*, outbufPos*/;
1360 + unsigned char *inbuf /*,*outbuf*/;
1361 + unsigned int inbufBitCount, inbufBits;
1362 + /* The CRC values stored in the block header and calculated from the
1364 + unsigned int crc32Table[256], headerCRC, totalCRC, writeCRC;
1365 + /* Intermediate buffer and its size (in bytes) */
1366 + unsigned int *dbuf, dbufSize;
1367 + /* These things are a bit too big to go on the stack */
1368 + unsigned char selectors[32768]; /* nSelectors = 15 bits */
1369 + struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */
1370 + int io_error; /* non-zero if we have IO error */
1374 +/* Return the next nnn bits of input. All reads from the compressed input
1375 + are done through this function. All reads are big endian */
1376 +static unsigned int INIT get_bits(struct bunzip_data *bd, char bits_wanted)
1378 + unsigned int bits = 0;
1380 + /* If we need to get more data from the byte buffer, do so.
1381 + (Loop getting one byte at a time to enforce endianness and avoid
1382 + unaligned access.) */
1383 + while (bd->inbufBitCount < bits_wanted) {
1384 + /* If we need to read more data from file into byte buffer, do
1386 + if (bd->inbufPos == bd->inbufCount) {
1389 + bd->inbufCount = bd->fill(bd->inbuf, BZIP2_IOBUF_SIZE);
1390 + if (bd->inbufCount <= 0) {
1391 + bd->io_error = RETVAL_UNEXPECTED_INPUT_EOF;
1396 + /* Avoid 32-bit overflow (dump bit buffer to top of output) */
1397 + if (bd->inbufBitCount >= 24) {
1398 + bits = bd->inbufBits&((1 << bd->inbufBitCount)-1);
1399 + bits_wanted -= bd->inbufBitCount;
1400 + bits <<= bits_wanted;
1401 + bd->inbufBitCount = 0;
1403 + /* Grab next 8 bits of input from buffer. */
1404 + bd->inbufBits = (bd->inbufBits << 8)|bd->inbuf[bd->inbufPos++];
1405 + bd->inbufBitCount += 8;
1407 + /* Calculate result */
1408 + bd->inbufBitCount -= bits_wanted;
1409 + bits |= (bd->inbufBits >> bd->inbufBitCount)&((1 << bits_wanted)-1);
1414 +/* Unpacks the next block and sets up for the inverse burrows-wheeler step. */
1416 +static int INIT get_next_block(struct bunzip_data *bd)
1418 + struct group_data *hufGroup = NULL;
1420 + int *limit = NULL;
1421 + int dbufCount, nextSym, dbufSize, groupCount, selector,
1422 + i, j, k, t, runPos, symCount, symTotal, nSelectors,
1424 + unsigned char uc, symToByte[256], mtfSymbol[256], *selectors;
1425 + unsigned int *dbuf, origPtr;
1428 + dbufSize = bd->dbufSize;
1429 + selectors = bd->selectors;
1431 + /* Read in header signature and CRC, then validate signature.
1432 + (last block signature means CRC is for whole file, return now) */
1433 + i = get_bits(bd, 24);
1434 + j = get_bits(bd, 24);
1435 + bd->headerCRC = get_bits(bd, 32);
1436 + if ((i == 0x177245) && (j == 0x385090))
1437 + return RETVAL_LAST_BLOCK;
1438 + if ((i != 0x314159) || (j != 0x265359))
1439 + return RETVAL_NOT_BZIP_DATA;
1440 + /* We can add support for blockRandomised if anybody complains.
1441 + There was some code for this in busybox 1.0.0-pre3, but nobody ever
1442 + noticed that it didn't actually work. */
1443 + if (get_bits(bd, 1))
1444 + return RETVAL_OBSOLETE_INPUT;
1445 + origPtr = get_bits(bd, 24);
1446 + if (origPtr > dbufSize)
1447 + return RETVAL_DATA_ERROR;
1448 + /* mapping table: if some byte values are never used (encoding things
1449 + like ascii text), the compression code removes the gaps to have fewer
1450 + symbols to deal with, and writes a sparse bitfield indicating which
1451 + values were present. We make a translation table to convert the
1452 + symbols back to the corresponding bytes. */
1453 + t = get_bits(bd, 16);
1455 + for (i = 0; i < 16; i++) {
1456 + if (t&(1 << (15-i))) {
1457 + k = get_bits(bd, 16);
1458 + for (j = 0; j < 16; j++)
1459 + if (k&(1 << (15-j)))
1460 + symToByte[symTotal++] = (16*i)+j;
1463 + /* How many different Huffman coding groups does this block use? */
1464 + groupCount = get_bits(bd, 3);
1465 + if (groupCount < 2 || groupCount > MAX_GROUPS)
1466 + return RETVAL_DATA_ERROR;
1467 + /* nSelectors: Every GROUP_SIZE many symbols we select a new
1468 + Huffman coding group. Read in the group selector list,
1469 + which is stored as MTF encoded bit runs. (MTF = Move To
1470 + Front, as each value is used it's moved to the start of the
1472 + nSelectors = get_bits(bd, 15);
1474 + return RETVAL_DATA_ERROR;
1475 + for (i = 0; i < groupCount; i++)
1477 + for (i = 0; i < nSelectors; i++) {
1478 + /* Get next value */
1479 + for (j = 0; get_bits(bd, 1); j++)
1480 + if (j >= groupCount)
1481 + return RETVAL_DATA_ERROR;
1482 + /* Decode MTF to get the next selector */
1483 + uc = mtfSymbol[j];
1485 + mtfSymbol[j] = mtfSymbol[j-1];
1486 + mtfSymbol[0] = selectors[i] = uc;
1488 + /* Read the Huffman coding tables for each group, which code
1489 + for symTotal literal symbols, plus two run symbols (RUNA,
1491 + symCount = symTotal+2;
1492 + for (j = 0; j < groupCount; j++) {
1493 + unsigned char length[MAX_SYMBOLS], temp[MAX_HUFCODE_BITS+1];
1494 + int minLen, maxLen, pp;
1495 + /* Read Huffman code lengths for each symbol. They're
1496 + stored in a way similar to mtf; record a starting
1497 + value for the first symbol, and an offset from the
1498 + previous value for everys symbol after that.
1499 + (Subtracting 1 before the loop and then adding it
1500 + back at the end is an optimization that makes the
1501 + test inside the loop simpler: symbol length 0
1502 + becomes negative, so an unsigned inequality catches
1504 + t = get_bits(bd, 5)-1;
1505 + for (i = 0; i < symCount; i++) {
1507 + if (((unsigned)t) > (MAX_HUFCODE_BITS-1))
1508 + return RETVAL_DATA_ERROR;
1510 + /* If first bit is 0, stop. Else
1511 + second bit indicates whether to
1512 + increment or decrement the value.
1513 + Optimization: grab 2 bits and unget
1514 + the second if the first was 0. */
1516 + k = get_bits(bd, 2);
1518 + bd->inbufBitCount++;
1521 + /* Add one if second bit 1, else
1522 + * subtract 1. Avoids if/else */
1523 + t += (((k+1)&2)-1);
1525 + /* Correct for the initial -1, to get the
1526 + * final symbol length */
1529 + /* Find largest and smallest lengths in this group */
1530 + minLen = maxLen = length[0];
1532 + for (i = 1; i < symCount; i++) {
1533 + if (length[i] > maxLen)
1534 + maxLen = length[i];
1535 + else if (length[i] < minLen)
1536 + minLen = length[i];
1539 + /* Calculate permute[], base[], and limit[] tables from
1542 + * permute[] is the lookup table for converting
1543 + * Huffman coded symbols into decoded symbols. base[]
1544 + * is the amount to subtract from the value of a
1545 + * Huffman symbol of a given length when using
1548 + * limit[] indicates the largest numerical value a
1549 + * symbol with a given number of bits can have. This
1550 + * is how the Huffman codes can vary in length: each
1551 + * code with a value > limit[length] needs another
1554 + hufGroup = bd->groups+j;
1555 + hufGroup->minLen = minLen;
1556 + hufGroup->maxLen = maxLen;
1557 + /* Note that minLen can't be smaller than 1, so we
1558 + adjust the base and limit array pointers so we're
1559 + not always wasting the first entry. We do this
1560 + again when using them (during symbol decoding).*/
1561 + base = hufGroup->base-1;
1562 + limit = hufGroup->limit-1;
1563 + /* Calculate permute[]. Concurently, initialize
1564 + * temp[] and limit[]. */
1566 + for (i = minLen; i <= maxLen; i++) {
1567 + temp[i] = limit[i] = 0;
1568 + for (t = 0; t < symCount; t++)
1569 + if (length[t] == i)
1570 + hufGroup->permute[pp++] = t;
1572 + /* Count symbols coded for at each bit length */
1573 + for (i = 0; i < symCount; i++)
1574 + temp[length[i]]++;
1575 + /* Calculate limit[] (the largest symbol-coding value
1576 + *at each bit length, which is (previous limit <<
1577 + *1)+symbols at this level), and base[] (number of
1578 + *symbols to ignore at each bit length, which is limit
1579 + *minus the cumulative count of symbols coded for
1582 + for (i = minLen; i < maxLen; i++) {
1584 + /* We read the largest possible symbol size
1585 + and then unget bits after determining how
1586 + many we need, and those extra bits could be
1587 + set to anything. (They're noise from
1588 + future symbols.) At each level we're
1589 + really only interested in the first few
1590 + bits, so here we set all the trailing
1591 + to-be-ignored bits to 1 so they don't
1592 + affect the value > limit[length]
1594 + limit[i] = (pp << (maxLen - i)) - 1;
1596 + base[i+1] = pp-(t += temp[i]);
1598 + limit[maxLen+1] = INT_MAX; /* Sentinal value for
1599 + * reading next sym. */
1600 + limit[maxLen] = pp+temp[maxLen]-1;
1603 + /* We've finished reading and digesting the block header. Now
1604 + read this block's Huffman coded symbols from the file and
1605 + undo the Huffman coding and run length encoding, saving the
1606 + result into dbuf[dbufCount++] = uc */
1608 + /* Initialize symbol occurrence counters and symbol Move To
1610 + for (i = 0; i < 256; i++) {
1612 + mtfSymbol[i] = (unsigned char)i;
1614 + /* Loop through compressed symbols. */
1615 + runPos = dbufCount = symCount = selector = 0;
1617 + /* Determine which Huffman coding group to use. */
1618 + if (!(symCount--)) {
1619 + symCount = GROUP_SIZE-1;
1620 + if (selector >= nSelectors)
1621 + return RETVAL_DATA_ERROR;
1622 + hufGroup = bd->groups+selectors[selector++];
1623 + base = hufGroup->base-1;
1624 + limit = hufGroup->limit-1;
1626 + /* Read next Huffman-coded symbol. */
1627 + /* Note: It is far cheaper to read maxLen bits and
1628 + back up than it is to read minLen bits and then an
1629 + additional bit at a time, testing as we go.
1630 + Because there is a trailing last block (with file
1631 + CRC), there is no danger of the overread causing an
1632 + unexpected EOF for a valid compressed file. As a
1633 + further optimization, we do the read inline
1634 + (falling back to a call to get_bits if the buffer
1635 + runs dry). The following (up to got_huff_bits:) is
1636 + equivalent to j = get_bits(bd, hufGroup->maxLen);
1638 + while (bd->inbufBitCount < hufGroup->maxLen) {
1639 + if (bd->inbufPos == bd->inbufCount) {
1640 + j = get_bits(bd, hufGroup->maxLen);
1641 + goto got_huff_bits;
1644 + (bd->inbufBits << 8)|bd->inbuf[bd->inbufPos++];
1645 + bd->inbufBitCount += 8;
1647 + bd->inbufBitCount -= hufGroup->maxLen;
1648 + j = (bd->inbufBits >> bd->inbufBitCount)&
1649 + ((1 << hufGroup->maxLen)-1);
1651 + /* Figure how how many bits are in next symbol and
1653 + i = hufGroup->minLen;
1654 + while (j > limit[i])
1656 + bd->inbufBitCount += (hufGroup->maxLen - i);
1657 + /* Huffman decode value to get nextSym (with bounds checking) */
1658 + if ((i > hufGroup->maxLen)
1659 + || (((unsigned)(j = (j>>(hufGroup->maxLen-i))-base[i]))
1661 + return RETVAL_DATA_ERROR;
1662 + nextSym = hufGroup->permute[j];
1663 + /* We have now decoded the symbol, which indicates
1664 + either a new literal byte, or a repeated run of the
1665 + most recent literal byte. First, check if nextSym
1666 + indicates a repeated run, and if so loop collecting
1667 + how many times to repeat the last literal. */
1668 + if (((unsigned)nextSym) <= SYMBOL_RUNB) { /* RUNA or RUNB */
1669 + /* If this is the start of a new run, zero out
1675 + /* Neat trick that saves 1 symbol: instead of
1676 + or-ing 0 or 1 at each bit position, add 1
1677 + or 2 instead. For example, 1011 is 1 << 0
1678 + + 1 << 1 + 2 << 2. 1010 is 2 << 0 + 2 << 1
1679 + + 1 << 2. You can make any bit pattern
1680 + that way using 1 less symbol than the basic
1681 + or 0/1 method (except all bits 0, which
1682 + would use no symbols, but a run of length 0
1683 + doesn't mean anything in this context).
1684 + Thus space is saved. */
1685 + t += (runPos << nextSym);
1686 + /* +runPos if RUNA; +2*runPos if RUNB */
1691 + /* When we hit the first non-run symbol after a run,
1692 + we now know how many times to repeat the last
1693 + literal, so append that many copies to our buffer
1694 + of decoded symbols (dbuf) now. (The last literal
1695 + used is the one at the head of the mtfSymbol
1699 + if (dbufCount+t >= dbufSize)
1700 + return RETVAL_DATA_ERROR;
1702 + uc = symToByte[mtfSymbol[0]];
1703 + byteCount[uc] += t;
1705 + dbuf[dbufCount++] = uc;
1707 + /* Is this the terminating symbol? */
1708 + if (nextSym > symTotal)
1710 + /* At this point, nextSym indicates a new literal
1711 + character. Subtract one to get the position in the
1712 + MTF array at which this literal is currently to be
1713 + found. (Note that the result can't be -1 or 0,
1714 + because 0 and 1 are RUNA and RUNB. But another
1715 + instance of the first symbol in the mtf array,
1716 + position 0, would have been handled as part of a
1717 + run above. Therefore 1 unused mtf position minus 2
1718 + non-literal nextSym values equals -1.) */
1719 + if (dbufCount >= dbufSize)
1720 + return RETVAL_DATA_ERROR;
1722 + uc = mtfSymbol[i];
1723 + /* Adjust the MTF array. Since we typically expect to
1724 + *move only a small number of symbols, and are bound
1725 + *by 256 in any case, using memmove here would
1726 + *typically be bigger and slower due to function call
1727 + *overhead and other assorted setup costs. */
1729 + mtfSymbol[i] = mtfSymbol[i-1];
1731 + mtfSymbol[0] = uc;
1732 + uc = symToByte[uc];
1733 + /* We have our literal byte. Save it into dbuf. */
1735 + dbuf[dbufCount++] = (unsigned int)uc;
1737 + /* At this point, we've read all the Huffman-coded symbols
1738 + (and repeated runs) for this block from the input stream,
1739 + and decoded them into the intermediate buffer. There are
1740 + dbufCount many decoded bytes in dbuf[]. Now undo the
1741 + Burrows-Wheeler transform on dbuf. See
1742 + http://dogma.net/markn/articles/bwt/bwt.htm
1744 + /* Turn byteCount into cumulative occurrence counts of 0 to n-1. */
1746 + for (i = 0; i < 256; i++) {
1747 + k = j+byteCount[i];
1751 + /* Figure out what order dbuf would be in if we sorted it. */
1752 + for (i = 0; i < dbufCount; i++) {
1753 + uc = (unsigned char)(dbuf[i] & 0xff);
1754 + dbuf[byteCount[uc]] |= (i << 8);
1757 + /* Decode first byte by hand to initialize "previous" byte.
1758 + Note that it doesn't get output, and if the first three
1759 + characters are identical it doesn't qualify as a run (hence
1760 + writeRunCountdown = 5). */
1762 + if (origPtr >= dbufCount)
1763 + return RETVAL_DATA_ERROR;
1764 + bd->writePos = dbuf[origPtr];
1765 + bd->writeCurrent = (unsigned char)(bd->writePos&0xff);
1766 + bd->writePos >>= 8;
1767 + bd->writeRunCountdown = 5;
1769 + bd->writeCount = dbufCount;
1774 +/* Undo burrows-wheeler transform on intermediate buffer to produce output.
1775 + If start_bunzip was initialized with out_fd =-1, then up to len bytes of
1776 + data are written to outbuf. Return value is number of bytes written or
1777 + error (all errors are negative numbers). If out_fd!=-1, outbuf and len
1778 + are ignored, data is written to out_fd and return is RETVAL_OK or error.
1781 +static int INIT read_bunzip(struct bunzip_data *bd, char *outbuf, int len)
1783 + const unsigned int *dbuf;
1784 + int pos, xcurrent, previous, gotcount;
1786 + /* If last read was short due to end of file, return last block now */
1787 + if (bd->writeCount < 0)
1788 + return bd->writeCount;
1792 + pos = bd->writePos;
1793 + xcurrent = bd->writeCurrent;
1795 + /* We will always have pending decoded data to write into the output
1796 + buffer unless this is the very first call (in which case we haven't
1797 + Huffman-decoded a block into the intermediate buffer yet). */
1799 + if (bd->writeCopies) {
1800 + /* Inside the loop, writeCopies means extra copies (beyond 1) */
1801 + --bd->writeCopies;
1802 + /* Loop outputting bytes */
1804 + /* If the output buffer is full, snapshot
1805 + * state and return */
1806 + if (gotcount >= len) {
1807 + bd->writePos = pos;
1808 + bd->writeCurrent = xcurrent;
1809 + bd->writeCopies++;
1812 + /* Write next byte into output buffer, updating CRC */
1813 + outbuf[gotcount++] = xcurrent;
1814 + bd->writeCRC = (((bd->writeCRC) << 8)
1815 + ^bd->crc32Table[((bd->writeCRC) >> 24)
1817 + /* Loop now if we're outputting multiple
1818 + * copies of this byte */
1819 + if (bd->writeCopies) {
1820 + --bd->writeCopies;
1824 + if (!bd->writeCount--)
1826 + /* Follow sequence vector to undo
1827 + * Burrows-Wheeler transform */
1828 + previous = xcurrent;
1830 + xcurrent = pos&0xff;
1832 + /* After 3 consecutive copies of the same
1833 + byte, the 4th is a repeat count. We count
1834 + down from 4 instead *of counting up because
1835 + testing for non-zero is faster */
1836 + if (--bd->writeRunCountdown) {
1837 + if (xcurrent != previous)
1838 + bd->writeRunCountdown = 4;
1840 + /* We have a repeated run, this byte
1841 + * indicates the count */
1842 + bd->writeCopies = xcurrent;
1843 + xcurrent = previous;
1844 + bd->writeRunCountdown = 5;
1845 + /* Sometimes there are just 3 bytes
1846 + * (run length 0) */
1847 + if (!bd->writeCopies)
1848 + goto decode_next_byte;
1849 + /* Subtract the 1 copy we'd output
1850 + * anyway to get extras */
1851 + --bd->writeCopies;
1854 + /* Decompression of this block completed successfully */
1855 + bd->writeCRC = ~bd->writeCRC;
1856 + bd->totalCRC = ((bd->totalCRC << 1) |
1857 + (bd->totalCRC >> 31)) ^ bd->writeCRC;
1858 + /* If this block had a CRC error, force file level CRC error. */
1859 + if (bd->writeCRC != bd->headerCRC) {
1860 + bd->totalCRC = bd->headerCRC+1;
1861 + return RETVAL_LAST_BLOCK;
1865 + /* Refill the intermediate buffer by Huffman-decoding next
1866 + * block of input */
1867 + /* (previous is just a convenient unused temp variable here) */
1868 + previous = get_next_block(bd);
1870 + bd->writeCount = previous;
1871 + return (previous != RETVAL_LAST_BLOCK) ? previous : gotcount;
1873 + bd->writeCRC = 0xffffffffUL;
1874 + pos = bd->writePos;
1875 + xcurrent = bd->writeCurrent;
1876 + goto decode_next_byte;
1879 +static int INIT nofill(void *buf, unsigned int len)
1884 +/* Allocate the structure, read file header. If in_fd ==-1, inbuf must contain
1885 + a complete bunzip file (len bytes long). If in_fd!=-1, inbuf and len are
1886 + ignored, and data is read from file handle into temporary buffer. */
1887 +static int INIT start_bunzip(struct bunzip_data **bdp, void *inbuf, int len,
1888 + int (*fill)(void*, unsigned int))
1890 + struct bunzip_data *bd;
1891 + unsigned int i, j, c;
1892 + const unsigned int BZh0 =
1893 + (((unsigned int)'B') << 24)+(((unsigned int)'Z') << 16)
1894 + +(((unsigned int)'h') << 8)+(unsigned int)'0';
1896 + /* Figure out how much data to allocate */
1897 + i = sizeof(struct bunzip_data);
1899 + /* Allocate bunzip_data. Most fields initialize to zero. */
1900 + bd = *bdp = malloc(i);
1901 + memset(bd, 0, sizeof(struct bunzip_data));
1902 + /* Setup input buffer */
1903 + bd->inbuf = inbuf;
1904 + bd->inbufCount = len;
1908 + bd->fill = nofill;
1910 + /* Init the CRC32 table (big endian) */
1911 + for (i = 0; i < 256; i++) {
1913 + for (j = 8; j; j--)
1914 + c = c&0x80000000 ? (c << 1)^0x04c11db7 : (c << 1);
1915 + bd->crc32Table[i] = c;
1918 + /* Ensure that file starts with "BZh['1'-'9']." */
1919 + i = get_bits(bd, 32);
1920 + if (((unsigned int)(i-BZh0-1)) >= 9)
1921 + return RETVAL_NOT_BZIP_DATA;
1923 + /* Fourth byte (ascii '1'-'9'), indicates block size in units of 100k of
1924 + uncompressed data. Allocate intermediate buffer for block. */
1925 + bd->dbufSize = 100000*(i-BZh0);
1927 + bd->dbuf = large_malloc(bd->dbufSize * sizeof(int));
1931 +/* Example usage: decompress src_fd to dst_fd. (Stops at end of bzip2 data,
1932 + not end of file.) */
1933 +STATIC int INIT bunzip2(unsigned char *buf, int len,
1934 + int(*fill)(void*, unsigned int),
1935 + int(*flush)(void*, unsigned int),
1936 + unsigned char *outbuf,
1938 + void(*error_fn)(char *x))
1940 + struct bunzip_data *bd;
1942 + unsigned char *inbuf;
1944 + set_error_fn(error_fn);
1946 + outbuf = malloc(BZIP2_IOBUF_SIZE);
1948 + len -= 4; /* Uncompressed size hack active in pre-boot
1951 + error("Could not allocate output bufer");
1957 + inbuf = malloc(BZIP2_IOBUF_SIZE);
1959 + error("Could not allocate input bufer");
1962 + i = start_bunzip(&bd, inbuf, len, fill);
1965 + i = read_bunzip(bd, outbuf, BZIP2_IOBUF_SIZE);
1971 + if (i != flush(outbuf, i)) {
1972 + i = RETVAL_UNEXPECTED_OUTPUT_EOF;
1977 + /* Check CRC and release memory */
1978 + if (i == RETVAL_LAST_BLOCK) {
1979 + if (bd->headerCRC != bd->totalCRC)
1980 + error("Data integrity error when decompressing.");
1983 + } else if (i == RETVAL_UNEXPECTED_OUTPUT_EOF) {
1984 + error("Compressed file ends unexpectedly");
1987 + large_free(bd->dbuf);
1989 + *pos = bd->inbufPos;
1999 +#define decompress bunzip2
2000 diff --git a/lib/decompress_inflate.c b/lib/decompress_inflate.c
2001 new file mode 100644
2002 index 0000000..839a329
2004 +++ b/lib/decompress_inflate.c
2007 +/* Pre-boot environment: included */
2009 +/* prevent inclusion of _LINUX_KERNEL_H in pre-boot environment: lots
2010 + * errors about console_printk etc... on ARM */
2011 +#define _LINUX_KERNEL_H
2013 +#include "zlib_inflate/inftrees.c"
2014 +#include "zlib_inflate/inffast.c"
2015 +#include "zlib_inflate/inflate.c"
2018 +/* initramfs et al: linked */
2020 +#include <linux/zutil.h>
2022 +#include "zlib_inflate/inftrees.h"
2023 +#include "zlib_inflate/inffast.h"
2024 +#include "zlib_inflate/inflate.h"
2026 +#include "zlib_inflate/infutil.h"
2028 +#endif /* STATIC */
2030 +#include <linux/decompress/mm.h>
2032 +#define INBUF_LEN (16*1024)
2034 +/* Included from initramfs et al code */
2035 +STATIC int INIT gunzip(unsigned char *buf, int len,
2036 + int(*fill)(void*, unsigned int),
2037 + int(*flush)(void*, unsigned int),
2038 + unsigned char *out_buf,
2040 + void(*error_fn)(char *x)) {
2042 + struct z_stream_s *strm;
2046 + set_error_fn(error_fn);
2049 + out_len = 0x8000; /* 32 K */
2050 + out_buf = malloc(out_len);
2052 + out_len = 0x7fffffff; /* no limit */
2055 + error("Out of memory while allocating output buffer");
2056 + goto gunzip_nomem1;
2062 + zbuf = malloc(INBUF_LEN);
2066 + error("Out of memory while allocating input buffer");
2067 + goto gunzip_nomem2;
2070 + strm = malloc(sizeof(*strm));
2071 + if (strm == NULL) {
2072 + error("Out of memory while allocating z_stream");
2073 + goto gunzip_nomem3;
2076 + strm->workspace = malloc(flush ? zlib_inflate_workspacesize() :
2077 + sizeof(struct inflate_state));
2078 + if (strm->workspace == NULL) {
2079 + error("Out of memory while allocating workspace");
2080 + goto gunzip_nomem4;
2084 + len = fill(zbuf, INBUF_LEN);
2086 + /* verify the gzip header */
2088 + zbuf[0] != 0x1f || zbuf[1] != 0x8b || zbuf[2] != 0x08) {
2091 + error("Not a gzip file");
2095 + /* skip over gzip header (1f,8b,08... 10 bytes total +
2096 + * possible asciz filename)
2098 + strm->next_in = zbuf + 10;
2099 + /* skip over asciz filename */
2100 + if (zbuf[3] & 0x8) {
2101 + while (strm->next_in[0])
2105 + strm->avail_in = len - (strm->next_in - zbuf);
2107 + strm->next_out = out_buf;
2108 + strm->avail_out = out_len;
2110 + rc = zlib_inflateInit2(strm, -MAX_WBITS);
2113 + WS(strm)->inflate_state.wsize = 0;
2114 + WS(strm)->inflate_state.window = NULL;
2117 + while (rc == Z_OK) {
2118 + if (strm->avail_in == 0) {
2119 + /* TODO: handle case where both pos and fill are set */
2120 + len = fill(zbuf, INBUF_LEN);
2123 + error("read error");
2126 + strm->next_in = zbuf;
2127 + strm->avail_in = len;
2129 + rc = zlib_inflate(strm, 0);
2131 + /* Write any data generated */
2132 + if (flush && strm->next_out > out_buf) {
2133 + int l = strm->next_out - out_buf;
2134 + if (l != flush(out_buf, l)) {
2136 + error("write error");
2139 + strm->next_out = out_buf;
2140 + strm->avail_out = out_len;
2143 + /* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */
2144 + if (rc == Z_STREAM_END) {
2147 + } else if (rc != Z_OK) {
2148 + error("uncompression error");
2153 + zlib_inflateEnd(strm);
2155 + /* add + 8 to skip over trailer */
2156 + *pos = strm->next_in - zbuf+8;
2159 + free(strm->workspace);
2169 + return rc; /* returns Z_OK (0) if successful */
2172 +#define decompress gunzip
2173 diff --git a/lib/decompress_unlzma.c b/lib/decompress_unlzma.c
2174 new file mode 100644
2175 index 0000000..546f2f4
2177 +++ b/lib/decompress_unlzma.c
2179 +/* Lzma decompressor for Linux kernel. Shamelessly snarfed
2180 + *from busybox 1.1.1
2182 + *Linux kernel adaptation
2183 + *Copyright (C) 2006 Alain < alain@knaff.lu >
2185 + *Based on small lzma deflate implementation/Small range coder
2186 + *implementation for lzma.
2187 + *Copyright (C) 2006 Aurelien Jacobs < aurel@gnuage.org >
2189 + *Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/)
2190 + *Copyright (C) 1999-2005 Igor Pavlov
2192 + *Copyrights of the parts, see headers below.
2195 + *This program is free software; you can redistribute it and/or
2196 + *modify it under the terms of the GNU Lesser General Public
2197 + *License as published by the Free Software Foundation; either
2198 + *version 2.1 of the License, or (at your option) any later version.
2200 + *This program is distributed in the hope that it will be useful,
2201 + *but WITHOUT ANY WARRANTY; without even the implied warranty of
2202 + *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2203 + *Lesser General Public License for more details.
2205 + *You should have received a copy of the GNU Lesser General Public
2206 + *License along with this library; if not, write to the Free Software
2207 + *Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2211 +#include <linux/decompress/unlzma.h>
2212 +#endif /* STATIC */
2214 +#include <linux/decompress/mm.h>
2216 +#define MIN(a, b) (((a) < (b)) ? (a) : (b))
2218 +static long long INIT read_int(unsigned char *ptr, int size)
2221 + long long ret = 0;
2223 + for (i = 0; i < size; i++)
2224 + ret = (ret << 8) | ptr[size-i-1];
2228 +#define ENDIAN_CONVERT(x) \
2229 + x = (typeof(x))read_int((unsigned char *)&x, sizeof(x))
2232 +/* Small range coder implementation for lzma.
2233 + *Copyright (C) 2006 Aurelien Jacobs < aurel@gnuage.org >
2235 + *Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/)
2236 + *Copyright (c) 1999-2005 Igor Pavlov
2239 +#include <linux/compiler.h>
2241 +#define LZMA_IOBUF_SIZE 0x10000
2244 + int (*fill)(void*, unsigned int);
2247 + uint8_t *buffer_end;
2255 +#define RC_TOP_BITS 24
2256 +#define RC_MOVE_BITS 5
2257 +#define RC_MODEL_TOTAL_BITS 11
2260 +/* Called twice: once at startup and once in rc_normalize() */
2261 +static void INIT rc_read(struct rc *rc)
2263 + rc->buffer_size = rc->fill((char *)rc->buffer, LZMA_IOBUF_SIZE);
2264 + if (rc->buffer_size <= 0)
2265 + error("unexpected EOF");
2266 + rc->ptr = rc->buffer;
2267 + rc->buffer_end = rc->buffer + rc->buffer_size;
2271 +static inline void INIT rc_init(struct rc *rc,
2272 + int (*fill)(void*, unsigned int),
2273 + char *buffer, int buffer_size)
2276 + rc->buffer = (uint8_t *)buffer;
2277 + rc->buffer_size = buffer_size;
2278 + rc->buffer_end = rc->buffer + rc->buffer_size;
2279 + rc->ptr = rc->buffer;
2282 + rc->range = 0xFFFFFFFF;
2285 +static inline void INIT rc_init_code(struct rc *rc)
2289 + for (i = 0; i < 5; i++) {
2290 + if (rc->ptr >= rc->buffer_end)
2292 + rc->code = (rc->code << 8) | *rc->ptr++;
2297 +/* Called once. TODO: bb_maybe_free() */
2298 +static inline void INIT rc_free(struct rc *rc)
2303 +/* Called twice, but one callsite is in inline'd rc_is_bit_0_helper() */
2304 +static void INIT rc_do_normalize(struct rc *rc)
2306 + if (rc->ptr >= rc->buffer_end)
2309 + rc->code = (rc->code << 8) | *rc->ptr++;
2311 +static inline void INIT rc_normalize(struct rc *rc)
2313 + if (rc->range < (1 << RC_TOP_BITS))
2314 + rc_do_normalize(rc);
2317 +/* Called 9 times */
2318 +/* Why rc_is_bit_0_helper exists?
2319 + *Because we want to always expose (rc->code < rc->bound) to optimizer
2321 +static inline uint32_t INIT rc_is_bit_0_helper(struct rc *rc, uint16_t *p)
2324 + rc->bound = *p * (rc->range >> RC_MODEL_TOTAL_BITS);
2327 +static inline int INIT rc_is_bit_0(struct rc *rc, uint16_t *p)
2329 + uint32_t t = rc_is_bit_0_helper(rc, p);
2330 + return rc->code < t;
2333 +/* Called ~10 times, but very small, thus inlined */
2334 +static inline void INIT rc_update_bit_0(struct rc *rc, uint16_t *p)
2336 + rc->range = rc->bound;
2337 + *p += ((1 << RC_MODEL_TOTAL_BITS) - *p) >> RC_MOVE_BITS;
2339 +static inline void rc_update_bit_1(struct rc *rc, uint16_t *p)
2341 + rc->range -= rc->bound;
2342 + rc->code -= rc->bound;
2343 + *p -= *p >> RC_MOVE_BITS;
2346 +/* Called 4 times in unlzma loop */
2347 +static int INIT rc_get_bit(struct rc *rc, uint16_t *p, int *symbol)
2349 + if (rc_is_bit_0(rc, p)) {
2350 + rc_update_bit_0(rc, p);
2354 + rc_update_bit_1(rc, p);
2355 + *symbol = *symbol * 2 + 1;
2361 +static inline int INIT rc_direct_bit(struct rc *rc)
2365 + if (rc->code >= rc->range) {
2366 + rc->code -= rc->range;
2373 +static inline void INIT
2374 +rc_bit_tree_decode(struct rc *rc, uint16_t *p, int num_levels, int *symbol)
2376 + int i = num_levels;
2380 + rc_get_bit(rc, p + *symbol, symbol);
2381 + *symbol -= 1 << num_levels;
2386 + * Small lzma deflate implementation.
2387 + * Copyright (C) 2006 Aurelien Jacobs < aurel@gnuage.org >
2389 + * Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/)
2390 + * Copyright (C) 1999-2005 Igor Pavlov
2394 +struct lzma_header {
2396 + uint32_t dict_size;
2397 + uint64_t dst_size;
2398 +} __attribute__ ((packed)) ;
2401 +#define LZMA_BASE_SIZE 1846
2402 +#define LZMA_LIT_SIZE 768
2404 +#define LZMA_NUM_POS_BITS_MAX 4
2406 +#define LZMA_LEN_NUM_LOW_BITS 3
2407 +#define LZMA_LEN_NUM_MID_BITS 3
2408 +#define LZMA_LEN_NUM_HIGH_BITS 8
2410 +#define LZMA_LEN_CHOICE 0
2411 +#define LZMA_LEN_CHOICE_2 (LZMA_LEN_CHOICE + 1)
2412 +#define LZMA_LEN_LOW (LZMA_LEN_CHOICE_2 + 1)
2413 +#define LZMA_LEN_MID (LZMA_LEN_LOW \
2414 + + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS)))
2415 +#define LZMA_LEN_HIGH (LZMA_LEN_MID \
2416 + +(1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS)))
2417 +#define LZMA_NUM_LEN_PROBS (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS))
2419 +#define LZMA_NUM_STATES 12
2420 +#define LZMA_NUM_LIT_STATES 7
2422 +#define LZMA_START_POS_MODEL_INDEX 4
2423 +#define LZMA_END_POS_MODEL_INDEX 14
2424 +#define LZMA_NUM_FULL_DISTANCES (1 << (LZMA_END_POS_MODEL_INDEX >> 1))
2426 +#define LZMA_NUM_POS_SLOT_BITS 6
2427 +#define LZMA_NUM_LEN_TO_POS_STATES 4
2429 +#define LZMA_NUM_ALIGN_BITS 4
2431 +#define LZMA_MATCH_MIN_LEN 2
2433 +#define LZMA_IS_MATCH 0
2434 +#define LZMA_IS_REP (LZMA_IS_MATCH + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX))
2435 +#define LZMA_IS_REP_G0 (LZMA_IS_REP + LZMA_NUM_STATES)
2436 +#define LZMA_IS_REP_G1 (LZMA_IS_REP_G0 + LZMA_NUM_STATES)
2437 +#define LZMA_IS_REP_G2 (LZMA_IS_REP_G1 + LZMA_NUM_STATES)
2438 +#define LZMA_IS_REP_0_LONG (LZMA_IS_REP_G2 + LZMA_NUM_STATES)
2439 +#define LZMA_POS_SLOT (LZMA_IS_REP_0_LONG \
2440 + + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX))
2441 +#define LZMA_SPEC_POS (LZMA_POS_SLOT \
2442 + +(LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS))
2443 +#define LZMA_ALIGN (LZMA_SPEC_POS \
2444 + + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX)
2445 +#define LZMA_LEN_CODER (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS))
2446 +#define LZMA_REP_LEN_CODER (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS)
2447 +#define LZMA_LITERAL (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS)
2452 + uint8_t previous_byte;
2453 + size_t buffer_pos;
2455 + size_t global_pos;
2456 + int(*flush)(void*, unsigned int);
2457 + struct lzma_header *header;
2462 + uint32_t rep0, rep1, rep2, rep3;
2465 +static inline size_t INIT get_pos(struct writer *wr)
2468 + wr->global_pos + wr->buffer_pos;
2471 +static inline uint8_t INIT peek_old_byte(struct writer *wr,
2476 + while (offs > wr->header->dict_size)
2477 + offs -= wr->header->dict_size;
2478 + pos = wr->buffer_pos - offs;
2479 + return wr->buffer[pos];
2481 + uint32_t pos = wr->buffer_pos - offs;
2482 + while (pos >= wr->header->dict_size)
2483 + pos += wr->header->dict_size;
2484 + return wr->buffer[pos];
2489 +static inline void INIT write_byte(struct writer *wr, uint8_t byte)
2491 + wr->buffer[wr->buffer_pos++] = wr->previous_byte = byte;
2492 + if (wr->flush && wr->buffer_pos == wr->header->dict_size) {
2493 + wr->buffer_pos = 0;
2494 + wr->global_pos += wr->header->dict_size;
2495 + wr->flush((char *)wr->buffer, wr->header->dict_size);
2500 +static inline void INIT copy_byte(struct writer *wr, uint32_t offs)
2502 + write_byte(wr, peek_old_byte(wr, offs));
2505 +static inline void INIT copy_bytes(struct writer *wr,
2506 + uint32_t rep0, int len)
2509 + copy_byte(wr, rep0);
2511 + } while (len != 0 && wr->buffer_pos < wr->header->dst_size);
2514 +static inline void INIT process_bit0(struct writer *wr, struct rc *rc,
2515 + struct cstate *cst, uint16_t *p,
2516 + int pos_state, uint16_t *prob,
2517 + int lc, uint32_t literal_pos_mask) {
2519 + rc_update_bit_0(rc, prob);
2520 + prob = (p + LZMA_LITERAL +
2522 + * (((get_pos(wr) & literal_pos_mask) << lc)
2523 + + (wr->previous_byte >> (8 - lc))))
2526 + if (cst->state >= LZMA_NUM_LIT_STATES) {
2527 + int match_byte = peek_old_byte(wr, cst->rep0);
2530 + uint16_t *prob_lit;
2533 + bit = match_byte & 0x100;
2534 + prob_lit = prob + 0x100 + bit + mi;
2535 + if (rc_get_bit(rc, prob_lit, &mi)) {
2542 + } while (mi < 0x100);
2544 + while (mi < 0x100) {
2545 + uint16_t *prob_lit = prob + mi;
2546 + rc_get_bit(rc, prob_lit, &mi);
2548 + write_byte(wr, mi);
2549 + if (cst->state < 4)
2551 + else if (cst->state < 10)
2557 +static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
2558 + struct cstate *cst, uint16_t *p,
2559 + int pos_state, uint16_t *prob) {
2561 + uint16_t *prob_len;
2565 + rc_update_bit_1(rc, prob);
2566 + prob = p + LZMA_IS_REP + cst->state;
2567 + if (rc_is_bit_0(rc, prob)) {
2568 + rc_update_bit_0(rc, prob);
2569 + cst->rep3 = cst->rep2;
2570 + cst->rep2 = cst->rep1;
2571 + cst->rep1 = cst->rep0;
2572 + cst->state = cst->state < LZMA_NUM_LIT_STATES ? 0 : 3;
2573 + prob = p + LZMA_LEN_CODER;
2575 + rc_update_bit_1(rc, prob);
2576 + prob = p + LZMA_IS_REP_G0 + cst->state;
2577 + if (rc_is_bit_0(rc, prob)) {
2578 + rc_update_bit_0(rc, prob);
2579 + prob = (p + LZMA_IS_REP_0_LONG
2581 + LZMA_NUM_POS_BITS_MAX) +
2583 + if (rc_is_bit_0(rc, prob)) {
2584 + rc_update_bit_0(rc, prob);
2586 + cst->state = cst->state < LZMA_NUM_LIT_STATES ?
2588 + copy_byte(wr, cst->rep0);
2591 + rc_update_bit_1(rc, prob);
2594 + uint32_t distance;
2596 + rc_update_bit_1(rc, prob);
2597 + prob = p + LZMA_IS_REP_G1 + cst->state;
2598 + if (rc_is_bit_0(rc, prob)) {
2599 + rc_update_bit_0(rc, prob);
2600 + distance = cst->rep1;
2602 + rc_update_bit_1(rc, prob);
2603 + prob = p + LZMA_IS_REP_G2 + cst->state;
2604 + if (rc_is_bit_0(rc, prob)) {
2605 + rc_update_bit_0(rc, prob);
2606 + distance = cst->rep2;
2608 + rc_update_bit_1(rc, prob);
2609 + distance = cst->rep3;
2610 + cst->rep3 = cst->rep2;
2612 + cst->rep2 = cst->rep1;
2614 + cst->rep1 = cst->rep0;
2615 + cst->rep0 = distance;
2617 + cst->state = cst->state < LZMA_NUM_LIT_STATES ? 8 : 11;
2618 + prob = p + LZMA_REP_LEN_CODER;
2621 + prob_len = prob + LZMA_LEN_CHOICE;
2622 + if (rc_is_bit_0(rc, prob_len)) {
2623 + rc_update_bit_0(rc, prob_len);
2624 + prob_len = (prob + LZMA_LEN_LOW
2626 + LZMA_LEN_NUM_LOW_BITS));
2628 + num_bits = LZMA_LEN_NUM_LOW_BITS;
2630 + rc_update_bit_1(rc, prob_len);
2631 + prob_len = prob + LZMA_LEN_CHOICE_2;
2632 + if (rc_is_bit_0(rc, prob_len)) {
2633 + rc_update_bit_0(rc, prob_len);
2634 + prob_len = (prob + LZMA_LEN_MID
2636 + LZMA_LEN_NUM_MID_BITS));
2637 + offset = 1 << LZMA_LEN_NUM_LOW_BITS;
2638 + num_bits = LZMA_LEN_NUM_MID_BITS;
2640 + rc_update_bit_1(rc, prob_len);
2641 + prob_len = prob + LZMA_LEN_HIGH;
2642 + offset = ((1 << LZMA_LEN_NUM_LOW_BITS)
2643 + + (1 << LZMA_LEN_NUM_MID_BITS));
2644 + num_bits = LZMA_LEN_NUM_HIGH_BITS;
2648 + rc_bit_tree_decode(rc, prob_len, num_bits, &len);
2651 + if (cst->state < 4) {
2654 + cst->state += LZMA_NUM_LIT_STATES;
2656 + p + LZMA_POS_SLOT +
2658 + LZMA_NUM_LEN_TO_POS_STATES ? len :
2659 + LZMA_NUM_LEN_TO_POS_STATES - 1)
2660 + << LZMA_NUM_POS_SLOT_BITS);
2661 + rc_bit_tree_decode(rc, prob,
2662 + LZMA_NUM_POS_SLOT_BITS,
2664 + if (pos_slot >= LZMA_START_POS_MODEL_INDEX) {
2666 + num_bits = (pos_slot >> 1) - 1;
2667 + cst->rep0 = 2 | (pos_slot & 1);
2668 + if (pos_slot < LZMA_END_POS_MODEL_INDEX) {
2669 + cst->rep0 <<= num_bits;
2670 + prob = p + LZMA_SPEC_POS +
2671 + cst->rep0 - pos_slot - 1;
2673 + num_bits -= LZMA_NUM_ALIGN_BITS;
2674 + while (num_bits--)
2675 + cst->rep0 = (cst->rep0 << 1) |
2676 + rc_direct_bit(rc);
2677 + prob = p + LZMA_ALIGN;
2678 + cst->rep0 <<= LZMA_NUM_ALIGN_BITS;
2679 + num_bits = LZMA_NUM_ALIGN_BITS;
2683 + while (num_bits--) {
2684 + if (rc_get_bit(rc, prob + mi, &mi))
2689 + cst->rep0 = pos_slot;
2690 + if (++(cst->rep0) == 0)
2694 + len += LZMA_MATCH_MIN_LEN;
2696 + copy_bytes(wr, cst->rep0, len);
2701 +STATIC inline int INIT unlzma(unsigned char *buf, int in_len,
2702 + int(*fill)(void*, unsigned int),
2703 + int(*flush)(void*, unsigned int),
2704 + unsigned char *output,
2706 + void(*error_fn)(char *x)
2709 + struct lzma_header header;
2711 + uint32_t pos_state_mask;
2712 + uint32_t literal_pos_mask;
2718 + struct cstate cst;
2719 + unsigned char *inbuf;
2722 + set_error_fn(error_fn);
2724 + in_len -= 4; /* Uncompressed size hack active in pre-boot
2729 + inbuf = malloc(LZMA_IOBUF_SIZE);
2731 + error("Could not allocate input bufer");
2736 + cst.rep0 = cst.rep1 = cst.rep2 = cst.rep3 = 1;
2738 + wr.header = &header;
2740 + wr.global_pos = 0;
2741 + wr.previous_byte = 0;
2742 + wr.buffer_pos = 0;
2744 + rc_init(&rc, fill, inbuf, in_len);
2746 + for (i = 0; i < sizeof(header); i++) {
2747 + if (rc.ptr >= rc.buffer_end)
2749 + ((unsigned char *)&header)[i] = *rc.ptr++;
2752 + if (header.pos >= (9 * 5 * 5))
2753 + error("bad header");
2767 + pos_state_mask = (1 << pb) - 1;
2768 + literal_pos_mask = (1 << lp) - 1;
2770 + ENDIAN_CONVERT(header.dict_size);
2771 + ENDIAN_CONVERT(header.dst_size);
2773 + if (header.dict_size == 0)
2774 + header.dict_size = 1;
2777 + wr.buffer = output;
2779 + wr.bufsize = MIN(header.dst_size, header.dict_size);
2780 + wr.buffer = large_malloc(wr.bufsize);
2782 + if (wr.buffer == NULL)
2785 + num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp));
2786 + p = (uint16_t *) large_malloc(num_probs * sizeof(*p));
2789 + num_probs = LZMA_LITERAL + (LZMA_LIT_SIZE << (lc + lp));
2790 + for (i = 0; i < num_probs; i++)
2791 + p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1;
2793 + rc_init_code(&rc);
2795 + while (get_pos(&wr) < header.dst_size) {
2796 + int pos_state = get_pos(&wr) & pos_state_mask;
2797 + uint16_t *prob = p + LZMA_IS_MATCH +
2798 + (cst.state << LZMA_NUM_POS_BITS_MAX) + pos_state;
2799 + if (rc_is_bit_0(&rc, prob))
2800 + process_bit0(&wr, &rc, &cst, p, pos_state, prob,
2801 + lc, literal_pos_mask);
2803 + process_bit1(&wr, &rc, &cst, p, pos_state, prob);
2804 + if (cst.rep0 == 0)
2810 + *posp = rc.ptr-rc.buffer;
2812 + wr.flush(wr.buffer, wr.buffer_pos);
2817 + large_free(wr.buffer);
2825 +#define decompress unlzma
2826 diff --git a/lib/zlib_inflate/inflate.h b/lib/zlib_inflate/inflate.h
2827 index df8a6c9..3d17b3d 100644
2828 --- a/lib/zlib_inflate/inflate.h
2829 +++ b/lib/zlib_inflate/inflate.h
2834 /* inflate.h -- internal inflate state definition
2835 * Copyright (C) 1995-2004 Mark Adler
2836 * For conditions of distribution and use, see copyright notice in zlib.h
2837 @@ -105,3 +108,4 @@ struct inflate_state {
2838 unsigned short work[288]; /* work area for code table building */
2839 code codes[ENOUGH]; /* space for code tables */
2842 diff --git a/lib/zlib_inflate/inftrees.h b/lib/zlib_inflate/inftrees.h
2843 index 5f5219b..b70b473 100644
2844 --- a/lib/zlib_inflate/inftrees.h
2845 +++ b/lib/zlib_inflate/inftrees.h
2850 /* inftrees.h -- header to use inftrees.c
2851 * Copyright (C) 1995-2005 Mark Adler
2852 * For conditions of distribution and use, see copyright notice in zlib.h
2853 @@ -53,3 +56,4 @@ typedef enum {
2854 extern int zlib_inflate_table (codetype type, unsigned short *lens,
2855 unsigned codes, code **table,
2856 unsigned *bits, unsigned short *work);
2858 diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
2859 index e063657..3b949a3 100644
2860 --- a/scripts/Makefile.lib
2861 +++ b/scripts/Makefile.lib
2862 @@ -186,3 +186,17 @@ quiet_cmd_gzip = GZIP $@
2863 cmd_gzip = gzip -f -9 < $< > $@
2867 +# ---------------------------------------------------------------------------
2869 +# Bzip2 does not include size in file... so we have to fake that
2870 +size_append=$(CONFIG_SHELL) $(srctree)/scripts/bin_size
2872 +quiet_cmd_bzip2 = BZIP2 $@
2873 +cmd_bzip2 = (bzip2 -9 < $< && $(size_append) $<) > $@ || (rm -f $@ ; false)
2876 +# ---------------------------------------------------------------------------
2878 +quiet_cmd_lzma = LZMA $@
2879 +cmd_lzma = (lzma -9 -c $< && $(size_append) $<) >$@ || (rm -f $@ ; false)
2880 diff --git a/scripts/bin_size b/scripts/bin_size
2881 new file mode 100644
2882 index 0000000..43e1b36
2884 +++ b/scripts/bin_size
2888 +if [ $# = 0 ] ; then
2889 + echo Usage: $0 file
2892 +size_dec=`stat -c "%s" $1`
2893 +size_hex_echo_string=`printf "%08x" $size_dec |
2894 + sed 's/\(..\)\(..\)\(..\)\(..\)/\\\\x\4\\\\x\3\\\\x\2\\\\x\1/g'`
2895 +/bin/echo -ne $size_hex_echo_string
2896 diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh
2897 index 5f3415f..3eea8f1 100644
2898 --- a/scripts/gen_initramfs_list.sh
2899 +++ b/scripts/gen_initramfs_list.sh
2901 # Released under the terms of the GNU GPL
2903 # Generate a cpio packed initramfs. It uses gen_init_cpio to generate
2904 -# the cpio archive, and gzip to pack it.
2905 +# the cpio archive, and then compresses it.
2906 # The script may also be used to generate the inputfile used for gen_init_cpio
2907 # This script assumes that gen_init_cpio is located in usr/ directory
2909 @@ -16,8 +16,8 @@ usage() {
2912 $0 [-o <file>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} ...
2913 - -o <file> Create gzipped initramfs file named <file> using
2914 - gen_init_cpio and gzip
2915 + -o <file> Create compressed initramfs file named <file> using
2916 + gen_init_cpio and compressor depending on the extension
2917 -u <uid> User ID to map to user ID 0 (root).
2918 <uid> is only meaningful if <cpio_source> is a
2919 directory. "squash" forces all files to uid 0.
2920 @@ -225,6 +225,7 @@ cpio_list=
2921 output="/dev/stdout"
2928 @@ -233,11 +234,15 @@ case "$arg" in
2929 echo "deps_initramfs := \\"
2932 - "-o") # generate gzipped cpio image named $1
2933 + "-o") # generate compressed cpio image named $1
2936 cpio_list="$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX)"
2938 + echo "$output_file" | grep -q "\.gz$" && compr="gzip -9 -f"
2939 + echo "$output_file" | grep -q "\.bz2$" && compr="bzip2 -9 -f"
2940 + echo "$output_file" | grep -q "\.lzma$" && compr="lzma -9 -f"
2941 + echo "$output_file" | grep -q "\.cpio$" && compr="cat"
2945 @@ -274,7 +279,7 @@ while [ $# -gt 0 ]; do
2949 -# If output_file is set we will generate cpio archive and gzip it
2950 +# If output_file is set we will generate cpio archive and compress it
2951 # we are carefull to delete tmp files
2952 if [ ! -z ${output_file} ]; then
2953 if [ -z ${cpio_file} ]; then
2954 @@ -287,7 +292,8 @@ if [ ! -z ${output_file} ]; then
2955 if [ "${is_cpio_compressed}" = "compressed" ]; then
2956 cat ${cpio_tfile} > ${output_file}
2958 - cat ${cpio_tfile} | gzip -f -9 - > ${output_file}
2959 + (cat ${cpio_tfile} | ${compr} - > ${output_file}) \
2960 + || (rm -f ${output_file} ; false)
2962 [ -z ${cpio_file} ] && rm ${cpio_tfile}
2964 diff --git a/usr/Kconfig b/usr/Kconfig
2965 index 86cecb5..43a3a0f 100644
2968 @@ -44,3 +44,92 @@ config INITRAMFS_ROOT_GID
2969 owned by group root in the initial ramdisk image.
2971 If you are not sure, leave it set to "0".
2974 + bool "Initial ramdisk compressed using gzip"
2976 + depends on BLK_DEV_INITRD=y
2977 + select DECOMPRESS_GZIP
2979 + Support loading of a gzip encoded initial ramdisk or cpio buffer.
2983 + bool "Initial ramdisk compressed using bzip2"
2985 + depends on BLK_DEV_INITRD=y
2986 + select DECOMPRESS_BZIP2
2988 + Support loading of a bzip2 encoded initial ramdisk or cpio buffer
2992 + bool "Initial ramdisk compressed using lzma"
2994 + depends on BLK_DEV_INITRD=y
2995 + select DECOMPRESS_LZMA
2997 + Support loading of a lzma encoded initial ramdisk or cpio buffer
3001 + prompt "Built-in initramfs compression mode"
3003 + This setting is only meaningful if the INITRAMFS_SOURCE is
3004 + set. It decides by which algorithm the INITRAMFS_SOURCE will
3006 + Several compression algorithms are available, which differ
3007 + in efficiency, compression and decompression speed.
3008 + Compression speed is only relevant when building a kernel.
3009 + Decompression speed is relevant at each boot.
3011 + If you have any problems with bzip2 or lzma compressed
3012 + initramfs, mail me (Alain Knaff) <alain@knaff.lu>.
3014 + High compression options are mostly useful for users who
3015 + are low on disk space (embedded systems), but for whom ram
3016 + size matters less.
3018 + If in doubt, select 'gzip'
3020 +config INITRAMFS_COMPRESSION_NONE
3023 + Do not compress the built-in initramfs at all. This may
3024 + sound wasteful in space, but, you should be aware that the
3025 + built-in initramfs will be compressed at a later stage
3026 + anyways along with the rest of the kernel, on those
3027 + architectures that support this.
3028 + However, not compressing the initramfs may lead to slightly
3029 + higher memory consumption during a short time at boot, while
3030 + both the cpio image and the unpacked filesystem image will
3031 + be present in memory simultaneously
3033 +config INITRAMFS_COMPRESSION_GZIP
3035 + depends on RD_GZIP
3037 + The old and tried gzip compression. Its compression ratio is
3038 + the poorest among the 3 choices; however its speed (both
3039 + compression and decompression) is the fastest.
3041 +config INITRAMFS_COMPRESSION_BZIP2
3043 + depends on RD_BZIP2
3045 + Its compression ratio and speed is intermediate.
3046 + Decompression speed is slowest among the three. The initramfs
3047 + size is about 10% smaller with bzip2, in comparison to gzip.
3048 + Bzip2 uses a large amount of memory. For modern kernels you
3049 + will need at least 8MB RAM or more for booting.
3051 +config INITRAMFS_COMPRESSION_LZMA
3053 + depends on RD_LZMA
3055 + The most recent compression algorithm.
3056 + Its ratio is best, decompression speed is between the other
3057 + two. Compression is slowest. The initramfs size is about 33%
3058 + smaller with LZMA in comparison to gzip.
3061 diff --git a/usr/Makefile b/usr/Makefile
3062 index 201f27f..b84894b 100644
3065 @@ -6,13 +6,25 @@ klibcdirs:;
3070 +suffix_$(CONFIG_INITRAMFS_COMPRESSION_NONE) =
3072 +# Gzip, but no bzip2
3073 +suffix_$(CONFIG_INITRAMFS_COMPRESSION_GZIP) = .gz
3076 +suffix_$(CONFIG_INITRAMFS_COMPRESSION_BZIP2) = .bz2
3079 +suffix_$(CONFIG_INITRAMFS_COMPRESSION_LZMA) = .lzma
3081 # Generate builtin.o based on initramfs_data.o
3082 -obj-$(CONFIG_BLK_DEV_INITRD) := initramfs_data.o
3083 +obj-$(CONFIG_BLK_DEV_INITRD) := initramfs_data$(suffix_y).o
3085 -# initramfs_data.o contains the initramfs_data.cpio.gz image.
3086 +# initramfs_data.o contains the compressed initramfs_data.cpio image.
3087 # The image is included using .incbin, a dependency which is not
3088 # tracked automatically.
3089 -$(obj)/initramfs_data.o: $(obj)/initramfs_data.cpio.gz FORCE
3090 +$(obj)/initramfs_data$(suffix_y).o: $(obj)/initramfs_data.cpio$(suffix_y) FORCE
3093 # Generate the initramfs cpio archive
3094 @@ -25,28 +37,28 @@ ramfs-args := \
3095 $(if $(CONFIG_INITRAMFS_ROOT_UID), -u $(CONFIG_INITRAMFS_ROOT_UID)) \
3096 $(if $(CONFIG_INITRAMFS_ROOT_GID), -g $(CONFIG_INITRAMFS_ROOT_GID))
3098 -# .initramfs_data.cpio.gz.d is used to identify all files included
3099 +# .initramfs_data.cpio.d is used to identify all files included
3100 # in initramfs and to detect if any files are added/removed.
3101 # Removed files are identified by directory timestamp being updated
3102 # The dependency list is generated by gen_initramfs.sh -l
3103 -ifneq ($(wildcard $(obj)/.initramfs_data.cpio.gz.d),)
3104 - include $(obj)/.initramfs_data.cpio.gz.d
3105 +ifneq ($(wildcard $(obj)/.initramfs_data.cpio.d),)
3106 + include $(obj)/.initramfs_data.cpio.d
3109 quiet_cmd_initfs = GEN $@
3110 cmd_initfs = $(initramfs) -o $@ $(ramfs-args) $(ramfs-input)
3112 -targets := initramfs_data.cpio.gz
3113 +targets := initramfs_data.cpio.gz initramfs_data.cpio.bz2 initramfs_data.cpio.lzma initramfs_data.cpio
3114 # do not try to update files included in initramfs
3115 $(deps_initramfs): ;
3117 $(deps_initramfs): klibcdirs
3118 -# We rebuild initramfs_data.cpio.gz if:
3119 -# 1) Any included file is newer then initramfs_data.cpio.gz
3120 +# We rebuild initramfs_data.cpio if:
3121 +# 1) Any included file is newer then initramfs_data.cpio
3122 # 2) There are changes in which files are included (added or deleted)
3123 -# 3) If gen_init_cpio are newer than initramfs_data.cpio.gz
3124 +# 3) If gen_init_cpio are newer than initramfs_data.cpio
3125 # 4) arguments to gen_initramfs.sh changes
3126 -$(obj)/initramfs_data.cpio.gz: $(obj)/gen_init_cpio $(deps_initramfs) klibcdirs
3127 - $(Q)$(initramfs) -l $(ramfs-input) > $(obj)/.initramfs_data.cpio.gz.d
3128 +$(obj)/initramfs_data.cpio$(suffix_y): $(obj)/gen_init_cpio $(deps_initramfs) klibcdirs
3129 + $(Q)$(initramfs) -l $(ramfs-input) > $(obj)/.initramfs_data.cpio.d
3130 $(call if_changed,initfs)
3132 diff --git a/usr/initramfs_data.S b/usr/initramfs_data.S
3133 index c2e1ad4..7c6973d 100644
3134 --- a/usr/initramfs_data.S
3135 +++ b/usr/initramfs_data.S
3136 @@ -26,5 +26,5 @@ SECTIONS
3139 .section .init.ramfs,"a"
3140 -.incbin "usr/initramfs_data.cpio.gz"
3141 +.incbin "usr/initramfs_data.cpio"
3143 diff --git a/usr/initramfs_data.bz2.S b/usr/initramfs_data.bz2.S
3144 new file mode 100644
3145 index 0000000..bc54d09
3147 +++ b/usr/initramfs_data.bz2.S
3150 + initramfs_data includes the compressed binary that is the
3151 + filesystem used for early user space.
3152 + Note: Older versions of "as" (prior to binutils 2.11.90.0.23
3153 + released on 2001-07-14) dit not support .incbin.
3154 + If you are forced to use older binutils than that then the
3155 + following trick can be applied to create the resulting binary:
3158 + ld -m elf_i386 --format binary --oformat elf32-i386 -r \
3159 + -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o
3160 + ld -m elf_i386 -r -o built-in.o initramfs_data.o
3162 + initramfs_data.scr looks like this:
3165 + .init.ramfs : { *(.data) }
3168 + The above example is for i386 - the parameters vary from architectures.
3169 + Eventually look up LDFLAGS_BLOB in an older version of the
3170 + arch/$(ARCH)/Makefile to see the flags used before .incbin was introduced.
3172 + Using .incbin has the advantage over ld that the correct flags are set
3173 + in the ELF header, as required by certain architectures.
3176 +.section .init.ramfs,"a"
3177 +.incbin "usr/initramfs_data.cpio.bz2"
3178 diff --git a/usr/initramfs_data.gz.S b/usr/initramfs_data.gz.S
3179 new file mode 100644
3180 index 0000000..890c8dd
3182 +++ b/usr/initramfs_data.gz.S
3185 + initramfs_data includes the compressed binary that is the
3186 + filesystem used for early user space.
3187 + Note: Older versions of "as" (prior to binutils 2.11.90.0.23
3188 + released on 2001-07-14) dit not support .incbin.
3189 + If you are forced to use older binutils than that then the
3190 + following trick can be applied to create the resulting binary:
3193 + ld -m elf_i386 --format binary --oformat elf32-i386 -r \
3194 + -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o
3195 + ld -m elf_i386 -r -o built-in.o initramfs_data.o
3197 + initramfs_data.scr looks like this:
3200 + .init.ramfs : { *(.data) }
3203 + The above example is for i386 - the parameters vary from architectures.
3204 + Eventually look up LDFLAGS_BLOB in an older version of the
3205 + arch/$(ARCH)/Makefile to see the flags used before .incbin was introduced.
3207 + Using .incbin has the advantage over ld that the correct flags are set
3208 + in the ELF header, as required by certain architectures.
3211 +.section .init.ramfs,"a"
3212 +.incbin "usr/initramfs_data.cpio.gz"
3213 diff --git a/usr/initramfs_data.lzma.S b/usr/initramfs_data.lzma.S
3214 new file mode 100644
3215 index 0000000..e11469e
3217 +++ b/usr/initramfs_data.lzma.S
3220 + initramfs_data includes the compressed binary that is the
3221 + filesystem used for early user space.
3222 + Note: Older versions of "as" (prior to binutils 2.11.90.0.23
3223 + released on 2001-07-14) dit not support .incbin.
3224 + If you are forced to use older binutils than that then the
3225 + following trick can be applied to create the resulting binary:
3228 + ld -m elf_i386 --format binary --oformat elf32-i386 -r \
3229 + -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o
3230 + ld -m elf_i386 -r -o built-in.o initramfs_data.o
3232 + initramfs_data.scr looks like this:
3235 + .init.ramfs : { *(.data) }
3238 + The above example is for i386 - the parameters vary from architectures.
3239 + Eventually look up LDFLAGS_BLOB in an older version of the
3240 + arch/$(ARCH)/Makefile to see the flags used before .incbin was introduced.
3242 + Using .incbin has the advantage over ld that the correct flags are set
3243 + in the ELF header, as required by certain architectures.
3246 +.section .init.ramfs,"a"
3247 +.incbin "usr/initramfs_data.cpio.lzma"
3249 To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
3250 the body of a message to majordomo@vger.kernel.org
3251 More majordomo info at http://vger.kernel.org/majordomo-info.html
3252 Please read the FAQ at http://www.tux.org/lkml/