From 9d2522748fe6b68a376b845fd1d8db45b50d3232 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Mon, 6 Jul 2009 11:28:34 +0000
Subject: add bcm47xx lzma initramfs patch which is useful to workaround some
 CFE limitations when ramdisk kernels are too big

SVN-Revision: 16709
---
 .../patches-2.6.27/500-lzma_initramfs.patch        | 125 +++++++++++++++++++++
 1 file changed, 125 insertions(+)
 create mode 100644 target/linux/brcm63xx/patches-2.6.27/500-lzma_initramfs.patch

(limited to 'target/linux')

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
-- 
cgit v1.2.3