diff options
Diffstat (limited to 'target/linux/brcm63xx')
-rw-r--r-- | target/linux/brcm63xx/patches-2.6.27/500-lzma_initramfs.patch | 125 |
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 0000000000..ad30e9436a --- /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 |