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