dc49e1206fea02b8afd66dec5336bb1478aaaf09
[openwrt/svn-archive/archive.git] / target / linux / brcm47xx / patches-2.6.28 / 500-lzma_initramfs.patch
1 --- a/init/initramfs.c
2 +++ b/init/initramfs.c
3 @@ -475,6 +475,69 @@ static void __init flush_window(void)
4 outcnt = 0;
5 }
6
7 +#include <linux/LzmaDecode.h>
8 +static int __init lzma_unzip(void)
9 +{
10 + unsigned int i; /* temp value */
11 + unsigned int lc; /* literal context bits */
12 + unsigned int lp; /* literal pos state bits */
13 + unsigned int pb; /* pos state bits */
14 + unsigned int osize; /* uncompressed size */
15 + unsigned char *workspace;
16 + unsigned char* outputbuffer;
17 + unsigned int outsizeProcessed = 0;
18 + int workspace_size;
19 + int res;
20 +
21 + // lzma args
22 + i = get_byte();
23 + lc = i % 9, i = i / 9;
24 + lp = i % 5, pb = i / 5;
25 +
26 + // skip dictionary size
27 + for (i = 0; i < 4; i++)
28 + get_byte();
29 +
30 + /* read the lower half of uncompressed size in the header */
31 + osize = ((unsigned int)get_byte()) +
32 + ((unsigned int)get_byte() << 8) +
33 + ((unsigned int)get_byte() << 16) +
34 + ((unsigned int)get_byte() << 24);
35 +
36 + /* skip rest of the header (upper half of uncompressed size) */
37 + for (i = 0; i < 4; i++)
38 + get_byte();
39 +
40 + workspace_size = ((LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp))) * sizeof(CProb)) + 100;
41 + printk( KERN_NOTICE "initramfs: LZMA lc=%d,lp=%d,pb=%d,origSize=%d\n",
42 + lc,lp,pb,osize);
43 + outputbuffer = kmalloc(osize, GFP_KERNEL);
44 + if (outputbuffer == 0) {
45 + printk(KERN_ERR "initramfs: Couldn't allocate lzma output buffer\n");
46 + return -1;
47 + }
48 +
49 + workspace = kmalloc(workspace_size, GFP_KERNEL);
50 + if (workspace == NULL) {
51 + printk(KERN_ERR "initramfs: Couldn't allocate lzma workspace\n");
52 + return -1;
53 + }
54 +
55 + res = LzmaDecode(workspace, workspace_size, lc, lp, pb, inbuf + inptr, insize - inptr, outputbuffer, osize, &outsizeProcessed);
56 + if( res != 0 ) {
57 + panic( KERN_ERR "initramfs: Lzma decode failure\n");
58 + return -1;
59 + }
60 +
61 + flush_buffer(outputbuffer, outsizeProcessed);
62 + inptr = insize;
63 +
64 + kfree(outputbuffer);
65 + kfree(workspace);
66 + state = Reset;
67 + return 0;
68 +}
69 +
70 static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
71 {
72 int written;
73 @@ -509,12 +572,28 @@ static char * __init unpack_to_rootfs(ch
74 inptr = 0;
75 outcnt = 0; /* bytes in output buffer */
76 bytes_out = 0;
77 - crc = (ulg)0xffffffffL; /* shift register contents */
78 - makecrc();
79 - gunzip();
80 - if (state != Reset)
81 + if( inbuf[0] == 037 && ((inbuf[1] == 0213) || (inbuf[1] == 0236)))
82 + {
83 + printk( KERN_NOTICE "detected gzip initramfs\n");
84 + crc = (ulg)0xffffffffL; /* shift register contents */
85 + makecrc();
86 + gunzip();
87 + if (state != Reset)
88 error("junk in gzipped archive");
89 - this_header = saved_offset + inptr;
90 + }
91 + else if(!memcmp(inbuf+1, "\x00\x00\x80\x00", 4)) /* FIXME: hardcoded dictionary size */
92 + {
93 + printk( KERN_NOTICE "detected lzma initramfs\n");
94 + lzma_unzip();
95 + }
96 + else
97 + {
98 + // skip forward ?
99 + crc = (ulg)0xffffffffL; /* shift register contents */
100 + makecrc();
101 + gunzip();
102 + }
103 + this_header = saved_offset + inptr;
104 buf += inptr;
105 len -= inptr;
106 }
107 --- a/scripts/gen_initramfs_list.sh
108 +++ b/scripts/gen_initramfs_list.sh
109 @@ -287,7 +287,7 @@ if [ ! -z ${output_file} ]; then
110 if [ "${is_cpio_compressed}" = "compressed" ]; then
111 cat ${cpio_tfile} > ${output_file}
112 else
113 - cat ${cpio_tfile} | gzip -f -9 - > ${output_file}
114 + lzma e -lc1 -lp2 -pb2 ${cpio_tfile} ${output_file}
115 fi
116 [ -z ${cpio_file} ] && rm ${cpio_tfile}
117 fi