summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--target/linux/brcm63xx/patches-2.6.27/500-lzma_initramfs.patch125
1 files changed, 125 insertions, 0 deletions
diff --git a/target/linux/brcm63xx/patches-2.6.27/500-lzma_initramfs.patch b/target/linux/brcm63xx/patches-2.6.27/500-lzma_initramfs.patch
new file mode 100644
index 0000000..ad30e94
--- /dev/null
+++ b/target/linux/brcm63xx/patches-2.6.27/500-lzma_initramfs.patch
@@ -0,0 +1,125 @@
+--- a/init/initramfs.c
++++ b/init/initramfs.c
+@@ -6,6 +6,7 @@
+ #include <linux/delay.h>
+ #include <linux/string.h>
+ #include <linux/syscalls.h>
++#include <linux/vmalloc.h>
+
+ static __initdata char *message;
+ static void __init error(char *x)
+@@ -423,6 +424,69 @@ static void __init flush_window(void)
+ outcnt = 0;
+ }
+
++#include <linux/LzmaDecode.h>
++static int __init lzma_unzip(void)
++{
++ unsigned int i; /* temp value */
++ unsigned int lc; /* literal context bits */
++ unsigned int lp; /* literal pos state bits */
++ unsigned int pb; /* pos state bits */
++ unsigned int osize; /* uncompressed size */
++ unsigned char *workspace;
++ unsigned char* outputbuffer;
++ unsigned int outsizeProcessed = 0;
++ int workspace_size;
++ int res;
++
++ // lzma args
++ i = get_byte();
++ lc = i % 9, i = i / 9;
++ lp = i % 5, pb = i / 5;
++
++ // skip dictionary size
++ for (i = 0; i < 4; i++)
++ get_byte();
++
++ /* read the lower half of uncompressed size in the header */
++ osize = ((unsigned int)get_byte()) +
++ ((unsigned int)get_byte() << 8) +
++ ((unsigned int)get_byte() << 16) +
++ ((unsigned int)get_byte() << 24);
++
++ /* skip rest of the header (upper half of uncompressed size) */
++ for (i = 0; i < 4; i++)
++ get_byte();
++
++ workspace_size = ((LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp))) * sizeof(CProb)) + 100;
++ printk( KERN_NOTICE "initramfs: LZMA lc=%d,lp=%d,pb=%d,origSize=%d\n",
++ lc,lp,pb,osize);
++ outputbuffer = vmalloc(osize);
++ if (outputbuffer == 0) {
++ printk(KERN_ERR "initramfs: Couldn't allocate lzma output buffer\n");
++ return -1;
++ }
++
++ workspace = vmalloc(workspace_size);
++ if (workspace == NULL) {
++ printk(KERN_ERR "initramfs: Couldn't allocate lzma workspace\n");
++ return -1;
++ }
++
++ res = LzmaDecode(workspace, workspace_size, lc, lp, pb, inbuf + inptr, insize - inptr, outputbuffer, osize, &outsizeProcessed);
++ if( res != 0 ) {
++ panic( KERN_ERR "initramfs: Lzma decode failure\n");
++ return -1;
++ }
++
++ flush_buffer(outputbuffer, outsizeProcessed);
++ inptr = insize;
++
++ vfree(outputbuffer);
++ vfree(workspace);
++ state = Reset;
++ return 0;
++}
++
+ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
+ {
+ int written;
+@@ -457,12 +521,28 @@ static char * __init unpack_to_rootfs(ch
+ inptr = 0;
+ outcnt = 0; /* bytes in output buffer */
+ bytes_out = 0;
+- crc = (ulg)0xffffffffL; /* shift register contents */
+- makecrc();
+- gunzip();
+- if (state != Reset)
++ if( inbuf[0] == 037 && ((inbuf[1] == 0213) || (inbuf[1] == 0236)))
++ {
++ printk( KERN_NOTICE "detected gzip initramfs\n");
++ crc = (ulg)0xffffffffL; /* shift register contents */
++ makecrc();
++ gunzip();
++ if (state != Reset)
+ error("junk in gzipped archive");
+- this_header = saved_offset + inptr;
++ }
++ else if(!memcmp(inbuf+1, "\x00\x00\x80\x00", 4)) /* FIXME: hardcoded dictionary size */
++ {
++ printk( KERN_NOTICE "detected lzma initramfs\n");
++ lzma_unzip();
++ }
++ else
++ {
++ // skip forward ?
++ crc = (ulg)0xffffffffL; /* shift register contents */
++ makecrc();
++ gunzip();
++ }
++ this_header = saved_offset + inptr;
+ buf += inptr;
+ len -= inptr;
+ }
+--- a/scripts/gen_initramfs_list.sh
++++ b/scripts/gen_initramfs_list.sh
+@@ -287,7 +287,7 @@ if [ ! -z ${output_file} ]; then
+ if [ "${is_cpio_compressed}" = "compressed" ]; then
+ cat ${cpio_tfile} > ${output_file}
+ else
+- cat ${cpio_tfile} | gzip -f -9 - > ${output_file}
++ lzma e -lc1 -lp2 -pb2 ${cpio_tfile} ${output_file}
+ fi
+ [ -z ${cpio_file} ] && rm ${cpio_tfile}
+ fi