summaryrefslogtreecommitdiff
path: root/init/initramfs.c
diff options
context:
space:
mode:
authorAlain Knaff <alain@knaff.lu>2009-01-05 00:46:17 +0300
committerH. Peter Anvin <hpa@zytor.com>2009-01-05 02:53:35 +0300
commit30d65dbfe3add7f010a075991dc0bfeaebb7d9e1 (patch)
treec60ce6748eea43d1e74d96ef03990b1e23f33b1d /init/initramfs.c
parentbc22c17e12c130dc929218a95aa347e0f3fd05dc (diff)
downloadlinux-30d65dbfe3add7f010a075991dc0bfeaebb7d9e1.tar.xz
bzip2/lzma: config and initramfs support for bzip2/lzma decompression
Impact: New code for initramfs decompression, new features This is the second part of the bzip2/lzma patch The bzip patch is based on an idea by Christian Ludwig, includes support for compressing the kernel with bzip2 or lzma rather than gzip. Both compressors give smaller sizes than gzip. Lzma's decompresses faster than bzip2. It also supports ramdisks and initramfs' compressed using these two compressors. The functionality has been successfully used for a couple of years by the udpcast project This version applies to "tip" kernel 2.6.28 This part contains: - support for new compressions (bzip2 and lzma) in initramfs and old-style ramdisk - config dialog for kernel compression (but new kernel compressions not yet supported) Signed-off-by: Alain Knaff <alain@knaff.lu> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'init/initramfs.c')
-rw-r--r--init/initramfs.c123
1 files changed, 42 insertions, 81 deletions
diff --git a/init/initramfs.c b/init/initramfs.c
index 4f5ba75aaa7c..40bd4fb95788 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -389,11 +389,14 @@ static int __init write_buffer(char *buf, unsigned len)
return len - count;
}
-static void __init flush_buffer(char *buf, unsigned len)
+
+static int __init flush_buffer(void *bufv, unsigned len)
{
+ char *buf = (char *) bufv;
int written;
+ int origLen = len;
if (message)
- return;
+ return -1;
while ((written = write_buffer(buf, len)) < len && !message) {
char c = buf[written];
if (c == '0') {
@@ -407,73 +410,14 @@ static void __init flush_buffer(char *buf, unsigned len)
} else
error("junk in compressed archive");
}
+ return origLen;
}
-/*
- * gzip declarations
- */
-
-#define OF(args) args
-
-#ifndef memzero
-#define memzero(s, n) memset ((s), 0, (n))
-#endif
-
-typedef unsigned char uch;
-typedef unsigned short ush;
-typedef unsigned long ulg;
-
-#define WSIZE 0x8000 /* window size--must be a power of two, and */
- /* at least 32K for zip's deflate method */
-
-static uch *inbuf;
-static uch *window;
-
-static unsigned insize; /* valid bytes in inbuf */
-static unsigned inptr; /* index of next byte to be processed in inbuf */
-static unsigned outcnt; /* bytes in output buffer */
-static long bytes_out;
-
-#define get_byte() (inptr < insize ? inbuf[inptr++] : -1)
-
-/* Diagnostic functions (stubbed out) */
-#define Assert(cond,msg)
-#define Trace(x)
-#define Tracev(x)
-#define Tracevv(x)
-#define Tracec(c,x)
-#define Tracecv(c,x)
-
-#define STATIC static
-#define INIT __init
-
-static void __init flush_window(void);
-static void __init error(char *m);
-
-#define NO_INFLATE_MALLOC
+static unsigned my_inptr; /* index of next byte to be processed in inbuf */
-#include "../lib/inflate.c"
-
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-static void __init flush_window(void)
-{
- ulg c = crc; /* temporary variable */
- unsigned n;
- uch *in, ch;
-
- flush_buffer(window, outcnt);
- in = window;
- for (n = 0; n < outcnt; n++) {
- ch = *in++;
- c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
- }
- crc = c;
- bytes_out += (ulg)outcnt;
- outcnt = 0;
-}
+#include <linux/decompress/bunzip2.h>
+#include <linux/decompress/unlzma.h>
+#include <linux/decompress/inflate.h>
static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
{
@@ -482,9 +426,10 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
header_buf = kmalloc(110, GFP_KERNEL);
symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL);
- window = kmalloc(WSIZE, GFP_KERNEL);
- if (!window || !header_buf || !symlink_buf || !name_buf)
+
+ if (!header_buf || !symlink_buf || !name_buf)
panic("can't allocate buffers");
+
state = Start;
this_header = 0;
message = NULL;
@@ -504,22 +449,38 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
continue;
}
this_header = 0;
- insize = len;
- inbuf = buf;
- inptr = 0;
- outcnt = 0; /* bytes in output buffer */
- bytes_out = 0;
- crc = (ulg)0xffffffffL; /* shift register contents */
- makecrc();
- gunzip();
+ if (!gunzip(buf, len, NULL, flush_buffer, NULL,
+ &my_inptr, error) &&
+ message == NULL)
+ goto ok;
+
+#ifdef CONFIG_RD_BZIP2
+ message = NULL; /* Zero out message, or else cpio will
+ think an error has already occured */
+ if (!bunzip2(buf, len, NULL, flush_buffer, NULL,
+ &my_inptr, error) &&
+ message == NULL) {
+ goto ok;
+ }
+#endif
+
+#ifdef CONFIG_RD_LZMA
+ message = NULL; /* Zero out message, or else cpio will
+ think an error has already occured */
+ if (!unlzma(buf, len, NULL, flush_buffer, NULL,
+ &my_inptr, error) &&
+ message == NULL) {
+ goto ok;
+ }
+#endif
+ok:
if (state != Reset)
- error("junk in gzipped archive");
- this_header = saved_offset + inptr;
- buf += inptr;
- len -= inptr;
+ error("junk in compressed archive");
+ this_header = saved_offset + my_inptr;
+ buf += my_inptr;
+ len -= my_inptr;
}
dir_utime();
- kfree(window);
kfree(name_buf);
kfree(symlink_buf);
kfree(header_buf);