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