From: Florian Fainelli Date: Fri, 24 Apr 2009 12:55:28 +0000 (+0000) Subject: [rdc] add support for 2.6.28 and use it as the default kernel version, tested on... X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fsvn-archive%2Farchive.git;a=commitdiff_plain;hb=8c141b1209fe4aa8f9d7aec38cf3d1e2eee5b46f [rdc] add support for 2.6.28 and use it as the default kernel version, tested on Airlink AR525W and RDC8610 eval board SVN-Revision: 15382 --- diff --git a/target/linux/rdc/Makefile b/target/linux/rdc/Makefile index 1e2083e9ae..91cff88856 100644 --- a/target/linux/rdc/Makefile +++ b/target/linux/rdc/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2006-2008 OpenWrt.org +# Copyright (C) 2006-2009 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. @@ -12,7 +12,7 @@ BOARDNAME:=RDC 321x FEATURES:=squashfs jffs2 pci usb CFLAGS:=-Os -pipe -march=i486 -funit-at-a-time -LINUX_VERSION:=2.6.24.7 +LINUX_VERSION:=2.6.28.9 include $(INCLUDE_DIR)/target.mk diff --git a/target/linux/rdc/base-files/etc/config/network b/target/linux/rdc/base-files/etc/config/network new file mode 100644 index 0000000000..44c57940e2 --- /dev/null +++ b/target/linux/rdc/base-files/etc/config/network @@ -0,0 +1,18 @@ +# Copyright (C) 2009 OpenWrt.org + +config interface loopback + option ifname lo + option proto static + option ipaddr 127.0.0.1 + option netmask 255.0.0.0 + +config interface lan + option ifname eth1 + option type bridge + option proto static + option ipaddr 192.168.1.1 + option netmask 255.255.255.0 + +config interface wan + option ifname eth0 + option proto dhcp diff --git a/target/linux/rdc/config-2.6.28 b/target/linux/rdc/config-2.6.28 new file mode 100644 index 0000000000..509b0ccd01 --- /dev/null +++ b/target/linux/rdc/config-2.6.28 @@ -0,0 +1,341 @@ +# CONFIG_4KSTACKS is not set +# CONFIG_60XX_WDT is not set +# CONFIG_64BIT is not set +# CONFIG_8139TOO is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_AGP is not set +# CONFIG_ALIM1535_WDT is not set +CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig" +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_ARCH_HAS_CPU_RELAX=y +CONFIG_ARCH_HAS_DEFAULT_IDLE=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +# CONFIG_AUDIT_ARCH is not set +CONFIG_BASE_SMALL=0 +# CONFIG_BINFMT_AOUT is not set +CONFIG_BITREVERSE=y +CONFIG_BOUNCE=y +CONFIG_CLASSIC_RCU=y +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_CMDLINE="console=ttyS0,38400 init=/etc/preinit" +CONFIG_CMDLINE_BOOL=y +# CONFIG_CMDLINE_OVERRIDE is not set +# CONFIG_COMPAT_VDSO is not set +# CONFIG_CPU5_WDT is not set +# CONFIG_CPU_FREQ is not set +CONFIG_CPU_SUP_AMD=y +CONFIG_CPU_SUP_CENTAUR_32=y +CONFIG_CPU_SUP_CYRIX_32=y +CONFIG_CPU_SUP_INTEL=y +CONFIG_CPU_SUP_TRANSMETA_32=y +CONFIG_CPU_SUP_UMC_32=y +# CONFIG_CRYPTO_AES_586 is not set +# CONFIG_CRYPTO_CRC32C_INTEL is not set +# CONFIG_CRYPTO_SALSA20_586 is not set +# CONFIG_CRYPTO_TWOFISH_586 is not set +# CONFIG_CS5535_GPIO is not set +# CONFIG_DCDBAS is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_DEFAULT_IO_DELAY_TYPE=0 +# CONFIG_DELL_RBU is not set +CONFIG_DEVPORT=y +CONFIG_DMI=y +CONFIG_DMIID=y +CONFIG_DOUBLEFAULT=y +CONFIG_EARLY_PRINTK=y +# CONFIG_EARLY_PRINTK_DBGP is not set +# CONFIG_EDAC is not set +# CONFIG_EDD is not set +# CONFIG_EUROTECH_WDT is not set +CONFIG_FAST_CMPXCHG_LOCAL=y +CONFIG_FIRMWARE_MEMMAP=y +# CONFIG_FIXED_PHY is not set +CONFIG_FIX_EARLYCON_MEM=y +# CONFIG_FREEZER is not set +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_CMOS_UPDATE=y +# CONFIG_GENERIC_CPU is not set +CONFIG_GENERIC_FIND_FIRST_BIT=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_ISA_DMA=y +# CONFIG_GENERIC_TIME_VSYSCALL is not set +# CONFIG_GEN_RTC is not set +# CONFIG_HANGCHECK_TIMER is not set +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAVE_AOUT=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_ATOMIC_IOMAP=y +# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_KVM=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_HAVE_OPROFILE=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y +# CONFIG_HIGHMEM4G is not set +# CONFIG_HIGHMEM64G is not set +# CONFIG_HIGH_RES_TIMERS is not set +# CONFIG_HPET_TIMER is not set +# CONFIG_HP_WATCHDOG is not set +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_AMD is not set +# CONFIG_HW_RANDOM_GEODE is not set +# CONFIG_HW_RANDOM_INTEL is not set +# CONFIG_HW_RANDOM_VIA is not set +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_I2C is not set +# CONFIG_I6300ESB_WDT is not set +# CONFIG_I8K is not set +# CONFIG_IB700_WDT is not set +# CONFIG_IBMASR is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +CONFIG_ICPLUS_PHY=y +# CONFIG_IDE is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_IOMMU_HELPER is not set +CONFIG_IOSCHED_CFQ=y +# CONFIG_IOSCHED_DEADLINE is not set +CONFIG_IO_DELAY_0X80=y +# CONFIG_IO_DELAY_0XED is not set +# CONFIG_IO_DELAY_NONE is not set +CONFIG_IO_DELAY_TYPE_0X80=0 +CONFIG_IO_DELAY_TYPE_0XED=1 +CONFIG_IO_DELAY_TYPE_NONE=3 +CONFIG_IO_DELAY_TYPE_UDELAY=2 +# CONFIG_IO_DELAY_UDELAY is not set +# CONFIG_ISA is not set +CONFIG_ISA_DMA_API=y +# CONFIG_ISCSI_IBFT_FIND is not set +# CONFIG_IT8712F_WDT is not set +# CONFIG_IT87_WDT is not set +# CONFIG_ITCO_WDT is not set +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_GZIP is not set +CONFIG_KERNEL_LZMA=y +CONFIG_KEXEC=y +CONFIG_KMOD=y +CONFIG_KTIME_SCALAR=y +# CONFIG_KVM is not set +CONFIG_LBD=y +# CONFIG_LEDS_ALIX is not set +# CONFIG_LGUEST is not set +CONFIG_LSF=y +# CONFIG_M386 is not set +CONFIG_M486=y +# CONFIG_M586 is not set +# CONFIG_M586MMX is not set +# CONFIG_M586TSC is not set +# CONFIG_M686 is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_MACINTOSH_DRIVERS is not set +CONFIG_MATH_EMULATION=y +# CONFIG_MCA is not set +# CONFIG_MCORE2 is not set +# CONFIG_MCRUSOE is not set +# CONFIG_MCYRIXIII is not set +# CONFIG_MEFFICEON is not set +# CONFIG_MEMTEST is not set +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MGEODEGX1 is not set +# CONFIG_MGEODE_LX is not set +# CONFIG_MICROCODE is not set +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MPENTIUM4 is not set +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +# CONFIG_MPSC is not set +CONFIG_MTD=y +# CONFIG_MTD_ABSENT is not set +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_MTD_BLOCK2MTD is not set +CONFIG_MTD_CFI=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_CHAR=y +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_NETSC520 is not set +# CONFIG_MTD_ONENAND is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PLATRAM is not set +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_RAM is not set +CONFIG_MTD_RDC3210=y +CONFIG_MTD_RDC3210_ALLOW_JFFS2=y +CONFIG_MTD_RDC3210_BUSWIDTH=2 +# CONFIG_MTD_RDC3210_FACTORY_PRESENT is not set +CONFIG_MTD_RDC3210_SIZE=0x400000 +# CONFIG_MTD_RDC3210_STATIC_MAP is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_SC520CDP is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_TS5500 is not set +# CONFIG_MTRR is not set +# CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set +# CONFIG_MWINCHIP3D is not set +# CONFIG_MWINCHIPC6 is not set +# CONFIG_NATSEMI is not set +# CONFIG_NF_DEFRAG_IPV4 is not set +CONFIG_NOHIGHMEM=y +# CONFIG_NSC_GPIO is not set +CONFIG_NVRAM=y +# CONFIG_OLPC is not set +# CONFIG_OPTIMIZE_INLINING is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PARAVIRT_GUEST is not set +# CONFIG_PC8736x_GPIO is not set +# CONFIG_PC87413_WDT is not set +CONFIG_PCI=y +# CONFIG_PCIEPORTBUS is not set +CONFIG_PCI_BIOS=y +CONFIG_PCI_DIRECT=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_GOANY=y +# CONFIG_PCI_GOBIOS is not set +# CONFIG_PCI_GODIRECT is not set +# CONFIG_PCI_GOMMCONFIG is not set +# CONFIG_PCI_GOOLPC is not set +# CONFIG_PCSPKR_PLATFORM is not set +CONFIG_PHYLIB=y +CONFIG_PHYSICAL_ALIGN=0x100000 +CONFIG_PHYSICAL_START=0x100000 +# CONFIG_PHYS_ADDR_T_64BIT is not set +# CONFIG_PROCESSOR_SELECT is not set +# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set +# CONFIG_R6040 is not set +CONFIG_RDC321X_WDT=y +# CONFIG_RD_BZIP2 is not set +CONFIG_RD_GZIP=y +# CONFIG_RD_LZMA is not set +# CONFIG_RELOCATABLE is not set +# CONFIG_RTC is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +# CONFIG_SBC7240_WDT is not set +# CONFIG_SBC8360_WDT is not set +# CONFIG_SBC_EPX_C3_WATCHDOG is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_SCHED_HRTICK is not set +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +# CONFIG_SCSI_DMA is not set +# CONFIG_SCx200 is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SMP is not set +# CONFIG_SMSC37B787_WDT is not set +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_SPARSEMEM_STATIC=y +CONFIG_SSB_POSSIBLE=y +# CONFIG_STRICT_DEVMEM is not set +# CONFIG_SYSPROF_TRACER is not set +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_TELCLOCK is not set +# CONFIG_TOSHIBA is not set +CONFIG_UID16=y +CONFIG_USB_SUPPORT=y +# CONFIG_VGASTATE is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIRTIO_BALLOON is not set +# CONFIG_VIRTIO_PCI is not set +CONFIG_VIRTUALIZATION=y +# CONFIG_VM86 is not set +# CONFIG_VMSPLIT_2G_OPT is not set +# CONFIG_VMSPLIT_3G_OPT is not set +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_W83697UG_WDT is not set +# CONFIG_WAFER_WDT is not set +CONFIG_X86=y +CONFIG_X86_32=y +# CONFIG_X86_64 is not set +CONFIG_X86_ALIGNMENT_16=y +CONFIG_X86_BIOS_REBOOT=y +CONFIG_X86_BSWAP=y +# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set +CONFIG_X86_CMPXCHG=y +CONFIG_X86_CPU=y +CONFIG_X86_CPUID=y +# CONFIG_X86_ELAN is not set +CONFIG_X86_F00F_BUG=y +# CONFIG_X86_GENERIC is not set +# CONFIG_X86_GENERICARCH is not set +CONFIG_X86_INVLPG=y +CONFIG_X86_L1_CACHE_SHIFT=4 +# CONFIG_X86_MCE is not set +CONFIG_X86_MINIMUM_CPU_FAMILY=4 +CONFIG_X86_MSR=y +# CONFIG_X86_PAE is not set +CONFIG_X86_PC=y +CONFIG_X86_POPAD_OK=y +CONFIG_X86_PPRO_FENCE=y +CONFIG_X86_RDC321X=y +CONFIG_X86_REBOOTFIXUPS=y +CONFIG_X86_RESERVE_LOW_64K=y +# CONFIG_X86_UP_APIC is not set +CONFIG_X86_VERBOSE_BOOTUP=y +# CONFIG_X86_VOYAGER is not set +# CONFIG_X86_VSMP is not set +CONFIG_X86_WP_WORKS_OK=y +CONFIG_X86_XADD=y +# CONFIG_ZONE_DMA32 is not set diff --git a/target/linux/rdc/files-2.6.28/drivers/mtd/maps/imghdr.h b/target/linux/rdc/files-2.6.28/drivers/mtd/maps/imghdr.h new file mode 100644 index 0000000000..7232b70615 --- /dev/null +++ b/target/linux/rdc/files-2.6.28/drivers/mtd/maps/imghdr.h @@ -0,0 +1,25 @@ +#ifndef GT_IMGHDR_H +#define GT_IMGHDR_H + +#define GTIMG_MAGIC "GMTK" + +/* Product ID */ +#define PID_RTL_AIRGO 1 +#define PID_RTL_RALINK 2 +#define PID_RDC_AIRGO 3 +#define PID_RDC_RALINK 5 /* White Lable */ + +/* Gemtek */ +typedef struct +{ + u8 magic[4]; /* ASICII: GMTK */ + u32 checksum; /* CRC32 */ + u32 version; /* x.x.x.x */ + u32 kernelsz; /* The size of the kernel image */ + u32 imagesz; /* The length of this image file ( kernel + romfs + this header) */ + u32 pid; /* Product ID */ + u32 fastcksum; /* Partial CRC32 on (First(256), medium(256), last(512)) */ + u32 reserved; +}gt_imghdr_t; + +#endif diff --git a/target/linux/rdc/files-2.6.28/drivers/mtd/maps/rdc3210.c b/target/linux/rdc/files-2.6.28/drivers/mtd/maps/rdc3210.c new file mode 100644 index 0000000000..3ba3f17258 --- /dev/null +++ b/target/linux/rdc/files-2.6.28/drivers/mtd/maps/rdc3210.c @@ -0,0 +1,392 @@ +/******************************************************************* + * Simple Flash mapping for RDC3210 * + * * + * 2005.03.23 * + * Dante Su (dante_su@gemtek.com.tw) * + * Copyright (C) 2005 Gemtek Corporation * + *******************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct mtd_info *rdc3210_mtd; + +struct map_info rdc3210_map = +{ + .name = "RDC3210 Flash", + .size = CONFIG_MTD_RDC3210_SIZE, + .bankwidth = CONFIG_MTD_RDC3210_BUSWIDTH, +}; + +/* Dante: This is the default static mapping, however this is nothing but a hint. (Say dynamic mapping) */ +static struct mtd_partition rdc3210_parts[] = +{ +#if CONFIG_MTD_RDC3210_SIZE == 0x400000 + { name: "linux", offset: 0, size: 0x003C0000 }, /* 3840 KB = (Kernel + ROMFS) = (768 KB + 3072 KB) */ + { name: "romfs", offset: 0x000C0000, size: 0x00300000 }, /* 3072 KB */ + { name: "nvram", offset: 0x003C0000, size: 0x00010000 }, /* 64 KB */ +#ifdef CONFIG_MTD_RDC3210_FACTORY_PRESENT + { name: "factory", offset: 0x003D0000, size: 0x00010000 }, /* 64 KB */ +#endif + { name: "bootldr", offset: 0x003E0000, size: 0x00020000 }, /* 128 KB */ +#elif CONFIG_MTD_RDC3210_SIZE == 0x200000 + { name: "linux", offset: 0x00008000, size: 0x001E8000 }, + { name: "romfs", offset: 0x000C8000, size: 0x00128000 }, + { name: "nvram", offset: 0x00000000, size: 0x00008000 }, /* 64 KB */ +#ifdef CONFIG_MTD_RDC3210_FACTORY_PRESENT +#error Unsupported configuration! +#endif + { name: "bootldr", offset: 0x001F0000, size: 0x00010000 }, + +#elif CONFIG_MTD_RDC3210_SIZE == 0x800000 + { name: "linux", offset: 0, size: 0x001F0000 }, /* 1984 KB */ + { name: "config", offset: 0x001F0000, size: 0x00010000 }, /* 64 KB */ + { name: "romfs", offset: 0x00200000, size: 0x005D0000 }, /* 5952 KB */ +#ifdef CONFIG_MTD_RDC3210_FACTORY_PRESENT + { name: "factory", offset: 0x007D0000, size: 0x00010000 }, /* 64 KB */ +#endif + { name: "bootldr", offset: 0x007E0000, size: 0x00010000 }, /* 64 KB */ +#else +#error Unsupported configuration! +#endif +}; + +static __u32 crctab[257] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, + 0 +}; + +static __u32 crc32(__u8 * buf, __u32 len) +{ + register int i; + __u32 sum; + register __u32 s0; + s0 = ~0; + for (i = 0; i < len; i++) { + s0 = (s0 >> 8) ^ crctab[(__u8) (s0 & 0xFF) ^ buf[i]]; + } + sum = ~s0; + return sum; +} + +static void erase_callback(struct erase_info *done) +{ + wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv; + wake_up(wait_q); +} + +static int erase_write (struct mtd_info *mtd, unsigned long pos, + int len, const char *buf) +{ + struct erase_info erase; + DECLARE_WAITQUEUE(wait, current); + wait_queue_head_t wait_q; + size_t retlen; + int ret; + + /* + * First, let's erase the flash block. + */ + + init_waitqueue_head(&wait_q); + erase.mtd = mtd; + erase.callback = erase_callback; + erase.addr = pos; + erase.len = len; + erase.priv = (u_long)&wait_q; + + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&wait_q, &wait); + + ret = mtd->erase(mtd, &erase); + if (ret) { + set_current_state(TASK_RUNNING); + remove_wait_queue(&wait_q, &wait); + printk (KERN_WARNING "erase of region [0x%lx, 0x%x] " + "on \"%s\" failed\n", + pos, len, mtd->name); + return ret; + } + + schedule(); /* Wait for erase to finish. */ + remove_wait_queue(&wait_q, &wait); + + /* + * Next, writhe data to flash. + */ + + ret = mtd->write (mtd, pos, len, &retlen, buf); + if (ret) + return ret; + if (retlen != len) + return -EIO; + return 0; +} + +static int __init init_rdc3210_map(void) +{ + rdc3210_map.phys = -rdc3210_map.size; + printk(KERN_NOTICE "flash device: %lx at %x\n", rdc3210_map.size, rdc3210_map.phys); + +#if CONFIG_MTD_RDC3210_SIZE == 0x800000 + simple_map_init(&rdc3210_map); +#endif + + rdc3210_map.map_priv_1 = (unsigned long)(rdc3210_map.virt = ioremap_nocache(rdc3210_map.phys, rdc3210_map.size)); + + if (!rdc3210_map.map_priv_1) + { + printk("Failed to ioremap\n"); + return -EIO; + } + rdc3210_mtd = do_map_probe("cfi_probe", &rdc3210_map); +#ifdef CONFIG_MTD_RDC3210_STATIC_MAP /* Dante: This is for fixed map */ + if (rdc3210_mtd) + { + rdc3210_mtd->owner = THIS_MODULE; + add_mtd_partitions(rdc3210_mtd, rdc3210_parts, sizeof(rdc3210_parts)/sizeof(rdc3210_parts[0])); + return 0; + } +#else /* Dante: This is for dynamic mapping */ + +#include "imghdr.h" + + typedef struct { + u8 magic[4]; + u32 kernelsz, ramdisksz; + u8 magic2[4]; + u32 sz2; + }sc_imghdr_t; + + if (rdc3210_mtd) + { // Dante + sc_imghdr_t *hdr2= (sc_imghdr_t *)(rdc3210_map.map_priv_1); + gt_imghdr_t *hdr = (gt_imghdr_t *)hdr2 +#ifdef CONFIG_MTD_RDC3210_ALLOW_JFFS2 + , *ptmp +#endif + ; + int len, tmp, tmp2, tmp3, tmp4, hdr_type = 0; + + if(!memcmp(hdr->magic, GTIMG_MAGIC, 4)) + { + hdr_type = 1; + tmp = hdr->kernelsz + sizeof(gt_imghdr_t); + tmp2 = rdc3210_mtd->erasesize; + tmp3 = ((tmp / 32) + ((tmp % 32) ? 1 : 0)) * 32; + tmp4 = ((tmp / tmp2) + ((tmp % tmp2) ? 1 : 0)) * tmp2; + } +#ifndef CONFIG_MTD_RDC3210_ALLOW_JFFS2 + else if (!memcmp(hdr2->magic, "CSYS", 4)) + { + hdr_type = 2; + tmp = hdr2->ramdisksz + hdr2->kernelsz + sizeof(sc_imghdr_t); + tmp2 = rdc3210_mtd->erasesize; + tmp3 = ((tmp / 32) + ((tmp % 32) ? 1 : 0)) * 32; + tmp4 = ((tmp / tmp2) + ((tmp % tmp2) ? 1 : 0)) * tmp2; + } +#endif + else + { + iounmap((void *)rdc3210_map.map_priv_1); + rdc3210_map.map_priv_1 = 0L; + rdc3210_map.virt = NULL; + printk("Invalid MAGIC for Firmware Image!!!\n"); + return -EIO; + } +#ifdef CONFIG_MTD_RDC3210_ALLOW_JFFS2 + tmp = (tmp3 == tmp4) ? tmp4 + tmp2 : tmp4; + if ((ptmp = (gt_imghdr_t *)vmalloc(tmp)) == NULL) + { + iounmap((void *)rdc3210_map.map_priv_1); + rdc3210_map.map_priv_1 = 0L; + rdc3210_map.virt = NULL; + printk("Can't allocate 0x%08x for flash-reading buffer!\n", tmp); + return -ENOMEM; + } + if (rdc3210_mtd->read(rdc3210_mtd, 0, tmp, &len, (__u8 *)ptmp) || len != tmp) + { + vfree(ptmp); + iounmap((void *)rdc3210_map.map_priv_1); + rdc3210_map.map_priv_1 = 0L; + rdc3210_map.virt = NULL; + printk("Can't read that much flash! Read 0x%08x of it.\n", len); + return -EIO; + } +#endif +#ifdef CONFIG_MTD_RDC3210_FACTORY_PRESENT + /* 1. Adjust Redboot */ + tmp = rdc3210_mtd->size - rdc3210_parts[4].size; + rdc3210_parts[4].offset = tmp - (tmp % tmp2); + rdc3210_parts[4].size = rdc3210_mtd->size - rdc3210_parts[4].offset; + + /* 2. Adjust Factory Default */ + tmp -= rdc3210_parts[3].size; + rdc3210_parts[3].offset = tmp - (tmp % tmp2); + rdc3210_parts[3].size = rdc3210_parts[4].offset - rdc3210_parts[3].offset; +#else + /* 1. Adjust Redboot */ + tmp = rdc3210_mtd->size - rdc3210_parts[3].size; + rdc3210_parts[3].offset = tmp - (tmp % tmp2); + rdc3210_parts[3].size = rdc3210_mtd->size - rdc3210_parts[3].offset; +#endif + if (hdr_type == 1) { + /* 3. Adjust NVRAM */ +#ifdef CONFIG_MTD_RDC3210_ALLOW_JFFS2 + if (*(__u32 *)(((unsigned char *)ptmp)+tmp3) == SQUASHFS_MAGIC) + { + len = 1; + tmp4 = tmp3; + tmp = hdr->imagesz; + rdc3210_parts[2].name = "rootfs_data"; + rdc3210_parts[2].offset = rdc3210_parts[0].offset + (((tmp / tmp2) + ((tmp % tmp2) ? 1 : 0)) * tmp2); + } + else +#else + tmp4 = tmp3; +#endif + { + len = 0; + tmp -= rdc3210_parts[2].size; + rdc3210_parts[2].offset = tmp - (tmp % tmp2); + } + rdc3210_parts[2].size = rdc3210_parts[3].offset - rdc3210_parts[2].offset; + } + else if (hdr_type == 2) + { + len = 0; + tmp4 = tmp3; + } + + /* 4. Adjust Linux (Kernel + ROMFS) */ + rdc3210_parts[0].size = rdc3210_parts[len + hdr_type + 1].offset - rdc3210_parts[0].offset; + + /* 5. Adjust ROMFS */ + rdc3210_parts[1].offset = rdc3210_parts[0].offset + tmp4; + rdc3210_parts[1].size = rdc3210_parts[hdr_type + 1].offset - rdc3210_parts[1].offset; +#ifdef CONFIG_MTD_RDC3210_ALLOW_JFFS2 + if (!(hdr->reserved || len)) + { + __u8 buf[1024]; + ptmp->reserved = hdr->imagesz; + ptmp->imagesz = tmp4; + ptmp->checksum = ptmp->fastcksum = 0; + memcpy(buf, ptmp, 0x100); + memcpy(buf + 0x100, ((__u8 *)ptmp) + ((tmp4 >> 1) - ((tmp4 & 0x6) >> 1)), 0x100); + memcpy(buf + 0x200, ((__u8 *)ptmp) + (tmp4 - 0x200), 0x200); + ptmp->fastcksum = crc32(buf, sizeof(buf)); + ptmp->checksum = crc32((__u8 *)ptmp, tmp4); + if (rdc3210_mtd->unlock) rdc3210_mtd->unlock(rdc3210_mtd, 0, tmp2); + if ((len = erase_write(rdc3210_mtd, 0, tmp2, (char *)ptmp))) + { + vfree(ptmp); + iounmap((void *)rdc3210_map.map_priv_1); + rdc3210_map.map_priv_1 = 0L; + rdc3210_map.virt = NULL; + printk("Couldn't erase! Got %d.\n", len); + return len; + } + if (rdc3210_mtd->sync) rdc3210_mtd->sync(rdc3210_mtd); + } + vfree(ptmp); +#endif + rdc3210_mtd->owner = THIS_MODULE; + add_mtd_partitions(rdc3210_mtd, rdc3210_parts, sizeof(rdc3210_parts)/sizeof(rdc3210_parts[0])); + return 0; + } +#endif + iounmap((void *)rdc3210_map.map_priv_1); + rdc3210_map.map_priv_1 = 0L; + rdc3210_map.virt = NULL; + return -ENXIO; +} + +static void __exit cleanup_rdc3210_map(void) +{ + if (rdc3210_mtd) + { + del_mtd_partitions(rdc3210_mtd); + map_destroy(rdc3210_mtd); + } + + if (rdc3210_map.map_priv_1) + { + iounmap((void *)rdc3210_map.map_priv_1); + rdc3210_map.map_priv_1 = 0L; + rdc3210_map.virt = NULL; + } +} + +module_init(init_rdc3210_map); +module_exit(cleanup_rdc3210_map); diff --git a/target/linux/rdc/patches-2.6.28/001-rdc3210_flash_map.patch b/target/linux/rdc/patches-2.6.28/001-rdc3210_flash_map.patch new file mode 100644 index 0000000000..4c12471ec3 --- /dev/null +++ b/target/linux/rdc/patches-2.6.28/001-rdc3210_flash_map.patch @@ -0,0 +1,63 @@ +--- a/drivers/mtd/maps/Kconfig ++++ b/drivers/mtd/maps/Kconfig +@@ -110,6 +110,50 @@ + Sun Microsystems boardsets. This driver will require CFI support + in the kernel, so if you did not enable CFI previously, do that now. + ++config MTD_RDC3210 ++ tristate "CFI Flash device mapped on RDC3210" ++ depends on X86 && MTD_CFI && MTD_PARTITIONS ++ help ++ RDC-3210 is the flash device we find on Ralink reference board. ++ ++config MTD_RDC3210_STATIC_MAP ++ bool "Partitions on RDC3210 mapped statically" if MTD_RDC3210 ++ select MTD_RDC3210_FACTORY_PRESENT ++ help ++ The mapping driver will use the static partition map for the ++ RDC-3210 flash device. ++ ++config MTD_RDC3210_FACTORY_PRESENT ++ bool "Reserve a partition on RDC3210 for factory presets" ++ depends on MTD_RDC3210 ++ default y ++ help ++ The mapping driver will reserve a partition on the RDC-3210 flash ++ device for resetting flash contents to factory defaults. ++ ++config MTD_RDC3210_ALLOW_JFFS2 ++ bool "JFFS2 filesystem usable in a partition on RDC3210" ++ depends on MTD_RDC3210 && !MTD_RDC3210_STATIC_MAP ++ help ++ The mapping driver will align a partition on the RDC-3210 flash ++ device to an erase-block boundary so that a JFFS2 filesystem may ++ reside on it. ++ ++config MTD_RDC3210_SIZE ++ hex "Amount of flash memory on RDC3210" ++ depends on MTD_RDC3210 ++ default "0x400000" ++ help ++ Total size in bytes of the RDC-3210 flash device ++ ++config MTD_RDC3210_BUSWIDTH ++ int "Width of CFI Flash device mapped on RDC3210" ++ depends on MTD_RDC3210 ++ default "2" ++ help ++ Number of bytes addressed on the RDC-3210 flash device before ++ addressing the same chip again ++ + config MTD_SC520CDP + tristate "CFI Flash device mapped on AMD SC520 CDP" + depends on X86 && MTD_CFI && MTD_CONCAT +--- a/drivers/mtd/maps/Makefile ++++ b/drivers/mtd/maps/Makefile +@@ -29,6 +29,7 @@ + obj-$(CONFIG_MTD_PMC_MSP_EVM) += pmcmsp-flash.o + obj-$(CONFIG_MTD_PMC_MSP_RAMROOT)+= pmcmsp-ramroot.o + obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o ++obj-$(CONFIG_MTD_RDC3210) += rdc3210.o + obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o + obj-$(CONFIG_MTD_TQM8XXL) += tqm8xxl.o + obj-$(CONFIG_MTD_SA1100) += sa1100-flash.o diff --git a/target/linux/rdc/patches-2.6.28/003-rootfstype.patch b/target/linux/rdc/patches-2.6.28/003-rootfstype.patch new file mode 100644 index 0000000000..55a4cd49f5 --- /dev/null +++ b/target/linux/rdc/patches-2.6.28/003-rootfstype.patch @@ -0,0 +1,11 @@ +--- a/init/do_mounts.c ++++ b/init/do_mounts.c +@@ -163,6 +163,8 @@ + { + char *s = page; + ++ if (!root_fs_names) ++ root_fs_names = "squashfs,jffs2"; + if (root_fs_names) { + strcpy(page, root_fs_names); + while (*s++) { diff --git a/target/linux/rdc/patches-2.6.28/004-yenta_mystery.patch b/target/linux/rdc/patches-2.6.28/004-yenta_mystery.patch new file mode 100644 index 0000000000..7faabdf7a3 --- /dev/null +++ b/target/linux/rdc/patches-2.6.28/004-yenta_mystery.patch @@ -0,0 +1,20 @@ +--- linux-2.6.24.7.orig/drivers/pcmcia/yenta_socket.c 2008-10-26 08:30:07.000000000 -0700 ++++ linux-2.6.24.7/drivers/pcmcia/yenta_socket.c 2008-10-26 08:54:27.000000000 -0700 +@@ -1171,6 +1171,17 @@ + + /* We must finish initialization here */ + ++#ifdef CONFIG_X86_RDC ++/* #define YO_TI1510_DATASHEET_GUY_EXPLAIN_THIS_JUNK 0x0044f044 */ ++#define YO_TI1510_DATASHEET_GUY_EXPLAIN_THIS_JUNK 0x0844b060 ++/* #define YO_TI1510_DATASHEET_GUY_EXPLAIN_THIS_JUNK 0x0044d044 */ ++ ++ config_writel(socket, 32*4, YO_TI1510_DATASHEET_GUY_EXPLAIN_THIS_JUNK); ++ config_writel(socket, 35*4, 0x00000022); ++ config_writel(socket, 36*4, 0x60200000); ++ config_writel(socket, 40*4, 0x7e020000); ++#endif ++ + if (!socket->cb_irq || request_irq(socket->cb_irq, yenta_interrupt, IRQF_SHARED, "yenta", socket)) { + /* No IRQ or request_irq failed. Poll */ + socket->cb_irq = 0; /* But zero is a valid IRQ number. */ diff --git a/target/linux/rdc/patches-2.6.28/005-fix_amit_breakage.patch b/target/linux/rdc/patches-2.6.28/005-fix_amit_breakage.patch new file mode 100644 index 0000000000..eabfd04ed3 --- /dev/null +++ b/target/linux/rdc/patches-2.6.28/005-fix_amit_breakage.patch @@ -0,0 +1,42 @@ +diff -ru linux-2.6.24.7.orig/arch/x86/boot/boot.h linux-2.6.24.7/arch/x86/boot/boot.h +--- linux-2.6.24.7.orig/arch/x86/boot/boot.h 2008-10-26 20:18:14.000000000 -0700 ++++ linux-2.6.24.7/arch/x86/boot/boot.h 2008-10-26 20:18:36.000000000 -0700 +@@ -60,7 +60,7 @@ + { + asm volatile("outl %0,%1" : : "a" (v), "dN" (port)); + } +-static inline u32 inl(u32 port) ++static inline u32 inl(u16 port) + { + u32 v; + asm volatile("inl %1,%0" : "=a" (v) : "dN" (port)); +diff -ru linux-2.6.24.7.orig/arch/x86/boot/pm.c linux-2.6.24.7/arch/x86/boot/pm.c +--- linux-2.6.24.7.orig/arch/x86/boot/pm.c 2008-10-26 19:55:50.000000000 -0700 ++++ linux-2.6.24.7/arch/x86/boot/pm.c 2008-10-26 21:38:12.000000000 -0700 +@@ -16,6 +16,9 @@ + + #include "boot.h" + #include ++#ifdef CONFIG_X86_RDC ++#include ++#endif + + /* + * Invoke the realmode switch hook if present; otherwise +@@ -160,6 +163,16 @@ + die(); + } + ++#ifdef CONFIG_X86_RDC ++ { ++ u32 bootctl; ++ ++ outl(0x80003840, RDC3210_CFGREG_ADDR); ++ bootctl = inl(RDC3210_CFGREG_DATA) | 0x07ff0000; ++ outl(bootctl, RDC3210_CFGREG_DATA); ++ } ++#endif ++ + /* Reset coprocessor (IGNNE#) */ + reset_coprocessor(); + diff --git a/target/linux/rdc/patches-2.6.28/006-bzip2_lzma_x86.patch b/target/linux/rdc/patches-2.6.28/006-bzip2_lzma_x86.patch new file mode 100644 index 0000000000..7e9252e2d9 --- /dev/null +++ b/target/linux/rdc/patches-2.6.28/006-bzip2_lzma_x86.patch @@ -0,0 +1,3138 @@ +diff -urN linux-2.6.28.9/arch/arm/boot/compressed/Makefile linux-2.6.28.9.new/arch/arm/boot/compressed/Makefile +--- linux-2.6.28.9/arch/arm/boot/compressed/Makefile 2009-03-23 22:55:52.000000000 +0100 ++++ linux-2.6.28.9.new/arch/arm/boot/compressed/Makefile 2009-04-24 14:08:08.000000000 +0200 +@@ -67,8 +67,15 @@ + + SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/ + +-targets := vmlinux vmlinux.lds piggy.gz piggy.o font.o font.c \ +- head.o misc.o $(OBJS) ++suffix_$(CONFIG_KERNEL_GZIP) = gz ++suffix_$(CONFIG_KERNEL_BZIP2) = bz2 ++suffix_$(CONFIG_KERNEL_LZMA) = lzma ++ ++targets := vmlinux vmlinux.lds \ ++ piggy.gz piggy.gz.o \ ++ piggy.bz2 piggy.bz2.o \ ++ piggy.lzma piggy.lzma.o \ ++ font.o font.c head.o misc.o $(OBJS) + + ifeq ($(CONFIG_FUNCTION_TRACER),y) + ORIG_CFLAGS := $(KBUILD_CFLAGS) +@@ -95,7 +102,7 @@ + # would otherwise mess up our GOT table + CFLAGS_misc.o := -Dstatic= + +-$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \ ++$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \ + $(addprefix $(obj)/, $(OBJS)) FORCE + $(call if_changed,ld) + @: +@@ -103,7 +110,17 @@ + $(obj)/piggy.gz: $(obj)/../Image FORCE + $(call if_changed,gzip) + +-$(obj)/piggy.o: $(obj)/piggy.gz FORCE ++$(obj)/piggy.bz2: $(obj)/../Image FORCE ++ $(call if_changed,bzip2) ++ ++$(obj)/piggy.lzma: $(obj)/../Image FORCE ++ $(call if_changed,lzma) ++ ++$(obj)/piggy.gz.o: $(obj)/piggy.gz FORCE ++ ++$(obj)/piggy.bz2.o: $(obj)/piggy.bz2 FORCE ++ ++$(obj)/piggy.lzma.o: $(obj)/piggy.lzma FORCE + + CFLAGS_font.o := -Dstatic= + +diff -urN linux-2.6.28.9/arch/arm/boot/compressed/misc.c linux-2.6.28.9.new/arch/arm/boot/compressed/misc.c +--- linux-2.6.28.9/arch/arm/boot/compressed/misc.c 2009-03-23 22:55:52.000000000 +0100 ++++ linux-2.6.28.9.new/arch/arm/boot/compressed/misc.c 2009-04-24 14:08:08.000000000 +0200 +@@ -169,116 +169,34 @@ + /* + * gzip delarations + */ +-#define OF(args) args + #define STATIC static + +-typedef unsigned char uch; +-typedef unsigned short ush; + typedef unsigned long ulg; + +-#define WSIZE 0x8000 /* Window size must be at least 32k, */ +- /* and a power of two */ +- +-static uch *inbuf; /* input buffer */ +-static uch window[WSIZE]; /* Sliding window buffer */ +- +-static unsigned insize; /* valid bytes in inbuf */ +-static unsigned inptr; /* index of next byte to be processed in inbuf */ +-static unsigned outcnt; /* bytes in output buffer */ +- +-/* gzip flag byte */ +-#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +-#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ +-#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +-#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +-#define COMMENT 0x10 /* bit 4 set: file comment present */ +-#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ +-#define RESERVED 0xC0 /* bit 6,7: reserved */ +- +-#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) +- +-/* Diagnostic functions */ +-#ifdef DEBUG +-# define Assert(cond,msg) {if(!(cond)) error(msg);} +-# define Trace(x) fprintf x +-# define Tracev(x) {if (verbose) fprintf x ;} +-# define Tracevv(x) {if (verbose>1) fprintf x ;} +-# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} +-# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} +-#else +-# define Assert(cond,msg) +-# define Trace(x) +-# define Tracev(x) +-# define Tracevv(x) +-# define Tracec(c,x) +-# define Tracecv(c,x) +-#endif +- +-static int fill_inbuf(void); +-static void flush_window(void); +-static void error(char *m); +- + extern char input_data[]; + extern char input_data_end[]; + +-static uch *output_data; +-static ulg output_ptr; +-static ulg bytes_out; +- + static void error(char *m); + +-static void putstr(const char *); +- +-extern int end; + static ulg free_mem_ptr; + static ulg free_mem_end_ptr; + +-#ifdef STANDALONE_DEBUG +-#define NO_INFLATE_MALLOC +-#endif +- + #define ARCH_HAS_DECOMP_WDOG ++#define NEW_CODE + ++#ifdef CONFIG_KERNEL_GZIP + #include "../../../../lib/inflate.c" ++#endif + +-/* =========================================================================== +- * Fill the input buffer. This is called only when the buffer is empty +- * and at least one byte is really needed. +- */ +-int fill_inbuf(void) +-{ +- if (insize != 0) +- error("ran out of input data"); ++#ifdef CONFIG_KERNEL_BZIP2 ++#include "../../../../lib/decompress_bunzip2.c" ++#endif + +- inbuf = input_data; +- insize = &input_data_end[0] - &input_data[0]; ++#ifdef CONFIG_KERNEL_LZMA ++#include "../../../../lib/decompress_unlzma.c" ++#endif + +- inptr = 1; +- return inbuf[0]; +-} + +-/* =========================================================================== +- * Write the output window window[0..outcnt-1] and update crc and bytes_out. +- * (Used for the decompressed data only.) +- */ +-void flush_window(void) +-{ +- ulg c = crc; +- unsigned n; +- uch *in, *out, ch; +- +- in = window; +- out = &output_data[output_ptr]; +- for (n = 0; n < outcnt; n++) { +- ch = *out++ = *in++; +- c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); +- } +- crc = c; +- bytes_out += (ulg)outcnt; +- output_ptr += (ulg)outcnt; +- outcnt = 0; +- putstr("."); +-} + + #ifndef arch_error + #define arch_error(x) +@@ -301,16 +219,24 @@ + decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p, + int arch_id) + { +- output_data = (uch *)output_start; /* Points to kernel start */ +- free_mem_ptr = free_mem_ptr_p; +- free_mem_end_ptr = free_mem_ptr_end_p; ++ ulg output_ptr; ++ ulg *ptr; ++ size_t input_len = input_data_end - input_data; ++ size_t pos = 0; ++ + __machine_arch_type = arch_id; + + arch_decomp_setup(); + +- makecrc(); +- putstr("Uncompressing Linux..."); +- gunzip(); ++ ptr = (ulg *) (((long)input_data_end) - 4); ++ output_ptr = output_start + *ptr; ++ ++ free_mem_ptr = output_ptr; ++ free_mem_end_ptr = output_ptr + 0x4000000; ++ ++ putstr("Decompressing Linux..."); ++ decompress(input_data, input_len, ++ NULL, NULL, (unsigned char *) output_start, &pos, error); + putstr(" done, booting the kernel.\n"); + return output_ptr; + } +@@ -320,11 +246,8 @@ + + int main() + { +- output_data = output_buffer; +- +- makecrc(); + putstr("Uncompressing Linux..."); +- gunzip(); ++ decompress(input_data, input_len, NULL, output_buffer, NULL); + putstr("done.\n"); + return 0; + } +diff -urN linux-2.6.28.9/arch/x86/boot/compressed/Makefile linux-2.6.28.9.new/arch/x86/boot/compressed/Makefile +--- linux-2.6.28.9/arch/x86/boot/compressed/Makefile 2009-03-23 22:55:52.000000000 +0100 ++++ linux-2.6.28.9.new/arch/x86/boot/compressed/Makefile 2009-04-24 14:10:01.000000000 +0200 +@@ -4,7 +4,7 @@ + # create a compressed vmlinux image from the original vmlinux + # + +-targets := vmlinux vmlinux.bin vmlinux.bin.gz head_$(BITS).o misc.o piggy.o ++targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma head_$(BITS).o misc.o piggy.o + + KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 + KBUILD_CFLAGS += -fno-strict-aliasing -fPIC +@@ -47,9 +47,17 @@ + ifdef CONFIG_RELOCATABLE + $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin.all FORCE + $(call if_changed,gzip) ++$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin.all FORCE ++ $(call if_changed,bzip2) ++$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin.all FORCE ++ $(call if_changed,lzma) + else + $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE + $(call if_changed,gzip) ++$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE ++ $(call if_changed,bzip2) ++$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE ++ $(call if_changed,lzma) + endif + LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T + +@@ -60,5 +68,9 @@ + LDFLAGS_piggy.o := -r --format binary --oformat elf64-x86-64 -T + endif + +-$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE ++suffix_$(CONFIG_KERNEL_GZIP) = gz ++suffix_$(CONFIG_KERNEL_BZIP2) = bz2 ++suffix_$(CONFIG_KERNEL_LZMA) = lzma ++ ++$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix_y) FORCE + $(call if_changed,ld) +diff -urN linux-2.6.28.9/arch/x86/boot/compressed/misc.c linux-2.6.28.9.new/arch/x86/boot/compressed/misc.c +--- linux-2.6.28.9/arch/x86/boot/compressed/misc.c 2009-03-23 22:55:52.000000000 +0100 ++++ linux-2.6.28.9.new/arch/x86/boot/compressed/misc.c 2009-04-24 14:08:08.000000000 +0200 +@@ -116,71 +116,13 @@ + /* + * gzip declarations + */ +- +-#define OF(args) args + #define STATIC static + + #undef memset + #undef memcpy + #define memzero(s, n) memset((s), 0, (n)) + +-typedef unsigned char uch; +-typedef unsigned short ush; +-typedef unsigned long ulg; +- +-/* +- * Window size must be at least 32k, and a power of two. +- * We don't actually have a window just a huge output buffer, +- * so we report a 2G window size, as that should always be +- * larger than our output buffer: +- */ +-#define WSIZE 0x80000000 + +-/* Input buffer: */ +-static unsigned char *inbuf; +- +-/* Sliding window buffer (and final output buffer): */ +-static unsigned char *window; +- +-/* Valid bytes in inbuf: */ +-static unsigned insize; +- +-/* Index of next byte to be processed in inbuf: */ +-static unsigned inptr; +- +-/* Bytes in output buffer: */ +-static unsigned outcnt; +- +-/* gzip flag byte */ +-#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ +-#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gz file */ +-#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +-#define ORIG_NAM 0x08 /* bit 3 set: original file name present */ +-#define COMMENT 0x10 /* bit 4 set: file comment present */ +-#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ +-#define RESERVED 0xC0 /* bit 6, 7: reserved */ +- +-#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) +- +-/* Diagnostic functions */ +-#ifdef DEBUG +-# define Assert(cond, msg) do { if (!(cond)) error(msg); } while (0) +-# define Trace(x) do { fprintf x; } while (0) +-# define Tracev(x) do { if (verbose) fprintf x ; } while (0) +-# define Tracevv(x) do { if (verbose > 1) fprintf x ; } while (0) +-# define Tracec(c, x) do { if (verbose && (c)) fprintf x ; } while (0) +-# define Tracecv(c, x) do { if (verbose > 1 && (c)) fprintf x ; } while (0) +-#else +-# define Assert(cond, msg) +-# define Trace(x) +-# define Tracev(x) +-# define Tracevv(x) +-# define Tracec(c, x) +-# define Tracecv(c, x) +-#endif +- +-static int fill_inbuf(void); +-static void flush_window(void); + static void error(char *m); + + /* +@@ -189,11 +131,6 @@ + static struct boot_params *real_mode; /* Pointer to real-mode data */ + static int quiet; + +-extern unsigned char input_data[]; +-extern int input_len; +- +-static long bytes_out; +- + static void *memset(void *s, int c, unsigned n); + static void *memcpy(void *dest, const void *src, unsigned n); + +@@ -213,7 +150,19 @@ + static int vidport; + static int lines, cols; + ++#define NEW_CODE ++ ++#ifdef CONFIG_KERNEL_GZIP + #include "../../../../lib/inflate.c" ++#endif ++ ++#ifdef CONFIG_KERNEL_BZIP2 ++#include "../../../../lib/decompress_bunzip2.c" ++#endif ++ ++#ifdef CONFIG_KERNEL_LZMA ++#include "../../../../lib/decompress_unlzma.c" ++#endif + + static void scroll(void) + { +@@ -293,38 +242,6 @@ + return dest; + } + +-/* =========================================================================== +- * Fill the input buffer. This is called only when the buffer is empty +- * and at least one byte is really needed. +- */ +-static int fill_inbuf(void) +-{ +- error("ran out of input data"); +- return 0; +-} +- +-/* =========================================================================== +- * Write the output window window[0..outcnt-1] and update crc and bytes_out. +- * (Used for the decompressed data only.) +- */ +-static void flush_window(void) +-{ +- /* With my window equal to my output buffer +- * I only need to compute the crc here. +- */ +- unsigned long c = crc; /* temporary variable */ +- unsigned n; +- unsigned char *in, ch; +- +- in = window; +- for (n = 0; n < outcnt; n++) { +- ch = *in++; +- c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); +- } +- crc = c; +- bytes_out += (unsigned long)outcnt; +- outcnt = 0; +-} + + static void error(char *x) + { +@@ -407,12 +324,8 @@ + lines = real_mode->screen_info.orig_video_lines; + cols = real_mode->screen_info.orig_video_cols; + +- window = output; /* Output buffer (Normally at 1M) */ + free_mem_ptr = heap; /* Heap */ + free_mem_end_ptr = heap + BOOT_HEAP_SIZE; +- inbuf = input_data; /* Input buffer */ +- insize = input_len; +- inptr = 0; + + #ifdef CONFIG_X86_64 + if ((unsigned long)output & (__KERNEL_ALIGN - 1)) +@@ -430,10 +343,9 @@ + #endif + #endif + +- makecrc(); + if (!quiet) + putstr("\nDecompressing Linux... "); +- gunzip(); ++ decompress(input_data, input_len, NULL, NULL, output, NULL, error); + parse_elf(output); + if (!quiet) + putstr("done.\nBooting the kernel.\n"); +diff -urN linux-2.6.28.9/arch/x86/include/asm/boot.h linux-2.6.28.9.new/arch/x86/include/asm/boot.h +--- linux-2.6.28.9/arch/x86/include/asm/boot.h 2009-03-23 22:55:52.000000000 +0100 ++++ linux-2.6.28.9.new/arch/x86/include/asm/boot.h 2009-04-24 14:08:08.000000000 +0200 +@@ -15,11 +15,21 @@ + + (CONFIG_PHYSICAL_ALIGN - 1)) \ + & ~(CONFIG_PHYSICAL_ALIGN - 1)) + ++#if (defined CONFIG_KERNEL_BZIP2) ++#define BOOT_HEAP_SIZE 0x400000 ++#else ++ + #ifdef CONFIG_X86_64 + #define BOOT_HEAP_SIZE 0x7000 +-#define BOOT_STACK_SIZE 0x4000 + #else + #define BOOT_HEAP_SIZE 0x4000 ++#endif ++ ++#endif ++ ++#ifdef CONFIG_X86_64 ++#define BOOT_STACK_SIZE 0x4000 ++#else + #define BOOT_STACK_SIZE 0x1000 + #endif + +diff -urN linux-2.6.28.9/drivers/block/Kconfig linux-2.6.28.9.new/drivers/block/Kconfig +--- linux-2.6.28.9/drivers/block/Kconfig 2009-03-23 22:55:52.000000000 +0100 ++++ linux-2.6.28.9.new/drivers/block/Kconfig 2009-04-24 14:08:08.000000000 +0200 +@@ -358,6 +358,30 @@ + will prevent RAM block device backing store memory from being + allocated from highmem (only a problem for highmem systems). + ++config RD_BZIP2 ++ bool "Initial ramdisk compressed using bzip2" ++ default n ++ depends on BLK_DEV_INITRD=y ++ help ++ Support loading of a bzip2 encoded initial ramdisk or cpio buffer ++ If unsure, say N. ++ ++config RD_LZMA ++ bool "Initial ramdisk compressed using lzma" ++ default n ++ depends on BLK_DEV_INITRD=y ++ help ++ Support loading of a lzma encoded initial ramdisk or cpio buffer ++ If unsure, say N. ++ ++config RD_GZIP ++ bool "Initial ramdisk compressed using gzip" ++ default y ++ depends on BLK_DEV_INITRD=y ++ help ++ Support loading of a gzip encoded initial ramdisk or cpio buffer. ++ If unsure, say Y. ++ + config CDROM_PKTCDVD + tristate "Packet writing on CD/DVD media" + depends on !UML +diff -urN linux-2.6.28.9/include/linux/decompress/bunzip2.h linux-2.6.28.9.new/include/linux/decompress/bunzip2.h +--- linux-2.6.28.9/include/linux/decompress/bunzip2.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.28.9.new/include/linux/decompress/bunzip2.h 2009-04-24 14:08:08.000000000 +0200 +@@ -0,0 +1,10 @@ ++#ifndef DECOMPRESS_BUNZIP2_H ++#define DECOMPRESS_BUNZIP2_H ++ ++int bunzip2(unsigned char *inbuf, int len, ++ int(*fill)(void*, unsigned int), ++ int(*flush)(void*, unsigned int), ++ unsigned char *output, ++ int *pos, ++ void(*error)(char *x)); ++#endif +diff -urN linux-2.6.28.9/include/linux/decompress/generic.h linux-2.6.28.9.new/include/linux/decompress/generic.h +--- linux-2.6.28.9/include/linux/decompress/generic.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.28.9.new/include/linux/decompress/generic.h 2009-04-24 14:08:08.000000000 +0200 +@@ -0,0 +1,30 @@ ++#ifndef DECOMPRESS_GENERIC_H ++#define DECOMPRESS_GENERIC_H ++ ++/* Minimal chunksize to be read. ++ *Bzip2 prefers at least 4096 ++ *Lzma prefers 0x10000 */ ++#define COMPR_IOBUF_SIZE 4096 ++ ++typedef int (*decompress_fn) (unsigned char *inbuf, int len, ++ int(*fill)(void*, unsigned int), ++ int(*writebb)(void*, unsigned int), ++ unsigned char *output, ++ int *posp, ++ void(*error)(char *x)); ++ ++/* inbuf - input buffer ++ *len - len of pre-read data in inbuf ++ *fill - function to fill inbuf if empty ++ *writebb - function to write out outbug ++ *posp - if non-null, input position (number of bytes read) will be ++ * returned here ++ * ++ *If len != 0, the inbuf is initialized (with as much data), and fill ++ *should not be called ++ *If len = 0, the inbuf is allocated, but empty. Its size is IOBUF_SIZE ++ *fill should be called (repeatedly...) to read data, at most IOBUF_SIZE ++ */ ++ ++ ++#endif +diff -urN linux-2.6.28.9/include/linux/decompress/inflate.h linux-2.6.28.9.new/include/linux/decompress/inflate.h +--- linux-2.6.28.9/include/linux/decompress/inflate.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.28.9.new/include/linux/decompress/inflate.h 2009-04-24 14:08:08.000000000 +0200 +@@ -0,0 +1,13 @@ ++#ifndef INFLATE_H ++#define INFLATE_H ++ ++/* Other housekeeping constants */ ++#define INBUFSIZ 4096 ++ ++int gunzip(unsigned char *inbuf, int len, ++ int(*fill)(void*, unsigned int), ++ int(*flush)(void*, unsigned int), ++ unsigned char *output, ++ int *pos, ++ void(*error_fn)(char *x)); ++#endif +diff -urN linux-2.6.28.9/include/linux/decompress/mm.h linux-2.6.28.9.new/include/linux/decompress/mm.h +--- linux-2.6.28.9/include/linux/decompress/mm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.28.9.new/include/linux/decompress/mm.h 2009-04-24 14:08:08.000000000 +0200 +@@ -0,0 +1,89 @@ ++/* ++ * linux/compr_mm.h ++ * ++ * Memory management for pre-boot and ramdisk uncompressors ++ * ++ * Authors: Alain Knaff ++ * ++ */ ++ ++#ifndef DECOMPR_MM_H ++#define DECOMPR_MM_H ++ ++#ifdef STATIC ++ ++/* Code active when included from pre-boot environment: */ ++ ++/* A trivial malloc implementation, adapted from ++ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 ++ */ ++static unsigned long malloc_ptr; ++static int malloc_count; ++ ++static void *malloc(int size) ++{ ++ void *p; ++ ++ if (size < 0) ++ error("Malloc error"); ++ if (!malloc_ptr) ++ malloc_ptr = free_mem_ptr; ++ ++ malloc_ptr = (malloc_ptr + 3) & ~3; /* Align */ ++ ++ p = (void *)malloc_ptr; ++ malloc_ptr += size; ++ ++ if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr) ++ error("Out of memory"); ++ ++ malloc_count++; ++ return p; ++} ++ ++static void free(void *where) ++{ ++ malloc_count--; ++ if (!malloc_count) ++ malloc_ptr = free_mem_ptr; ++} ++ ++#define large_malloc(a) malloc(a) ++#define large_free(a) free(a) ++ ++#define set_error_fn(x) ++#define panic error ++ ++#define INIT ++ ++#else /* STATIC */ ++ ++/* Code active when compiled standalone for use when loading ramdisk: */ ++ ++#include ++#include ++#include ++#include ++ ++/* Use defines rather than static inline in order to avoid spurious ++ * warnings when not needed (indeed large_malloc / large_free are not ++ * needed by inflate */ ++ ++#define malloc(a) kmalloc(a, GFP_KERNEL) ++#define free(a) kfree(a) ++ ++#define large_malloc(a) vmalloc(a) ++#define large_free(a) vfree(a) ++ ++static void(*error)(char *m); ++#define set_error_fn(x) error = x; ++#define NEW_CODE ++ ++#define INIT __init ++#define STATIC ++ ++#include ++ ++#endif /* STATIC */ ++ ++#endif /* DECOMPR_MM_H */ +diff -urN linux-2.6.28.9/include/linux/decompress/unlzma.h linux-2.6.28.9.new/include/linux/decompress/unlzma.h +--- linux-2.6.28.9/include/linux/decompress/unlzma.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.28.9.new/include/linux/decompress/unlzma.h 2009-04-24 14:08:08.000000000 +0200 +@@ -0,0 +1,12 @@ ++#ifndef DECOMPRESS_UNLZMA_H ++#define DECOMPRESS_UNLZMA_H ++ ++int unlzma(unsigned char *, int, ++ int(*fill)(void*, unsigned int), ++ int(*flush)(void*, unsigned int), ++ unsigned char *output, ++ int *posp, ++ void(*error)(char *x) ++ ); ++ ++#endif +diff -urN linux-2.6.28.9/init/Kconfig linux-2.6.28.9.new/init/Kconfig +--- linux-2.6.28.9/init/Kconfig 2009-03-23 22:55:52.000000000 +0100 ++++ linux-2.6.28.9.new/init/Kconfig 2009-04-24 14:08:08.000000000 +0200 +@@ -101,6 +101,56 @@ + + which is done within the script "scripts/setlocalversion".) + ++choice ++ prompt "Kernel compression mode" ++ default KERNEL_GZIP ++ help ++ The linux kernel is a kind of self-extracting executable. ++ Several compression algorithms are available, which differ ++ in efficiency, compression and decompression speed. ++ Compression speed is only relevant when building a kernel. ++ Decompression speed is relevant at each boot. ++ ++ If you have any problems with bzip2 or lzma compressed ++ kernels, mail me (Alain Knaff) . (An older ++ version of this functionality (bzip2 only), for 2.4, was ++ supplied by Christian Ludwig) ++ ++ High compression options are mostly useful for users, who ++ are low on disk space (embedded systems), but for whom ram ++ size matters less. ++ ++ If in doubt, select 'gzip' ++ ++config KERNEL_GZIP ++ bool "Gzip" ++ help ++ The old and tried gzip compression. Its compression ratio is ++ the poorest among the 3 choices; however its speed (both ++ compression and decompression) is the fastest. ++ ++config KERNEL_BZIP2 ++ bool "Bzip2" ++ help ++ Its compression ratio and speed is intermediate. ++ Decompression speed is slowest among the 3. ++ The kernel size is about 10 per cent smaller with bzip2, ++ in comparison to gzip. ++ Bzip2 uses a large amount of memory. For modern kernels ++ you will need at least 8MB RAM or more for booting. ++ ++config KERNEL_LZMA ++ bool "LZMA" ++ help ++ The most recent compression algorithm. ++ Its ratio is best, decompression speed is between the other ++ 2. Compression is slowest. ++ The kernel size is about 33 per cent smaller with lzma, ++ in comparison to gzip. ++ ++endchoice ++ ++ + config SWAP + bool "Support for paging of anonymous memory (swap)" + depends on MMU && BLOCK +diff -urN linux-2.6.28.9/init/do_mounts_rd.c linux-2.6.28.9.new/init/do_mounts_rd.c +--- linux-2.6.28.9/init/do_mounts_rd.c 2009-04-24 13:59:44.000000000 +0200 ++++ linux-2.6.28.9.new/init/do_mounts_rd.c 2009-04-24 14:08:08.000000000 +0200 +@@ -11,6 +11,12 @@ + + #include "do_mounts.h" + ++#include ++ ++#include ++#include ++#include ++ + int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */ + + static int __init prompt_ramdisk(char *str) +@@ -29,7 +35,7 @@ + } + __setup("ramdisk_start=", ramdisk_start_setup); + +-static int __init crd_load(int in_fd, int out_fd); ++static int __init crd_load(int in_fd, int out_fd, decompress_fn deco); + + /* + * This routine tries to find a RAM disk image to load, and returns the +@@ -46,7 +52,7 @@ + * gzip + */ + static int __init +-identify_ramdisk_image(int fd, int start_block) ++identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) + { + const int size = 512; + struct minix_super_block *minixsb; +@@ -74,6 +80,7 @@ + sys_lseek(fd, start_block * BLOCK_SIZE, 0); + sys_read(fd, buf, size); + ++#ifdef CONFIG_RD_GZIP + /* + * If it matches the gzip magic numbers, return 0 + */ +@@ -81,9 +88,39 @@ + printk(KERN_NOTICE + "RAMDISK: Compressed image found at block %d\n", + start_block); ++ *decompressor = gunzip; ++ nblocks = 0; ++ goto done; ++ } ++#endif ++ ++#ifdef CONFIG_RD_BZIP2 ++ /* ++ * If it matches the bzip2 magic numbers, return -1 ++ */ ++ if (buf[0] == 0x42 && (buf[1] == 0x5a)) { ++ printk(KERN_NOTICE ++ "RAMDISK: Bzipped image found at block %d\n", ++ start_block); ++ *decompressor = bunzip2; + nblocks = 0; + goto done; + } ++#endif ++ ++#ifdef CONFIG_RD_LZMA ++ /* ++ * If it matches the lzma magic numbers, return -1 ++ */ ++ if (buf[0] == 0x5d && (buf[1] == 0x00)) { ++ printk(KERN_NOTICE ++ "RAMDISK: Lzma image found at block %d\n", ++ start_block); ++ *decompressor = unlzma; ++ nblocks = 0; ++ goto done; ++ } ++#endif + + /* romfs is at block zero too */ + if (romfsb->word0 == ROMSB_WORD0 && +@@ -156,6 +193,7 @@ + int nblocks, i, disk; + char *buf = NULL; + unsigned short rotate = 0; ++ decompress_fn decompressor = NULL; + #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES) + char rotator[4] = { '|' , '/' , '-' , '\\' }; + #endif +@@ -168,12 +206,12 @@ + if (in_fd < 0) + goto noclose_input; + +- nblocks = identify_ramdisk_image(in_fd, rd_image_start); ++ nblocks = identify_ramdisk_image(in_fd, rd_image_start, &decompressor); + if (nblocks < 0) + goto done; + + if (nblocks == 0) { +- if (crd_load(in_fd, out_fd) == 0) ++ if (crd_load(in_fd, out_fd, decompressor) == 0) + goto successful_load; + goto done; + } +@@ -272,138 +310,48 @@ + return rd_load_image("/dev/root"); + } + +-/* +- * gzip declarations +- */ +- +-#define OF(args) args +- +-#ifndef memzero +-#define memzero(s, n) memset ((s), 0, (n)) +-#endif +- +-typedef unsigned char uch; +-typedef unsigned short ush; +-typedef unsigned long ulg; +- +-#define INBUFSIZ 4096 +-#define WSIZE 0x8000 /* window size--must be a power of two, and */ +- /* at least 32K for zip's deflate method */ +- +-static uch *inbuf; +-static uch *window; +- +-static unsigned insize; /* valid bytes in inbuf */ +-static unsigned inptr; /* index of next byte to be processed in inbuf */ +-static unsigned outcnt; /* bytes in output buffer */ + static int exit_code; +-static int unzip_error; +-static long bytes_out; ++static int decompress_error; + static int crd_infd, crd_outfd; + +-#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) +- +-/* Diagnostic functions (stubbed out) */ +-#define Assert(cond,msg) +-#define Trace(x) +-#define Tracev(x) +-#define Tracevv(x) +-#define Tracec(c,x) +-#define Tracecv(c,x) +- +-#define STATIC static +-#define INIT __init +- +-static int __init fill_inbuf(void); +-static void __init flush_window(void); +-static void __init error(char *m); +- +-#define NO_INFLATE_MALLOC +- +-#include "../lib/inflate.c" +- +-/* =========================================================================== +- * Fill the input buffer. This is called only when the buffer is empty +- * and at least one byte is really needed. +- * Returning -1 does not guarantee that gunzip() will ever return. +- */ +-static int __init fill_inbuf(void) ++static int __init compr_fill(void *buf, unsigned int len) + { +- if (exit_code) return -1; +- +- insize = sys_read(crd_infd, inbuf, INBUFSIZ); +- if (insize == 0) { +- error("RAMDISK: ran out of compressed data"); +- return -1; +- } +- +- inptr = 1; +- +- return inbuf[0]; ++ int r = sys_read(crd_infd, buf, len); ++ if (r < 0) ++ printk(KERN_ERR "RAMDISK: error while reading compressed data"); ++ else if (r == 0) ++ printk(KERN_ERR "RAMDISK: EOF while reading compressed data"); ++ return r; + } + +-/* =========================================================================== +- * Write the output window window[0..outcnt-1] and update crc and bytes_out. +- * (Used for the decompressed data only.) +- */ +-static void __init flush_window(void) ++static int __init compr_flush(void *window, unsigned int outcnt) + { +- ulg c = crc; /* temporary variable */ +- unsigned n, written; +- uch *in, ch; +- +- written = sys_write(crd_outfd, window, outcnt); +- if (written != outcnt && unzip_error == 0) { +- printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n", +- written, outcnt, bytes_out); +- unzip_error = 1; +- } +- in = window; +- for (n = 0; n < outcnt; n++) { +- ch = *in++; +- c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); +- } +- crc = c; +- bytes_out += (ulg)outcnt; +- outcnt = 0; ++ int written = sys_write(crd_outfd, window, outcnt); ++ if (written != outcnt) { ++ if (decompress_error == 0) ++ printk(KERN_ERR ++ "RAMDISK: incomplete write (%d != %d)\n", ++ written, outcnt); ++ decompress_error = 1; ++ return -1; ++ } ++ return outcnt; + } + + static void __init error(char *x) + { + printk(KERN_ERR "%s\n", x); + exit_code = 1; +- unzip_error = 1; ++ decompress_error = 1; + } + +-static int __init crd_load(int in_fd, int out_fd) ++static int __init crd_load(int in_fd, int out_fd, decompress_fn deco) + { + int result; +- +- insize = 0; /* valid bytes in inbuf */ +- inptr = 0; /* index of next byte to be processed in inbuf */ +- outcnt = 0; /* bytes in output buffer */ +- exit_code = 0; +- bytes_out = 0; +- crc = (ulg)0xffffffffL; /* shift register contents */ +- + crd_infd = in_fd; + crd_outfd = out_fd; +- inbuf = kmalloc(INBUFSIZ, GFP_KERNEL); +- if (!inbuf) { +- printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n"); +- return -1; +- } +- window = kmalloc(WSIZE, GFP_KERNEL); +- if (!window) { +- printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n"); +- kfree(inbuf); +- return -1; +- } +- makecrc(); +- result = gunzip(); +- if (unzip_error) ++ result = deco(NULL, 0, compr_fill, compr_flush, NULL, NULL, error); ++ if (decompress_error) + result = 1; +- kfree(inbuf); +- kfree(window); + return result; + } +diff -urN linux-2.6.28.9/init/initramfs.c linux-2.6.28.9.new/init/initramfs.c +--- linux-2.6.28.9/init/initramfs.c 2009-03-23 22:55:52.000000000 +0100 ++++ linux-2.6.28.9.new/init/initramfs.c 2009-04-24 14:13:53.000000000 +0200 +@@ -389,11 +389,14 @@ + return len - count; + } + +-static void __init flush_buffer(char *buf, unsigned len) ++ ++static int __init flush_buffer(void *bufv, unsigned len) + { ++ char *buf = (char *) bufv; + int written; ++ int origLen = len; + if (message) +- return; ++ return -1; + while ((written = write_buffer(buf, len)) < len && !message) { + char c = buf[written]; + if (c == '0') { +@@ -407,73 +410,14 @@ + } else + error("junk in compressed archive"); + } ++ return origLen; + } + +-/* +- * gzip declarations +- */ +- +-#define OF(args) args +- +-#ifndef memzero +-#define memzero(s, n) memset ((s), 0, (n)) +-#endif ++static unsigned my_inptr; /* index of next byte to be processed in inbuf */ + +-typedef unsigned char uch; +-typedef unsigned short ush; +-typedef unsigned long ulg; +- +-#define WSIZE 0x8000 /* window size--must be a power of two, and */ +- /* at least 32K for zip's deflate method */ +- +-static uch *inbuf; +-static uch *window; +- +-static unsigned insize; /* valid bytes in inbuf */ +-static unsigned inptr; /* index of next byte to be processed in inbuf */ +-static unsigned outcnt; /* bytes in output buffer */ +-static long bytes_out; +- +-#define get_byte() (inptr < insize ? inbuf[inptr++] : -1) +- +-/* Diagnostic functions (stubbed out) */ +-#define Assert(cond,msg) +-#define Trace(x) +-#define Tracev(x) +-#define Tracevv(x) +-#define Tracec(c,x) +-#define Tracecv(c,x) +- +-#define STATIC static +-#define INIT __init +- +-static void __init flush_window(void); +-static void __init error(char *m); +- +-#define NO_INFLATE_MALLOC +- +-#include "../lib/inflate.c" +- +-/* =========================================================================== +- * Write the output window window[0..outcnt-1] and update crc and bytes_out. +- * (Used for the decompressed data only.) +- */ +-static void __init flush_window(void) +-{ +- ulg c = crc; /* temporary variable */ +- unsigned n; +- uch *in, ch; +- +- flush_buffer(window, outcnt); +- in = window; +- for (n = 0; n < outcnt; n++) { +- ch = *in++; +- c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); +- } +- crc = c; +- bytes_out += (ulg)outcnt; +- outcnt = 0; +-} ++#include ++#include ++#include + + static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) + { +@@ -482,9 +426,10 @@ + header_buf = kmalloc(110, GFP_KERNEL); + symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL); + name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL); +- window = kmalloc(WSIZE, GFP_KERNEL); +- if (!window || !header_buf || !symlink_buf || !name_buf) ++ ++ if (!header_buf || !symlink_buf || !name_buf) + panic("can't allocate buffers"); ++ + state = Start; + this_header = 0; + message = NULL; +@@ -504,22 +449,38 @@ + continue; + } + this_header = 0; +- insize = len; +- inbuf = buf; +- inptr = 0; +- outcnt = 0; /* bytes in output buffer */ +- bytes_out = 0; +- crc = (ulg)0xffffffffL; /* shift register contents */ +- makecrc(); +- gunzip(); ++ if (!gunzip(buf, len, NULL, flush_buffer, NULL, ++ &my_inptr, error) && ++ message == NULL) ++ goto ok; ++ ++#ifdef CONFIG_RD_BZIP2 ++ message = NULL; /* Zero out message, or else cpio will think an error has already occured */ ++ if (!bunzip2(buf, len, NULL, flush_buffer, NULL, ++ &my_inptr, error) < 0 ++ && ++ message == NULL) { ++ goto ok; ++ } ++#endif ++ ++#ifdef CONFIG_RD_LZMA ++ message = NULL; /* Zero out message, or else cpio will think an error has already occured */ ++ if (!unlzma(buf, len, NULL, flush_buffer, NULL, ++ &my_inptr, error) < 0 ++ && ++ message == NULL) { ++ goto ok; ++ } ++#endif ++ok: + if (state != Reset) +- error("junk in gzipped archive"); +- this_header = saved_offset + inptr; +- buf += inptr; +- len -= inptr; ++ error("junk in compressed archive"); ++ this_header = saved_offset + my_inptr; ++ buf += my_inptr; ++ len -= my_inptr; + } + dir_utime(); +- kfree(window); + kfree(name_buf); + kfree(symlink_buf); + kfree(header_buf); +diff -urN linux-2.6.28.9/lib/Makefile linux-2.6.28.9.new/lib/Makefile +--- linux-2.6.28.9/lib/Makefile 2009-04-24 13:59:44.000000000 +0200 ++++ linux-2.6.28.9.new/lib/Makefile 2009-04-24 14:08:08.000000000 +0200 +@@ -11,7 +11,8 @@ + rbtree.o radix-tree.o dump_stack.o \ + idr.o int_sqrt.o extable.o prio_tree.o \ + sha1.o irq_regs.o reciprocal_div.o argv_split.o \ +- proportions.o prio_heap.o ratelimit.o show_mem.o ++ proportions.o prio_heap.o ratelimit.o show_mem.o \ ++ inflate.o decompress_bunzip2.o decompress_unlzma.o + + lib-$(CONFIG_MMU) += ioremap.o + lib-$(CONFIG_SMP) += cpumask.o +diff -urN linux-2.6.28.9/lib/decompress_bunzip2.c linux-2.6.28.9.new/lib/decompress_bunzip2.c +--- linux-2.6.28.9/lib/decompress_bunzip2.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.28.9.new/lib/decompress_bunzip2.c 2009-04-24 14:08:08.000000000 +0200 +@@ -0,0 +1,735 @@ ++/* vi: set sw = 4 ts = 4: */ ++/* Small bzip2 deflate implementation, by Rob Landley (rob@landley.net). ++ ++ Based on bzip2 decompression code by Julian R Seward (jseward@acm.org), ++ which also acknowledges contributions by Mike Burrows, David Wheeler, ++ Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten, ++ Robert Sedgewick, and Jon L. Bentley. ++ ++ This code is licensed under the LGPLv2: ++ LGPL (http://www.gnu.org/copyleft/lgpl.html ++*/ ++ ++/* ++ Size and speed optimizations by Manuel Novoa III (mjn3@codepoet.org). ++ ++ More efficient reading of Huffman codes, a streamlined read_bunzip() ++ function, and various other tweaks. In (limited) tests, approximately ++ 20% faster than bzcat on x86 and about 10% faster on arm. ++ ++ Note that about 2/3 of the time is spent in read_unzip() reversing ++ the Burrows-Wheeler transformation. Much of that time is delay ++ resulting from cache misses. ++ ++ I would ask that anyone benefiting from this work, especially those ++ using it in commercial products, consider making a donation to my local ++ non-profit hospice organization in the name of the woman I loved, who ++ passed away Feb. 12, 2003. ++ ++ In memory of Toni W. Hagan ++ ++ Hospice of Acadiana, Inc. ++ 2600 Johnston St., Suite 200 ++ Lafayette, LA 70503-3240 ++ ++ Phone (337) 232-1234 or 1-800-738-2226 ++ Fax (337) 232-1297 ++ ++ http://www.hospiceacadiana.com/ ++ ++ Manuel ++ */ ++ ++/* ++ Made it fit for running in Linux Kernel by Alain Knaff (alain@knaff.lu) ++*/ ++ ++ ++#ifndef STATIC ++#include ++#endif /* !STATIC */ ++ ++#include ++ ++#ifndef INT_MAX ++#define INT_MAX 0x7fffffff ++#endif ++ ++/* Constants for Huffman coding */ ++#define MAX_GROUPS 6 ++#define GROUP_SIZE 50 /* 64 would have been more efficient */ ++#define MAX_HUFCODE_BITS 20 /* Longest Huffman code allowed */ ++#define MAX_SYMBOLS 258 /* 256 literals + RUNA + RUNB */ ++#define SYMBOL_RUNA 0 ++#define SYMBOL_RUNB 1 ++ ++/* Status return values */ ++#define RETVAL_OK 0 ++#define RETVAL_LAST_BLOCK (-1) ++#define RETVAL_NOT_BZIP_DATA (-2) ++#define RETVAL_UNEXPECTED_INPUT_EOF (-3) ++#define RETVAL_UNEXPECTED_OUTPUT_EOF (-4) ++#define RETVAL_DATA_ERROR (-5) ++#define RETVAL_OUT_OF_MEMORY (-6) ++#define RETVAL_OBSOLETE_INPUT (-7) ++ ++/* Other housekeeping constants */ ++#define BZIP2_IOBUF_SIZE 4096 ++ ++/* This is what we know about each Huffman coding group */ ++struct group_data { ++ /* We have an extra slot at the end of limit[] for a sentinal value. */ ++ int limit[MAX_HUFCODE_BITS+1]; ++ int base[MAX_HUFCODE_BITS]; ++ int permute[MAX_SYMBOLS]; ++ int minLen, maxLen; ++}; ++ ++/* Structure holding all the housekeeping data, including IO buffers and ++ memory that persists between calls to bunzip */ ++struct bunzip_data { ++ /* State for interrupting output loop */ ++ int writeCopies, writePos, writeRunCountdown, writeCount, writeCurrent; ++ /* I/O tracking data (file handles, buffers, positions, etc.) */ ++ int (*fill)(void*, unsigned int); ++ int inbufCount, inbufPos /*, outbufPos*/; ++ unsigned char *inbuf /*,*outbuf*/; ++ unsigned int inbufBitCount, inbufBits; ++ /* The CRC values stored in the block header and calculated from the ++ data */ ++ unsigned int crc32Table[256], headerCRC, totalCRC, writeCRC; ++ /* Intermediate buffer and its size (in bytes) */ ++ unsigned int *dbuf, dbufSize; ++ /* These things are a bit too big to go on the stack */ ++ unsigned char selectors[32768]; /* nSelectors = 15 bits */ ++ struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */ ++ int io_error; /* non-zero if we have IO error */ ++}; ++ ++ ++/* Return the next nnn bits of input. All reads from the compressed input ++ are done through this function. All reads are big endian */ ++static unsigned int INIT get_bits(struct bunzip_data *bd, char bits_wanted) ++{ ++ unsigned int bits = 0; ++ ++ /* If we need to get more data from the byte buffer, do so. ++ (Loop getting one byte at a time to enforce endianness and avoid ++ unaligned access.) */ ++ while (bd->inbufBitCount < bits_wanted) { ++ /* If we need to read more data from file into byte buffer, do ++ so */ ++ if (bd->inbufPos == bd->inbufCount) { ++ if (bd->io_error) ++ return 0; ++ bd->inbufCount = bd->fill(bd->inbuf, BZIP2_IOBUF_SIZE); ++ if (bd->inbufCount <= 0) { ++ bd->io_error = RETVAL_UNEXPECTED_INPUT_EOF; ++ return 0; ++ } ++ bd->inbufPos = 0; ++ } ++ /* Avoid 32-bit overflow (dump bit buffer to top of output) */ ++ if (bd->inbufBitCount >= 24) { ++ bits = bd->inbufBits&((1 << bd->inbufBitCount)-1); ++ bits_wanted -= bd->inbufBitCount; ++ bits <<= bits_wanted; ++ bd->inbufBitCount = 0; ++ } ++ /* Grab next 8 bits of input from buffer. */ ++ bd->inbufBits = (bd->inbufBits << 8)|bd->inbuf[bd->inbufPos++]; ++ bd->inbufBitCount += 8; ++ } ++ /* Calculate result */ ++ bd->inbufBitCount -= bits_wanted; ++ bits |= (bd->inbufBits >> bd->inbufBitCount)&((1 << bits_wanted)-1); ++ ++ return bits; ++} ++ ++/* Unpacks the next block and sets up for the inverse burrows-wheeler step. */ ++ ++static int INIT get_next_block(struct bunzip_data *bd) ++{ ++ struct group_data *hufGroup = NULL; ++ int *base = NULL; ++ int *limit = NULL; ++ int dbufCount, nextSym, dbufSize, groupCount, selector, ++ i, j, k, t, runPos, symCount, symTotal, nSelectors, ++ byteCount[256]; ++ unsigned char uc, symToByte[256], mtfSymbol[256], *selectors; ++ unsigned int *dbuf, origPtr; ++ ++ dbuf = bd->dbuf; ++ dbufSize = bd->dbufSize; ++ selectors = bd->selectors; ++ ++ /* Read in header signature and CRC, then validate signature. ++ (last block signature means CRC is for whole file, return now) */ ++ i = get_bits(bd, 24); ++ j = get_bits(bd, 24); ++ bd->headerCRC = get_bits(bd, 32); ++ if ((i == 0x177245) && (j == 0x385090)) ++ return RETVAL_LAST_BLOCK; ++ if ((i != 0x314159) || (j != 0x265359)) ++ return RETVAL_NOT_BZIP_DATA; ++ /* We can add support for blockRandomised if anybody complains. ++ There was some code for this in busybox 1.0.0-pre3, but nobody ever ++ noticed that it didn't actually work. */ ++ if (get_bits(bd, 1)) ++ return RETVAL_OBSOLETE_INPUT; ++ origPtr = get_bits(bd, 24); ++ if (origPtr > dbufSize) ++ return RETVAL_DATA_ERROR; ++ /* mapping table: if some byte values are never used (encoding things ++ like ascii text), the compression code removes the gaps to have fewer ++ symbols to deal with, and writes a sparse bitfield indicating which ++ values were present. We make a translation table to convert the ++ symbols back to the corresponding bytes. */ ++ t = get_bits(bd, 16); ++ symTotal = 0; ++ for (i = 0; i < 16; i++) { ++ if (t&(1 << (15-i))) { ++ k = get_bits(bd, 16); ++ for (j = 0; j < 16; j++) ++ if (k&(1 << (15-j))) ++ symToByte[symTotal++] = (16*i)+j; ++ } ++ } ++ /* How many different Huffman coding groups does this block use? */ ++ groupCount = get_bits(bd, 3); ++ if (groupCount < 2 || groupCount > MAX_GROUPS) ++ return RETVAL_DATA_ERROR; ++ /* nSelectors: Every GROUP_SIZE many symbols we select a new ++ Huffman coding group. Read in the group selector list, ++ which is stored as MTF encoded bit runs. (MTF = Move To ++ Front, as each value is used it's moved to the start of the ++ list.) */ ++ nSelectors = get_bits(bd, 15); ++ if (!nSelectors) ++ return RETVAL_DATA_ERROR; ++ for (i = 0; i < groupCount; i++) ++ mtfSymbol[i] = i; ++ for (i = 0; i < nSelectors; i++) { ++ /* Get next value */ ++ for (j = 0; get_bits(bd, 1); j++) ++ if (j >= groupCount) ++ return RETVAL_DATA_ERROR; ++ /* Decode MTF to get the next selector */ ++ uc = mtfSymbol[j]; ++ for (; j; j--) ++ mtfSymbol[j] = mtfSymbol[j-1]; ++ mtfSymbol[0] = selectors[i] = uc; ++ } ++ /* Read the Huffman coding tables for each group, which code ++ for symTotal literal symbols, plus two run symbols (RUNA, ++ RUNB) */ ++ symCount = symTotal+2; ++ for (j = 0; j < groupCount; j++) { ++ unsigned char length[MAX_SYMBOLS], temp[MAX_HUFCODE_BITS+1]; ++ int minLen, maxLen, pp; ++ /* Read Huffman code lengths for each symbol. They're ++ stored in a way similar to mtf; record a starting ++ value for the first symbol, and an offset from the ++ previous value for everys symbol after that. ++ (Subtracting 1 before the loop and then adding it ++ back at the end is an optimization that makes the ++ test inside the loop simpler: symbol length 0 ++ becomes negative, so an unsigned inequality catches ++ it.) */ ++ t = get_bits(bd, 5)-1; ++ for (i = 0; i < symCount; i++) { ++ for (;;) { ++ if (((unsigned)t) > (MAX_HUFCODE_BITS-1)) ++ return RETVAL_DATA_ERROR; ++ ++ /* If first bit is 0, stop. Else ++ second bit indicates whether to ++ increment or decrement the value. ++ Optimization: grab 2 bits and unget ++ the second if the first was 0. */ ++ ++ k = get_bits(bd, 2); ++ if (k < 2) { ++ bd->inbufBitCount++; ++ break; ++ } ++ /* Add one if second bit 1, else ++ * subtract 1. Avoids if/else */ ++ t += (((k+1)&2)-1); ++ } ++ /* Correct for the initial -1, to get the ++ * final symbol length */ ++ length[i] = t+1; ++ } ++ /* Find largest and smallest lengths in this group */ ++ minLen = maxLen = length[0]; ++ ++ for (i = 1; i < symCount; i++) { ++ if (length[i] > maxLen) ++ maxLen = length[i]; ++ else if (length[i] < minLen) ++ minLen = length[i]; ++ } ++ ++ /* Calculate permute[], base[], and limit[] tables from ++ * length[]. ++ * ++ * permute[] is the lookup table for converting ++ * Huffman coded symbols into decoded symbols. base[] ++ * is the amount to subtract from the value of a ++ * Huffman symbol of a given length when using ++ * permute[]. ++ * ++ * limit[] indicates the largest numerical value a ++ * symbol with a given number of bits can have. This ++ * is how the Huffman codes can vary in length: each ++ * code with a value > limit[length] needs another ++ * bit. ++ */ ++ hufGroup = bd->groups+j; ++ hufGroup->minLen = minLen; ++ hufGroup->maxLen = maxLen; ++ /* Note that minLen can't be smaller than 1, so we ++ adjust the base and limit array pointers so we're ++ not always wasting the first entry. We do this ++ again when using them (during symbol decoding).*/ ++ base = hufGroup->base-1; ++ limit = hufGroup->limit-1; ++ /* Calculate permute[]. Concurently, initialize ++ * temp[] and limit[]. */ ++ pp = 0; ++ for (i = minLen; i <= maxLen; i++) { ++ temp[i] = limit[i] = 0; ++ for (t = 0; t < symCount; t++) ++ if (length[t] == i) ++ hufGroup->permute[pp++] = t; ++ } ++ /* Count symbols coded for at each bit length */ ++ for (i = 0; i < symCount; i++) ++ temp[length[i]]++; ++ /* Calculate limit[] (the largest symbol-coding value ++ *at each bit length, which is (previous limit << ++ *1)+symbols at this level), and base[] (number of ++ *symbols to ignore at each bit length, which is limit ++ *minus the cumulative count of symbols coded for ++ *already). */ ++ pp = t = 0; ++ for (i = minLen; i < maxLen; i++) { ++ pp += temp[i]; ++ /* We read the largest possible symbol size ++ and then unget bits after determining how ++ many we need, and those extra bits could be ++ set to anything. (They're noise from ++ future symbols.) At each level we're ++ really only interested in the first few ++ bits, so here we set all the trailing ++ to-be-ignored bits to 1 so they don't ++ affect the value > limit[length] ++ comparison. */ ++ limit[i] = (pp << (maxLen - i)) - 1; ++ pp <<= 1; ++ base[i+1] = pp-(t += temp[i]); ++ } ++ limit[maxLen+1] = INT_MAX; /* Sentinal value for ++ * reading next sym. */ ++ limit[maxLen] = pp+temp[maxLen]-1; ++ base[minLen] = 0; ++ } ++ /* We've finished reading and digesting the block header. Now ++ read this block's Huffman coded symbols from the file and ++ undo the Huffman coding and run length encoding, saving the ++ result into dbuf[dbufCount++] = uc */ ++ ++ /* Initialize symbol occurrence counters and symbol Move To ++ * Front table */ ++ for (i = 0; i < 256; i++) { ++ byteCount[i] = 0; ++ mtfSymbol[i] = (unsigned char)i; ++ } ++ /* Loop through compressed symbols. */ ++ runPos = dbufCount = symCount = selector = 0; ++ for (;;) { ++ /* Determine which Huffman coding group to use. */ ++ if (!(symCount--)) { ++ symCount = GROUP_SIZE-1; ++ if (selector >= nSelectors) ++ return RETVAL_DATA_ERROR; ++ hufGroup = bd->groups+selectors[selector++]; ++ base = hufGroup->base-1; ++ limit = hufGroup->limit-1; ++ } ++ /* Read next Huffman-coded symbol. */ ++ /* Note: It is far cheaper to read maxLen bits and ++ back up than it is to read minLen bits and then an ++ additional bit at a time, testing as we go. ++ Because there is a trailing last block (with file ++ CRC), there is no danger of the overread causing an ++ unexpected EOF for a valid compressed file. As a ++ further optimization, we do the read inline ++ (falling back to a call to get_bits if the buffer ++ runs dry). The following (up to got_huff_bits:) is ++ equivalent to j = get_bits(bd, hufGroup->maxLen); ++ */ ++ while (bd->inbufBitCount < hufGroup->maxLen) { ++ if (bd->inbufPos == bd->inbufCount) { ++ j = get_bits(bd, hufGroup->maxLen); ++ goto got_huff_bits; ++ } ++ bd->inbufBits = ++ (bd->inbufBits << 8)|bd->inbuf[bd->inbufPos++]; ++ bd->inbufBitCount += 8; ++ }; ++ bd->inbufBitCount -= hufGroup->maxLen; ++ j = (bd->inbufBits >> bd->inbufBitCount)& ++ ((1 << hufGroup->maxLen)-1); ++got_huff_bits: ++ /* Figure how how many bits are in next symbol and ++ * unget extras */ ++ i = hufGroup->minLen; ++ while (j > limit[i]) ++ ++i; ++ bd->inbufBitCount += (hufGroup->maxLen - i); ++ /* Huffman decode value to get nextSym (with bounds checking) */ ++ if ((i > hufGroup->maxLen) ++ || (((unsigned)(j = (j>>(hufGroup->maxLen-i))-base[i])) ++ >= MAX_SYMBOLS)) ++ return RETVAL_DATA_ERROR; ++ nextSym = hufGroup->permute[j]; ++ /* We have now decoded the symbol, which indicates ++ either a new literal byte, or a repeated run of the ++ most recent literal byte. First, check if nextSym ++ indicates a repeated run, and if so loop collecting ++ how many times to repeat the last literal. */ ++ if (((unsigned)nextSym) <= SYMBOL_RUNB) { /* RUNA or RUNB */ ++ /* If this is the start of a new run, zero out ++ * counter */ ++ if (!runPos) { ++ runPos = 1; ++ t = 0; ++ } ++ /* Neat trick that saves 1 symbol: instead of ++ or-ing 0 or 1 at each bit position, add 1 ++ or 2 instead. For example, 1011 is 1 << 0 ++ + 1 << 1 + 2 << 2. 1010 is 2 << 0 + 2 << 1 ++ + 1 << 2. You can make any bit pattern ++ that way using 1 less symbol than the basic ++ or 0/1 method (except all bits 0, which ++ would use no symbols, but a run of length 0 ++ doesn't mean anything in this context). ++ Thus space is saved. */ ++ t += (runPos << nextSym); ++ /* +runPos if RUNA; +2*runPos if RUNB */ ++ ++ runPos <<= 1; ++ continue; ++ } ++ /* When we hit the first non-run symbol after a run, ++ we now know how many times to repeat the last ++ literal, so append that many copies to our buffer ++ of decoded symbols (dbuf) now. (The last literal ++ used is the one at the head of the mtfSymbol ++ array.) */ ++ if (runPos) { ++ runPos = 0; ++ if (dbufCount+t >= dbufSize) ++ return RETVAL_DATA_ERROR; ++ ++ uc = symToByte[mtfSymbol[0]]; ++ byteCount[uc] += t; ++ while (t--) ++ dbuf[dbufCount++] = uc; ++ } ++ /* Is this the terminating symbol? */ ++ if (nextSym > symTotal) ++ break; ++ /* At this point, nextSym indicates a new literal ++ character. Subtract one to get the position in the ++ MTF array at which this literal is currently to be ++ found. (Note that the result can't be -1 or 0, ++ because 0 and 1 are RUNA and RUNB. But another ++ instance of the first symbol in the mtf array, ++ position 0, would have been handled as part of a ++ run above. Therefore 1 unused mtf position minus 2 ++ non-literal nextSym values equals -1.) */ ++ if (dbufCount >= dbufSize) ++ return RETVAL_DATA_ERROR; ++ i = nextSym - 1; ++ uc = mtfSymbol[i]; ++ /* Adjust the MTF array. Since we typically expect to ++ *move only a small number of symbols, and are bound ++ *by 256 in any case, using memmove here would ++ *typically be bigger and slower due to function call ++ *overhead and other assorted setup costs. */ ++ do { ++ mtfSymbol[i] = mtfSymbol[i-1]; ++ } while (--i); ++ mtfSymbol[0] = uc; ++ uc = symToByte[uc]; ++ /* We have our literal byte. Save it into dbuf. */ ++ byteCount[uc]++; ++ dbuf[dbufCount++] = (unsigned int)uc; ++ } ++ /* At this point, we've read all the Huffman-coded symbols ++ (and repeated runs) for this block from the input stream, ++ and decoded them into the intermediate buffer. There are ++ dbufCount many decoded bytes in dbuf[]. Now undo the ++ Burrows-Wheeler transform on dbuf. See ++ http://dogma.net/markn/articles/bwt/bwt.htm ++ */ ++ /* Turn byteCount into cumulative occurrence counts of 0 to n-1. */ ++ j = 0; ++ for (i = 0; i < 256; i++) { ++ k = j+byteCount[i]; ++ byteCount[i] = j; ++ j = k; ++ } ++ /* Figure out what order dbuf would be in if we sorted it. */ ++ for (i = 0; i < dbufCount; i++) { ++ uc = (unsigned char)(dbuf[i] & 0xff); ++ dbuf[byteCount[uc]] |= (i << 8); ++ byteCount[uc]++; ++ } ++ /* Decode first byte by hand to initialize "previous" byte. ++ Note that it doesn't get output, and if the first three ++ characters are identical it doesn't qualify as a run (hence ++ writeRunCountdown = 5). */ ++ if (dbufCount) { ++ if (origPtr >= dbufCount) ++ return RETVAL_DATA_ERROR; ++ bd->writePos = dbuf[origPtr]; ++ bd->writeCurrent = (unsigned char)(bd->writePos&0xff); ++ bd->writePos >>= 8; ++ bd->writeRunCountdown = 5; ++ } ++ bd->writeCount = dbufCount; ++ ++ return RETVAL_OK; ++} ++ ++/* Undo burrows-wheeler transform on intermediate buffer to produce output. ++ If start_bunzip was initialized with out_fd =-1, then up to len bytes of ++ data are written to outbuf. Return value is number of bytes written or ++ error (all errors are negative numbers). If out_fd!=-1, outbuf and len ++ are ignored, data is written to out_fd and return is RETVAL_OK or error. ++*/ ++ ++static int INIT read_bunzip(struct bunzip_data *bd, char *outbuf, int len) ++{ ++ const unsigned int *dbuf; ++ int pos, xcurrent, previous, gotcount; ++ ++ /* If last read was short due to end of file, return last block now */ ++ if (bd->writeCount < 0) ++ return bd->writeCount; ++ ++ gotcount = 0; ++ dbuf = bd->dbuf; ++ pos = bd->writePos; ++ xcurrent = bd->writeCurrent; ++ ++ /* We will always have pending decoded data to write into the output ++ buffer unless this is the very first call (in which case we haven't ++ Huffman-decoded a block into the intermediate buffer yet). */ ++ ++ if (bd->writeCopies) { ++ /* Inside the loop, writeCopies means extra copies (beyond 1) */ ++ --bd->writeCopies; ++ /* Loop outputting bytes */ ++ for (;;) { ++ /* If the output buffer is full, snapshot ++ * state and return */ ++ if (gotcount >= len) { ++ bd->writePos = pos; ++ bd->writeCurrent = xcurrent; ++ bd->writeCopies++; ++ return len; ++ } ++ /* Write next byte into output buffer, updating CRC */ ++ outbuf[gotcount++] = xcurrent; ++ bd->writeCRC = (((bd->writeCRC) << 8) ++ ^bd->crc32Table[((bd->writeCRC) >> 24) ++ ^xcurrent]); ++ /* Loop now if we're outputting multiple ++ * copies of this byte */ ++ if (bd->writeCopies) { ++ --bd->writeCopies; ++ continue; ++ } ++decode_next_byte: ++ if (!bd->writeCount--) ++ break; ++ /* Follow sequence vector to undo ++ * Burrows-Wheeler transform */ ++ previous = xcurrent; ++ pos = dbuf[pos]; ++ xcurrent = pos&0xff; ++ pos >>= 8; ++ /* After 3 consecutive copies of the same ++ byte, the 4th is a repeat count. We count ++ down from 4 instead *of counting up because ++ testing for non-zero is faster */ ++ if (--bd->writeRunCountdown) { ++ if (xcurrent != previous) ++ bd->writeRunCountdown = 4; ++ } else { ++ /* We have a repeated run, this byte ++ * indicates the count */ ++ bd->writeCopies = xcurrent; ++ xcurrent = previous; ++ bd->writeRunCountdown = 5; ++ /* Sometimes there are just 3 bytes ++ * (run length 0) */ ++ if (!bd->writeCopies) ++ goto decode_next_byte; ++ /* Subtract the 1 copy we'd output ++ * anyway to get extras */ ++ --bd->writeCopies; ++ } ++ } ++ /* Decompression of this block completed successfully */ ++ bd->writeCRC = ~bd->writeCRC; ++ bd->totalCRC = ((bd->totalCRC << 1) | ++ (bd->totalCRC >> 31)) ^ bd->writeCRC; ++ /* If this block had a CRC error, force file level CRC error. */ ++ if (bd->writeCRC != bd->headerCRC) { ++ bd->totalCRC = bd->headerCRC+1; ++ return RETVAL_LAST_BLOCK; ++ } ++ } ++ ++ /* Refill the intermediate buffer by Huffman-decoding next ++ * block of input */ ++ /* (previous is just a convenient unused temp variable here) */ ++ previous = get_next_block(bd); ++ if (previous) { ++ bd->writeCount = previous; ++ return (previous != RETVAL_LAST_BLOCK) ? previous : gotcount; ++ } ++ bd->writeCRC = 0xffffffffUL; ++ pos = bd->writePos; ++ xcurrent = bd->writeCurrent; ++ goto decode_next_byte; ++} ++ ++static int INIT nofill(void *buf, unsigned int len) ++{ ++ return -1; ++} ++ ++/* Allocate the structure, read file header. If in_fd ==-1, inbuf must contain ++ a complete bunzip file (len bytes long). If in_fd!=-1, inbuf and len are ++ ignored, and data is read from file handle into temporary buffer. */ ++static int INIT start_bunzip(struct bunzip_data **bdp, void *inbuf, int len, ++ int (*fill)(void*, unsigned int)) ++{ ++ struct bunzip_data *bd; ++ unsigned int i, j, c; ++ const unsigned int BZh0 = ++ (((unsigned int)'B') << 24)+(((unsigned int)'Z') << 16) ++ +(((unsigned int)'h') << 8)+(unsigned int)'0'; ++ ++ /* Figure out how much data to allocate */ ++ i = sizeof(struct bunzip_data); ++ ++ /* Allocate bunzip_data. Most fields initialize to zero. */ ++ bd = *bdp = malloc(i); ++ memset(bd, 0, sizeof(struct bunzip_data)); ++ /* Setup input buffer */ ++ bd->inbuf = inbuf; ++ bd->inbufCount = len; ++ if (fill != NULL) ++ bd->fill = fill; ++ else ++ bd->fill = nofill; ++ ++ /* Init the CRC32 table (big endian) */ ++ for (i = 0; i < 256; i++) { ++ c = i << 24; ++ for (j = 8; j; j--) ++ c = c&0x80000000 ? (c << 1)^0x04c11db7 : (c << 1); ++ bd->crc32Table[i] = c; ++ } ++ ++ /* Ensure that file starts with "BZh['1'-'9']." */ ++ i = get_bits(bd, 32); ++ if (((unsigned int)(i-BZh0-1)) >= 9) ++ return RETVAL_NOT_BZIP_DATA; ++ ++ /* Fourth byte (ascii '1'-'9'), indicates block size in units of 100k of ++ uncompressed data. Allocate intermediate buffer for block. */ ++ bd->dbufSize = 100000*(i-BZh0); ++ ++ bd->dbuf = large_malloc(bd->dbufSize * sizeof(int)); ++ return RETVAL_OK; ++} ++ ++/* Example usage: decompress src_fd to dst_fd. (Stops at end of bzip2 data, ++ not end of file.) */ ++STATIC int INIT bunzip2(unsigned char *buf, int len, ++ int(*fill)(void*, unsigned int), ++ int(*flush)(void*, unsigned int), ++ unsigned char *outbuf, ++ int *pos, ++ void(*error_fn)(char *x)) ++{ ++ struct bunzip_data *bd; ++ int i = -1; ++ unsigned char *inbuf; ++ ++ set_error_fn(error_fn); ++ if (flush) ++ outbuf = malloc(BZIP2_IOBUF_SIZE); ++ else ++ len -= 4; /* Uncompressed size hack active in pre-boot ++ environment */ ++ if (!outbuf) { ++ error("Could not allocate output bufer"); ++ return -1; ++ } ++ if (buf) ++ inbuf = buf; ++ else ++ inbuf = malloc(BZIP2_IOBUF_SIZE); ++ if (!inbuf) { ++ error("Could not allocate input bufer"); ++ goto exit_0; ++ } ++ i = start_bunzip(&bd, inbuf, len, fill); ++ if (!i) { ++ for (;;) { ++ i = read_bunzip(bd, outbuf, BZIP2_IOBUF_SIZE); ++ if (i <= 0) ++ break; ++ if (!flush) ++ outbuf += i; ++ else ++ if (i != flush(outbuf, i)) { ++ i = RETVAL_UNEXPECTED_OUTPUT_EOF; ++ break; ++ } ++ } ++ } ++ /* Check CRC and release memory */ ++ if (i == RETVAL_LAST_BLOCK) { ++ if (bd->headerCRC != bd->totalCRC) ++ error("Data integrity error when decompressing."); ++ else ++ i = RETVAL_OK; ++ } else if (i == RETVAL_UNEXPECTED_OUTPUT_EOF) { ++ error("Compressed file ends unexpectedly"); ++ } ++ if (bd->dbuf) ++ large_free(bd->dbuf); ++ if (pos) ++ *pos = bd->inbufPos; ++ free(bd); ++ if (!buf) ++ free(inbuf); ++exit_0: ++ if (flush) ++ free(outbuf); ++ return i; ++} ++ ++#define decompress bunzip2 +diff -urN linux-2.6.28.9/lib/decompress_unlzma.c linux-2.6.28.9.new/lib/decompress_unlzma.c +--- linux-2.6.28.9/lib/decompress_unlzma.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.28.9.new/lib/decompress_unlzma.c 2009-04-24 14:08:08.000000000 +0200 +@@ -0,0 +1,647 @@ ++/* Lzma decompressor for Linux kernel. Shamelessly snarfed ++ *from busybox 1.1.1 ++ * ++ *Linux kernel adaptation ++ *Copyright (C) 2006 Alain < alain@knaff.lu > ++ * ++ *Based on small lzma deflate implementation/Small range coder ++ *implementation for lzma. ++ *Copyright (C) 2006 Aurelien Jacobs < aurel@gnuage.org > ++ * ++ *Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/) ++ *Copyright (C) 1999-2005 Igor Pavlov ++ * ++ *Copyrights of the parts, see headers below. ++ * ++ * ++ *This program is free software; you can redistribute it and/or ++ *modify it under the terms of the GNU Lesser General Public ++ *License as published by the Free Software Foundation; either ++ *version 2.1 of the License, or (at your option) any later version. ++ * ++ *This program is distributed in the hope that it will be useful, ++ *but WITHOUT ANY WARRANTY; without even the implied warranty of ++ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ *Lesser General Public License for more details. ++ * ++ *You should have received a copy of the GNU Lesser General Public ++ *License along with this library; if not, write to the Free Software ++ *Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#ifndef STATIC ++#include ++#endif /* STATIC */ ++ ++#include ++ ++#define MIN(a, b) (((a) < (b)) ? (a) : (b)) ++ ++static long long INIT read_int(unsigned char *ptr, int size) ++{ ++ int i; ++ long long ret = 0; ++ ++ for (i = 0; i < size; i++) ++ ret = (ret << 8) | ptr[size-i-1]; ++ return ret; ++} ++ ++#define ENDIAN_CONVERT(x) \ ++ x = (typeof(x))read_int((unsigned char *)&x, sizeof(x)) ++ ++ ++/* Small range coder implementation for lzma. ++ *Copyright (C) 2006 Aurelien Jacobs < aurel@gnuage.org > ++ * ++ *Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/) ++ *Copyright (c) 1999-2005 Igor Pavlov ++ */ ++ ++#include ++ ++#define LZMA_IOBUF_SIZE 0x10000 ++ ++struct rc { ++ int (*fill)(void*, unsigned int); ++ uint8_t *ptr; ++ uint8_t *buffer; ++ uint8_t *buffer_end; ++ int buffer_size; ++ uint32_t code; ++ uint32_t range; ++ uint32_t bound; ++}; ++ ++ ++#define RC_TOP_BITS 24 ++#define RC_MOVE_BITS 5 ++#define RC_MODEL_TOTAL_BITS 11 ++ ++ ++/* Called twice: once at startup and once in rc_normalize() */ ++static void INIT rc_read(struct rc *rc) ++{ ++ rc->buffer_size = rc->fill((char *)rc->buffer, LZMA_IOBUF_SIZE); ++ if (rc->buffer_size <= 0) ++ error("unexpected EOF"); ++ rc->ptr = rc->buffer; ++ rc->buffer_end = rc->buffer + rc->buffer_size; ++} ++ ++/* Called once */ ++static inline void INIT rc_init(struct rc *rc, ++ int (*fill)(void*, unsigned int), ++ char *buffer, int buffer_size) ++{ ++ rc->fill = fill; ++ rc->buffer = (uint8_t *)buffer; ++ rc->buffer_size = buffer_size; ++ rc->buffer_end = rc->buffer + rc->buffer_size; ++ rc->ptr = rc->buffer; ++ ++ rc->code = 0; ++ rc->range = 0xFFFFFFFF; ++} ++ ++static inline void INIT rc_init_code(struct rc *rc) ++{ ++ int i; ++ ++ for (i = 0; i < 5; i++) { ++ if (rc->ptr >= rc->buffer_end) ++ rc_read(rc); ++ rc->code = (rc->code << 8) | *rc->ptr++; ++ } ++} ++ ++ ++/* Called once. TODO: bb_maybe_free() */ ++static inline void INIT rc_free(struct rc *rc) ++{ ++ free(rc->buffer); ++} ++ ++/* Called twice, but one callsite is in inline'd rc_is_bit_0_helper() */ ++static void INIT rc_do_normalize(struct rc *rc) ++{ ++ if (rc->ptr >= rc->buffer_end) ++ rc_read(rc); ++ rc->range <<= 8; ++ rc->code = (rc->code << 8) | *rc->ptr++; ++} ++static inline void INIT rc_normalize(struct rc *rc) ++{ ++ if (rc->range < (1 << RC_TOP_BITS)) ++ rc_do_normalize(rc); ++} ++ ++/* Called 9 times */ ++/* Why rc_is_bit_0_helper exists? ++ *Because we want to always expose (rc->code < rc->bound) to optimizer ++ */ ++static inline uint32_t INIT rc_is_bit_0_helper(struct rc *rc, uint16_t *p) ++{ ++ rc_normalize(rc); ++ rc->bound = *p * (rc->range >> RC_MODEL_TOTAL_BITS); ++ return rc->bound; ++} ++static inline int INIT rc_is_bit_0(struct rc *rc, uint16_t *p) ++{ ++ uint32_t t = rc_is_bit_0_helper(rc, p); ++ return rc->code < t; ++} ++ ++/* Called ~10 times, but very small, thus inlined */ ++static inline void INIT rc_update_bit_0(struct rc *rc, uint16_t *p) ++{ ++ rc->range = rc->bound; ++ *p += ((1 << RC_MODEL_TOTAL_BITS) - *p) >> RC_MOVE_BITS; ++} ++static inline void rc_update_bit_1(struct rc *rc, uint16_t *p) ++{ ++ rc->range -= rc->bound; ++ rc->code -= rc->bound; ++ *p -= *p >> RC_MOVE_BITS; ++} ++ ++/* Called 4 times in unlzma loop */ ++static int INIT rc_get_bit(struct rc *rc, uint16_t *p, int *symbol) ++{ ++ if (rc_is_bit_0(rc, p)) { ++ rc_update_bit_0(rc, p); ++ *symbol *= 2; ++ return 0; ++ } else { ++ rc_update_bit_1(rc, p); ++ *symbol = *symbol * 2 + 1; ++ return 1; ++ } ++} ++ ++/* Called once */ ++static inline int INIT rc_direct_bit(struct rc *rc) ++{ ++ rc_normalize(rc); ++ rc->range >>= 1; ++ if (rc->code >= rc->range) { ++ rc->code -= rc->range; ++ return 1; ++ } ++ return 0; ++} ++ ++/* Called twice */ ++static inline void INIT ++rc_bit_tree_decode(struct rc *rc, uint16_t *p, int num_levels, int *symbol) ++{ ++ int i = num_levels; ++ ++ *symbol = 1; ++ while (i--) ++ rc_get_bit(rc, p + *symbol, symbol); ++ *symbol -= 1 << num_levels; ++} ++ ++ ++/* ++ * Small lzma deflate implementation. ++ * Copyright (C) 2006 Aurelien Jacobs < aurel@gnuage.org > ++ * ++ * Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/) ++ * Copyright (C) 1999-2005 Igor Pavlov ++ */ ++ ++ ++struct lzma_header { ++ uint8_t pos; ++ uint32_t dict_size; ++ uint64_t dst_size; ++} __attribute__ ((packed)) ; ++ ++ ++#define LZMA_BASE_SIZE 1846 ++#define LZMA_LIT_SIZE 768 ++ ++#define LZMA_NUM_POS_BITS_MAX 4 ++ ++#define LZMA_LEN_NUM_LOW_BITS 3 ++#define LZMA_LEN_NUM_MID_BITS 3 ++#define LZMA_LEN_NUM_HIGH_BITS 8 ++ ++#define LZMA_LEN_CHOICE 0 ++#define LZMA_LEN_CHOICE_2 (LZMA_LEN_CHOICE + 1) ++#define LZMA_LEN_LOW (LZMA_LEN_CHOICE_2 + 1) ++#define LZMA_LEN_MID (LZMA_LEN_LOW \ ++ + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS))) ++#define LZMA_LEN_HIGH (LZMA_LEN_MID \ ++ +(1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS))) ++#define LZMA_NUM_LEN_PROBS (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS)) ++ ++#define LZMA_NUM_STATES 12 ++#define LZMA_NUM_LIT_STATES 7 ++ ++#define LZMA_START_POS_MODEL_INDEX 4 ++#define LZMA_END_POS_MODEL_INDEX 14 ++#define LZMA_NUM_FULL_DISTANCES (1 << (LZMA_END_POS_MODEL_INDEX >> 1)) ++ ++#define LZMA_NUM_POS_SLOT_BITS 6 ++#define LZMA_NUM_LEN_TO_POS_STATES 4 ++ ++#define LZMA_NUM_ALIGN_BITS 4 ++ ++#define LZMA_MATCH_MIN_LEN 2 ++ ++#define LZMA_IS_MATCH 0 ++#define LZMA_IS_REP (LZMA_IS_MATCH + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)) ++#define LZMA_IS_REP_G0 (LZMA_IS_REP + LZMA_NUM_STATES) ++#define LZMA_IS_REP_G1 (LZMA_IS_REP_G0 + LZMA_NUM_STATES) ++#define LZMA_IS_REP_G2 (LZMA_IS_REP_G1 + LZMA_NUM_STATES) ++#define LZMA_IS_REP_0_LONG (LZMA_IS_REP_G2 + LZMA_NUM_STATES) ++#define LZMA_POS_SLOT (LZMA_IS_REP_0_LONG \ ++ + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)) ++#define LZMA_SPEC_POS (LZMA_POS_SLOT \ ++ +(LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS)) ++#define LZMA_ALIGN (LZMA_SPEC_POS \ ++ + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX) ++#define LZMA_LEN_CODER (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS)) ++#define LZMA_REP_LEN_CODER (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS) ++#define LZMA_LITERAL (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS) ++ ++ ++struct writer { ++ uint8_t *buffer; ++ uint8_t previous_byte; ++ size_t buffer_pos; ++ int bufsize; ++ size_t global_pos; ++ int(*flush)(void*, unsigned int); ++ struct lzma_header *header; ++}; ++ ++struct cstate { ++ int state; ++ uint32_t rep0, rep1, rep2, rep3; ++}; ++ ++static inline size_t INIT get_pos(struct writer *wr) ++{ ++ return ++ wr->global_pos + wr->buffer_pos; ++} ++ ++static inline uint8_t INIT peek_old_byte(struct writer *wr, ++ uint32_t offs) ++{ ++ if (!wr->flush) { ++ int32_t pos; ++ while (offs > wr->header->dict_size) ++ offs -= wr->header->dict_size; ++ pos = wr->buffer_pos - offs; ++ return wr->buffer[pos]; ++ } else { ++ uint32_t pos = wr->buffer_pos - offs; ++ while (pos >= wr->header->dict_size) ++ pos += wr->header->dict_size; ++ return wr->buffer[pos]; ++ } ++ ++} ++ ++static inline void INIT write_byte(struct writer *wr, uint8_t byte) ++{ ++ wr->buffer[wr->buffer_pos++] = wr->previous_byte = byte; ++ if (wr->flush && wr->buffer_pos == wr->header->dict_size) { ++ wr->buffer_pos = 0; ++ wr->global_pos += wr->header->dict_size; ++ wr->flush((char *)wr->buffer, wr->header->dict_size); ++ } ++} ++ ++ ++static inline void INIT copy_byte(struct writer *wr, uint32_t offs) ++{ ++ write_byte(wr, peek_old_byte(wr, offs)); ++} ++ ++static inline void INIT copy_bytes(struct writer *wr, ++ uint32_t rep0, int len) ++{ ++ do { ++ copy_byte(wr, rep0); ++ len--; ++ } while (len != 0 && wr->buffer_pos < wr->header->dst_size); ++} ++ ++static inline void INIT process_bit0(struct writer *wr, struct rc *rc, ++ struct cstate *cst, uint16_t *p, ++ int pos_state, uint16_t *prob, ++ int lc, uint32_t literal_pos_mask) { ++ int mi = 1; ++ rc_update_bit_0(rc, prob); ++ prob = (p + LZMA_LITERAL + ++ (LZMA_LIT_SIZE ++ * (((get_pos(wr) & literal_pos_mask) << lc) ++ + (wr->previous_byte >> (8 - lc)))) ++ ); ++ ++ if (cst->state >= LZMA_NUM_LIT_STATES) { ++ int match_byte = peek_old_byte(wr, cst->rep0); ++ do { ++ int bit; ++ uint16_t *prob_lit; ++ ++ match_byte <<= 1; ++ bit = match_byte & 0x100; ++ prob_lit = prob + 0x100 + bit + mi; ++ if (rc_get_bit(rc, prob_lit, &mi)) { ++ if (!bit) ++ break; ++ } else { ++ if (bit) ++ break; ++ } ++ } while (mi < 0x100); ++ } ++ while (mi < 0x100) { ++ uint16_t *prob_lit = prob + mi; ++ rc_get_bit(rc, prob_lit, &mi); ++ } ++ write_byte(wr, mi); ++ if (cst->state < 4) ++ cst->state = 0; ++ else if (cst->state < 10) ++ cst->state -= 3; ++ else ++ cst->state -= 6; ++} ++ ++static inline void INIT process_bit1(struct writer *wr, struct rc *rc, ++ struct cstate *cst, uint16_t *p, ++ int pos_state, uint16_t *prob) { ++ int offset; ++ uint16_t *prob_len; ++ int num_bits; ++ int len; ++ ++ rc_update_bit_1(rc, prob); ++ prob = p + LZMA_IS_REP + cst->state; ++ if (rc_is_bit_0(rc, prob)) { ++ rc_update_bit_0(rc, prob); ++ cst->rep3 = cst->rep2; ++ cst->rep2 = cst->rep1; ++ cst->rep1 = cst->rep0; ++ cst->state = cst->state < LZMA_NUM_LIT_STATES ? 0 : 3; ++ prob = p + LZMA_LEN_CODER; ++ } else { ++ rc_update_bit_1(rc, prob); ++ prob = p + LZMA_IS_REP_G0 + cst->state; ++ if (rc_is_bit_0(rc, prob)) { ++ rc_update_bit_0(rc, prob); ++ prob = (p + LZMA_IS_REP_0_LONG ++ + (cst->state << ++ LZMA_NUM_POS_BITS_MAX) + ++ pos_state); ++ if (rc_is_bit_0(rc, prob)) { ++ rc_update_bit_0(rc, prob); ++ ++ cst->state = cst->state < LZMA_NUM_LIT_STATES ? ++ 9 : 11; ++ copy_byte(wr, cst->rep0); ++ return; ++ } else { ++ rc_update_bit_1(rc, prob); ++ } ++ } else { ++ uint32_t distance; ++ ++ rc_update_bit_1(rc, prob); ++ prob = p + LZMA_IS_REP_G1 + cst->state; ++ if (rc_is_bit_0(rc, prob)) { ++ rc_update_bit_0(rc, prob); ++ distance = cst->rep1; ++ } else { ++ rc_update_bit_1(rc, prob); ++ prob = p + LZMA_IS_REP_G2 + cst->state; ++ if (rc_is_bit_0(rc, prob)) { ++ rc_update_bit_0(rc, prob); ++ distance = cst->rep2; ++ } else { ++ rc_update_bit_1(rc, prob); ++ distance = cst->rep3; ++ cst->rep3 = cst->rep2; ++ } ++ cst->rep2 = cst->rep1; ++ } ++ cst->rep1 = cst->rep0; ++ cst->rep0 = distance; ++ } ++ cst->state = cst->state < LZMA_NUM_LIT_STATES ? 8 : 11; ++ prob = p + LZMA_REP_LEN_CODER; ++ } ++ ++ prob_len = prob + LZMA_LEN_CHOICE; ++ if (rc_is_bit_0(rc, prob_len)) { ++ rc_update_bit_0(rc, prob_len); ++ prob_len = (prob + LZMA_LEN_LOW ++ + (pos_state << ++ LZMA_LEN_NUM_LOW_BITS)); ++ offset = 0; ++ num_bits = LZMA_LEN_NUM_LOW_BITS; ++ } else { ++ rc_update_bit_1(rc, prob_len); ++ prob_len = prob + LZMA_LEN_CHOICE_2; ++ if (rc_is_bit_0(rc, prob_len)) { ++ rc_update_bit_0(rc, prob_len); ++ prob_len = (prob + LZMA_LEN_MID ++ + (pos_state << ++ LZMA_LEN_NUM_MID_BITS)); ++ offset = 1 << LZMA_LEN_NUM_LOW_BITS; ++ num_bits = LZMA_LEN_NUM_MID_BITS; ++ } else { ++ rc_update_bit_1(rc, prob_len); ++ prob_len = prob + LZMA_LEN_HIGH; ++ offset = ((1 << LZMA_LEN_NUM_LOW_BITS) ++ + (1 << LZMA_LEN_NUM_MID_BITS)); ++ num_bits = LZMA_LEN_NUM_HIGH_BITS; ++ } ++ } ++ ++ rc_bit_tree_decode(rc, prob_len, num_bits, &len); ++ len += offset; ++ ++ if (cst->state < 4) { ++ int pos_slot; ++ ++ cst->state += LZMA_NUM_LIT_STATES; ++ prob = ++ p + LZMA_POS_SLOT + ++ ((len < ++ LZMA_NUM_LEN_TO_POS_STATES ? len : ++ LZMA_NUM_LEN_TO_POS_STATES - 1) ++ << LZMA_NUM_POS_SLOT_BITS); ++ rc_bit_tree_decode(rc, prob, ++ LZMA_NUM_POS_SLOT_BITS, ++ &pos_slot); ++ if (pos_slot >= LZMA_START_POS_MODEL_INDEX) { ++ int i, mi; ++ num_bits = (pos_slot >> 1) - 1; ++ cst->rep0 = 2 | (pos_slot & 1); ++ if (pos_slot < LZMA_END_POS_MODEL_INDEX) { ++ cst->rep0 <<= num_bits; ++ prob = p + LZMA_SPEC_POS + ++ cst->rep0 - pos_slot - 1; ++ } else { ++ num_bits -= LZMA_NUM_ALIGN_BITS; ++ while (num_bits--) ++ cst->rep0 = (cst->rep0 << 1) | ++ rc_direct_bit(rc); ++ prob = p + LZMA_ALIGN; ++ cst->rep0 <<= LZMA_NUM_ALIGN_BITS; ++ num_bits = LZMA_NUM_ALIGN_BITS; ++ } ++ i = 1; ++ mi = 1; ++ while (num_bits--) { ++ if (rc_get_bit(rc, prob + mi, &mi)) ++ cst->rep0 |= i; ++ i <<= 1; ++ } ++ } else ++ cst->rep0 = pos_slot; ++ if (++(cst->rep0) == 0) ++ return; ++ } ++ ++ len += LZMA_MATCH_MIN_LEN; ++ ++ copy_bytes(wr, cst->rep0, len); ++} ++ ++ ++ ++STATIC inline int INIT unlzma(unsigned char *buf, int in_len, ++ int(*fill)(void*, unsigned int), ++ int(*flush)(void*, unsigned int), ++ unsigned char *output, ++ int *posp, ++ void(*error_fn)(char *x) ++ ) ++{ ++ struct lzma_header header; ++ int lc, pb, lp; ++ uint32_t pos_state_mask; ++ uint32_t literal_pos_mask; ++ uint16_t *p; ++ int num_probs; ++ struct rc rc; ++ int i, mi; ++ struct writer wr; ++ struct cstate cst; ++ unsigned char *inbuf; ++ int ret = -1; ++ ++ set_error_fn(error_fn); ++ if (!flush) ++ in_len -= 4; /* Uncompressed size hack active in pre-boot ++ environment */ ++ if (buf) ++ inbuf = buf; ++ else ++ inbuf = malloc(LZMA_IOBUF_SIZE); ++ if (!inbuf) { ++ error("Could not allocate input bufer"); ++ goto exit_0; ++ } ++ ++ cst.state = 0; ++ cst.rep0 = cst.rep1 = cst.rep2 = cst.rep3 = 1; ++ ++ wr.header = &header; ++ wr.flush = flush; ++ wr.global_pos = 0; ++ wr.previous_byte = 0; ++ wr.buffer_pos = 0; ++ ++ rc_init(&rc, fill, inbuf, in_len); ++ ++ for (i = 0; i < sizeof(header); i++) { ++ if (rc.ptr >= rc.buffer_end) ++ rc_read(&rc); ++ ((unsigned char *)&header)[i] = *rc.ptr++; ++ } ++ ++ if (header.pos >= (9 * 5 * 5)) ++ error("bad header"); ++ ++ mi = 0; ++ lc = header.pos; ++ while (lc >= 9) { ++ mi++; ++ lc -= 9; ++ } ++ pb = 0; ++ lp = mi; ++ while (lp >= 5) { ++ pb++; ++ lp -= 5; ++ } ++ pos_state_mask = (1 << pb) - 1; ++ literal_pos_mask = (1 << lp) - 1; ++ ++ ENDIAN_CONVERT(header.dict_size); ++ ENDIAN_CONVERT(header.dst_size); ++ ++ if (header.dict_size == 0) ++ header.dict_size = 1; ++ ++ if (output) ++ wr.buffer = output; ++ else { ++ wr.bufsize = MIN(header.dst_size, header.dict_size); ++ wr.buffer = large_malloc(wr.bufsize); ++ } ++ if (wr.buffer == NULL) ++ goto exit_1; ++ ++ num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)); ++ p = (uint16_t *) large_malloc(num_probs * sizeof(*p)); ++ if (p == 0) ++ goto exit_2; ++ num_probs = LZMA_LITERAL + (LZMA_LIT_SIZE << (lc + lp)); ++ for (i = 0; i < num_probs; i++) ++ p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1; ++ ++ rc_init_code(&rc); ++ ++ while (get_pos(&wr) < header.dst_size) { ++ int pos_state = get_pos(&wr) & pos_state_mask; ++ uint16_t *prob = p + LZMA_IS_MATCH + ++ (cst.state << LZMA_NUM_POS_BITS_MAX) + pos_state; ++ if (rc_is_bit_0(&rc, prob)) ++ process_bit0(&wr, &rc, &cst, p, pos_state, prob, ++ lc, literal_pos_mask); ++ else { ++ process_bit1(&wr, &rc, &cst, p, pos_state, prob); ++ if (cst.rep0 == 0) ++ break; ++ } ++ } ++ ++ if (posp) ++ *posp = rc.ptr-rc.buffer; ++ if (wr.flush) ++ wr.flush(wr.buffer, wr.buffer_pos); ++ ret = 0; ++ large_free(p); ++exit_2: ++ if (!output) ++ large_free(wr.buffer); ++exit_1: ++ if (!buf) ++ free(inbuf); ++exit_0: ++ return ret; ++} ++ ++#define decompress unlzma +diff -urN linux-2.6.28.9/lib/inflate.c linux-2.6.28.9.new/lib/inflate.c +--- linux-2.6.28.9/lib/inflate.c 2009-03-23 22:55:52.000000000 +0100 ++++ linux-2.6.28.9.new/lib/inflate.c 2009-04-24 14:08:08.000000000 +0200 +@@ -109,20 +109,78 @@ + #endif + + #ifndef STATIC ++#include ++#endif /* ! STATIC */ + +-#if defined(STDC_HEADERS) || defined(HAVE_STDLIB_H) +-# include +-# include ++#include ++ ++#include ++ ++#ifdef NEW_CODE ++static int(*flush_cb)(void*, unsigned int); ++static int(*fill_cb)(void*, unsigned int); ++ ++/* Begin stuff copied from initramfs */ ++/* ++ * gzip declarations ++ */ ++ ++#define OF(args) args ++ ++#ifndef memzero ++#define memzero(s, n) memset((s), 0, (n)) + #endif + +-#include "gzip.h" +-#define STATIC +-#endif /* !STATIC */ ++#define INBUFSIZ 4096 ++ ++#define WSIZE 0x8000 /* window size--must be a power of two, and */ ++ /* at least 32K for zip's deflate method */ ++ ++static uint8_t *inbuf; ++static uint8_t *window; ++ ++static unsigned insize; /* valid bytes in inbuf */ ++static unsigned outcnt; /* bytes in output buffer */ ++static long bytes_out; ++ ++/* --- */ ++ ++static unsigned inptr; /* index of next byte to be processed in inbuf */ ++ ++/* --- */ ++ ++/* =========================================================================== ++ * Fill the input buffer. This is called only when the buffer is empty ++ * and at least one byte is really needed. ++ * Returning -1 does not guarantee that gunzip() will ever return. ++ */ ++static int INIT fill_inbuf(void) ++{ ++ insize = fill_cb(inbuf, INBUFSIZ); ++ if (insize <= 0) { ++ error("RAMDISK: ran out of compressed data"); ++ return -1; ++ } ++ ++ inptr = 1; ++ ++ return inbuf[0]; ++} ++ ++#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) ++ ++/* Diagnostic functions (stubbed out) */ ++#define Assert(cond, msg) ++#define Trace(x) ++#define Tracev(x) ++#define Tracevv(x) ++#define Tracec(c, x) ++#define Tracecv(c, x) + +-#ifndef INIT +-#define INIT ++static void flush_window(void); ++/* End stuff copied from initramfs */ + #endif +- ++ + #define slide window + + /* Huffman code lookup table entry--this entry is four bytes for machines +@@ -133,10 +191,10 @@ + an unused code. If a code with e == 99 is looked up, this implies an + error in the data. */ + struct huft { +- uch e; /* number of extra bits or operation */ +- uch b; /* number of bits in this code or subcode */ ++ uint8_t e; /* number of extra bits or operation */ ++ uint8_t b; /* number of bits in this code or subcode */ + union { +- ush n; /* literal, length base, or distance base */ ++ uint16_t n; /* literal, length base, or distance base */ + struct huft *t; /* pointer to next level of table */ + } v; + }; +@@ -144,7 +202,7 @@ + + /* Function prototypes */ + STATIC int INIT huft_build OF((unsigned *, unsigned, unsigned, +- const ush *, const ush *, struct huft **, int *)); ++ const uint16_t *, const uint16_t *, struct huft **, int *)); + STATIC int INIT huft_free OF((struct huft *)); + STATIC int INIT inflate_codes OF((struct huft *, struct huft *, int, int)); + STATIC int INIT inflate_stored OF((void)); +@@ -159,28 +217,28 @@ + circular buffer. The index is updated simply by incrementing and then + ANDing with 0x7fff (32K-1). */ + /* It is left to other modules to supply the 32 K area. It is assumed +- to be usable as if it were declared "uch slide[32768];" or as just +- "uch *slide;" and then malloc'ed in the latter case. The definition ++ to be usable as if it were declared "uint8_t slide[32768];" or as just ++ "uint8_t *slide;" and then malloc'ed in the latter case. The definition + must be in unzip.h, included above. */ + /* unsigned wp; current position in slide */ + #define wp outcnt + #define flush_output(w) (wp=(w),flush_window()) + + /* Tables for deflate from PKZIP's appnote.txt. */ +-static const unsigned border[] = { /* Order of the bit length code lengths */ ++static const unsigned border[] = { /* Order of the bit length code lengths */ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; +-static const ush cplens[] = { /* Copy lengths for literal codes 257..285 */ ++static const uint16_t cplens[] = { /* Copy lengths for literal codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* note: see note #13 above about the 258 in this list. */ +-static const ush cplext[] = { /* Extra bits for literal codes 257..285 */ ++static const uint16_t cplext[] = { /* Extra bits for literal codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */ +-static const ush cpdist[] = { /* Copy offsets for distance codes 0..29 */ ++static const uint16_t cpdist[] = { /* Copy offsets for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; +-static const ush cpdext[] = { /* Extra bits for distance codes */ ++static const uint16_t cpdext[] = { /* Extra bits for distance codes */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; +@@ -217,59 +275,21 @@ + the stream. + */ + +-STATIC ulg bb; /* bit buffer */ ++STATIC uint32_t bb; /* bit buffer */ + STATIC unsigned bk; /* bits in bit buffer */ + +-STATIC const ush mask_bits[] = { ++STATIC const uint16_t mask_bits[] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff + }; + +-#define NEXTBYTE() ({ int v = get_byte(); if (v < 0) goto underrun; (uch)v; }) +-#define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<>=(n);k-=(n);} + +-#ifndef NO_INFLATE_MALLOC +-/* A trivial malloc implementation, adapted from +- * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 +- */ +- +-static unsigned long malloc_ptr; +-static int malloc_count; +- +-static void *malloc(int size) +-{ +- void *p; +- +- if (size < 0) +- error("Malloc error"); +- if (!malloc_ptr) +- malloc_ptr = free_mem_ptr; +- +- malloc_ptr = (malloc_ptr + 3) & ~3; /* Align */ +- +- p = (void *)malloc_ptr; +- malloc_ptr += size; +- +- if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr) +- error("Out of memory"); +- +- malloc_count++; +- return p; +-} +- +-static void free(void *where) +-{ +- malloc_count--; +- if (!malloc_count) +- malloc_ptr = free_mem_ptr; +-} +-#else +-#define malloc(a) kmalloc(a, GFP_KERNEL) +-#define free(a) kfree(a) +-#endif +- + /* + Huffman code decoding is performed using a multi-level table lookup. + The fastest way to decode is to simply build a lookup table whose +@@ -307,7 +327,7 @@ + STATIC const int dbits = 6; /* bits in base distance lookup table */ + + +-/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ ++/* If BMAX needs to be larger than 16, then h and x[] should be uint32_t. */ + #define BMAX 16 /* maximum bit length of any code (16 for explode) */ + #define N_MAX 288 /* maximum number of codes in any set */ + +@@ -319,8 +339,8 @@ + unsigned *b, /* code lengths in bits (all assumed <= BMAX) */ + unsigned n, /* number of codes (assumed <= N_MAX) */ + unsigned s, /* number of simple-valued codes (0..s-1) */ +- const ush *d, /* list of base values for non-simple codes */ +- const ush *e, /* list of extra bits for non-simple codes */ ++ const uint16_t *d, /* list of base values for non-simple codes */ ++ const uint16_t *e, /* list of extra bits for non-simple codes */ + struct huft **t, /* result: starting table */ + int *m /* maximum lookup bits, returns actual */ + ) +@@ -500,8 +520,8 @@ + if (h) + { + x[h] = i; /* save pattern for backing up */ +- r.b = (uch)l; /* bits to dump before this table */ +- r.e = (uch)(16 + j); /* bits in this table */ ++ r.b = (uint8_t)l; /* bits to dump before this table */ ++ r.e = (uint8_t)(16 + j); /* bits in this table */ + r.v.t = q; /* pointer to this table */ + j = i >> (w - l); /* (get around Turbo C bug) */ + u[h-1][j] = r; /* connect to last table */ +@@ -511,18 +531,18 @@ + DEBG("h6c "); + + /* set up table entry in r */ +- r.b = (uch)(k - w); ++ r.b = (uint8_t)(k - w); + if (p >= v + n) + r.e = 99; /* out of values--invalid code */ + else if (*p < s) + { +- r.e = (uch)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */ +- r.v.n = (ush)(*p); /* simple code is just the value */ ++ r.e = (uint8_t)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */ ++ r.v.n = (uint16_t)(*p); /* simple code is just the value */ + p++; /* one compiler does not like *p++ */ + } + else + { +- r.e = (uch)e[*p - s]; /* non-simple--look up in lists */ ++ r.e = (uint8_t)e[*p - s]; /* non-simple--look up in lists */ + r.v.n = d[*p++ - s]; + } + DEBG("h6d "); +@@ -592,11 +612,12 @@ + Return an error code or zero if it all goes ok. */ + { + register unsigned e; /* table entry flag/number of extra bits */ +- unsigned n, d; /* length and index for copy */ ++ unsigned n; ++ int d; /* source index for copy */ + unsigned w; /* current window position */ + struct huft *t; /* pointer to table entry */ + unsigned ml, md; /* masks for bl and bd bits */ +- register ulg b; /* bit buffer */ ++ register uint32_t b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + + +@@ -622,7 +643,7 @@ + DUMPBITS(t->b) + if (e == 16) /* then it's a literal */ + { +- slide[w++] = (uch)t->v.n; ++ slide[w++] = (uint8_t)t->v.n; + Tracevv((stderr, "%c", slide[w-1])); + if (w == WSIZE) + { +@@ -659,11 +680,25 @@ + + /* do the copy */ + do { +- n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); ++#ifdef NEW_CODE ++ if (flush_cb) { ++#endif ++ /* Sliding window emulated using circular buffer: ++ * manage wrap-around */ ++ e = WSIZE - ((d &= WSIZE-1) > w ? d : w); ++ if (e > n) ++ e = n; ++#ifdef NEW_CODE ++ } else { ++ e = n; ++ } ++#endif ++ n -= e; ++ + #if !defined(NOMEMCPY) && !defined(DEBUG) + if (w - d >= e) /* (this test assumes unsigned comparison) */ + { +- memcpy(slide + w, slide + d, e); ++ memcpy(slide + w, slide + d, e); + w += e; + d += e; + } +@@ -673,9 +708,8 @@ + slide[w++] = slide[d++]; + Tracevv((stderr, "%c", slide[w-1])); + } while (--e); +- if (w == WSIZE) +- { +- flush_output(w); ++ if (w == WSIZE) { ++ flush_output(w); + w = 0; + } + } while (n); +@@ -702,7 +736,7 @@ + { + unsigned n; /* number of bytes in block */ + unsigned w; /* current window position */ +- register ulg b; /* bit buffer */ ++ register uint32_t b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + + DEBG("> 8); ++ } ++ crc = c; ++ bytes_out += (uint32_t)outcnt; ++ if (flush_cb != NULL) ++ flush_cb(window, outcnt); /* TODO: handle unzip_error */ ++ else ++ window += outcnt; ++ outcnt = 0; ++} ++ ++static int empty_fill(void *buf, unsigned int len) ++{ ++ return 0; ++} ++#endif ++ ++ + /* + * Do the uncompression! + */ +-static int INIT gunzip(void) ++STATIC int INIT gunzip( ++#ifdef NEW_CODE ++ unsigned char *buf, int len, ++ int(*fill)(void*, unsigned int), ++ int(*flush)(void*, unsigned int), ++ unsigned char *output, ++ int *posp, ++ void(*error_fn)(char *x) ++#else ++ void ++#endif ++ ) + { +- uch flags; ++ uint8_t flags; + unsigned char magic[2]; /* magic header */ + char method; +- ulg orig_crc = 0; /* original crc */ +- ulg orig_len = 0; /* original uncompressed length */ ++ uint32_t orig_crc = 0; /* original crc */ ++ uint32_t orig_len = 0; /* original uncompressed length */ + int res; + ++#ifdef NEW_CODE ++ set_error_fn(error_fn); ++ if (fill == NULL) ++ fill_cb = empty_fill; ++ else ++ fill_cb = fill; ++ if (output) ++ window = output; ++ else { ++ window = malloc(0x8000); ++ if (!window) ++ panic("can't allocate buffers"); ++ flush_cb = flush; ++ } ++ ++ insize = len; ++ if (buf) ++ inbuf = buf; ++ else ++ inbuf = malloc(INBUFSIZ); ++#endif ++ ++ inptr = 0; ++ outcnt = 0; /* bytes in output buffer */ ++ bytes_out = 0; ++ crc = (uint32_t)0xffffffffL; /* shift register contents */ ++ makecrc(); ++ + magic[0] = NEXTBYTE(); + magic[1] = NEXTBYTE(); + method = NEXTBYTE(); +@@ -1212,7 +1317,7 @@ + return -1; + } + +- flags = (uch)get_byte(); ++ flags = (uint8_t)get_byte(); + if ((flags & ENCRYPTED) != 0) { + error("Input is encrypted"); + return -1; +@@ -1277,15 +1382,15 @@ + /* crc32 (see algorithm.doc) + * uncompressed input size modulo 2^32 + */ +- orig_crc = (ulg) NEXTBYTE(); +- orig_crc |= (ulg) NEXTBYTE() << 8; +- orig_crc |= (ulg) NEXTBYTE() << 16; +- orig_crc |= (ulg) NEXTBYTE() << 24; ++ orig_crc = (uint32_t) NEXTBYTE(); ++ orig_crc |= (uint32_t) NEXTBYTE() << 8; ++ orig_crc |= (uint32_t) NEXTBYTE() << 16; ++ orig_crc |= (uint32_t) NEXTBYTE() << 24; + +- orig_len = (ulg) NEXTBYTE(); +- orig_len |= (ulg) NEXTBYTE() << 8; +- orig_len |= (ulg) NEXTBYTE() << 16; +- orig_len |= (ulg) NEXTBYTE() << 24; ++ orig_len = (uint32_t) NEXTBYTE(); ++ orig_len |= (uint32_t) NEXTBYTE() << 8; ++ orig_len |= (uint32_t) NEXTBYTE() << 16; ++ orig_len |= (uint32_t) NEXTBYTE() << 24; + + /* Validate decompression */ + if (orig_crc != CRC_VALUE) { +@@ -1296,11 +1401,22 @@ + error("length error"); + return -1; + } ++#ifdef NEW_CODE ++ if (!output) ++ free(window); ++ if (posp) ++ *posp = inptr; ++#endif + return 0; + + underrun: /* NEXTBYTE() goto's here if needed */ ++ free(window); ++#ifdef NEW_CODE ++ if (!buf) ++ free(inbuf); ++#endif + error("out of input data"); + return -1; + } + +- ++#define decompress gunzip +diff -urN linux-2.6.28.9/scripts/Makefile.lib linux-2.6.28.9.new/scripts/Makefile.lib +--- linux-2.6.28.9/scripts/Makefile.lib 2009-03-23 22:55:52.000000000 +0100 ++++ linux-2.6.28.9.new/scripts/Makefile.lib 2009-04-24 14:08:08.000000000 +0200 +@@ -183,3 +183,17 @@ + cmd_gzip = gzip -f -9 < $< > $@ + + ++# Bzip2 ++# --------------------------------------------------------------------------- ++ ++# Bzip2 does not include size in file... so we have to fake that ++size_append=$(CONFIG_SHELL) $(srctree)/scripts/bin_size ++ ++quiet_cmd_bzip2 = BZIP2 $@ ++cmd_bzip2 = (bzip2 -9 < $< ; $(size_append) $<) > $@ || (rm -f $@ ; false) ++ ++# Lzma ++# --------------------------------------------------------------------------- ++ ++quiet_cmd_lzma = LZMA $@ ++cmd_lzma = (/usr/bin/lzma -9 -c $< ; $(size_append) $<) >$@ || (rm -f $@ ; false) +diff -urN linux-2.6.28.9/scripts/bin_size linux-2.6.28.9.new/scripts/bin_size +--- linux-2.6.28.9/scripts/bin_size 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.28.9.new/scripts/bin_size 2009-04-24 14:08:08.000000000 +0200 +@@ -0,0 +1,10 @@ ++#!/bin/sh ++ ++if [ $# = 0 ] ; then ++ echo Usage: $0 file ++fi ++ ++size_dec=`stat -c "%s" $1` ++size_hex_echo_string=`printf "%08x" $size_dec | ++ sed 's/\(..\)\(..\)\(..\)\(..\)/\\\\x\4\\\\x\3\\\\x\2\\\\x\1/g'` ++/bin/echo -ne $size_hex_echo_string diff --git a/target/linux/rdc/patches-2.6.28/007-r6040_git_updates.patch b/target/linux/rdc/patches-2.6.28/007-r6040_git_updates.patch new file mode 100644 index 0000000000..777add3804 --- /dev/null +++ b/target/linux/rdc/patches-2.6.28/007-r6040_git_updates.patch @@ -0,0 +1,195 @@ +--- linux-2.6.28.9/drivers/net/r6040.c 2009-03-23 22:55:52.000000000 +0100 ++++ linux-2.6.28.9.new/drivers/net/r6040.c 2009-04-24 14:24:51.000000000 +0200 +@@ -49,12 +49,12 @@ + #include + + #define DRV_NAME "r6040" +-#define DRV_VERSION "0.19" +-#define DRV_RELDATE "18Dec2008" ++#define DRV_VERSION "0.22" ++#define DRV_RELDATE "25Mar2009" + + /* PHY CHIP Address */ + #define PHY1_ADDR 1 /* For MAC1 */ +-#define PHY2_ADDR 2 /* For MAC2 */ ++#define PHY2_ADDR 3 /* For MAC2 */ + #define PHY_MODE 0x3100 /* PHY CHIP Register 0 */ + #define PHY_CAP 0x01E1 /* PHY CHIP Register 4 */ + +@@ -160,6 +160,7 @@ + "Florian Fainelli "); + MODULE_LICENSE("GPL"); + MODULE_DESCRIPTION("RDC R6040 NAPI PCI FastEthernet driver"); ++MODULE_VERSION(DRV_VERSION " " DRV_RELDATE); + + /* RX and TX interrupts that we handle */ + #define RX_INTS (RX_FIFO_FULL | RX_NO_DESC | RX_FINISH) +@@ -200,7 +201,7 @@ + + static char version[] __devinitdata = KERN_INFO DRV_NAME + ": RDC R6040 NAPI net driver," +- "version "DRV_VERSION " (" DRV_RELDATE ")\n"; ++ "version "DRV_VERSION " (" DRV_RELDATE ")"; + + static int phy_table[] = { PHY1_ADDR, PHY2_ADDR }; + +@@ -330,7 +331,7 @@ + do { + skb = netdev_alloc_skb(dev, MAX_BUF_SIZE); + if (!skb) { +- printk(KERN_ERR "%s: failed to alloc skb for rx\n", dev->name); ++ printk(KERN_ERR DRV_NAME "%s: failed to alloc skb for rx\n", dev->name); + rc = -ENOMEM; + goto err_exit; + } +@@ -438,7 +439,6 @@ + { + struct r6040_private *lp = netdev_priv(dev); + void __iomem *ioaddr = lp->base; +- struct pci_dev *pdev = lp->pdev; + int limit = 2048; + u16 *adrp; + u16 cmd; +@@ -457,22 +457,12 @@ + iowrite16(adrp[0], ioaddr + MID_0L); + iowrite16(adrp[1], ioaddr + MID_0M); + iowrite16(adrp[2], ioaddr + MID_0H); +- free_irq(dev->irq, dev); +- +- /* Free RX buffer */ +- r6040_free_rxbufs(dev); +- +- /* Free TX buffer */ +- r6040_free_txbufs(dev); +- +- /* Free Descriptor memory */ +- pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma); +- pci_free_consistent(pdev, TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma); + } + + static int r6040_close(struct net_device *dev) + { + struct r6040_private *lp = netdev_priv(dev); ++ struct pci_dev *pdev = lp->pdev; + + /* deleted timer */ + del_timer_sync(&lp->timer); +@@ -481,8 +471,28 @@ + napi_disable(&lp->napi); + netif_stop_queue(dev); + r6040_down(dev); ++ ++ free_irq(dev->irq, dev); ++ ++ /* Free RX buffer */ ++ r6040_free_rxbufs(dev); ++ ++ /* Free TX buffer */ ++ r6040_free_txbufs(dev); ++ + spin_unlock_irq(&lp->lock); + ++ /* Free Descriptor memory */ ++ if (lp->rx_ring) { ++ pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma); ++ lp->rx_ring = NULL; ++ } ++ ++ if (lp->tx_ring) { ++ pci_free_consistent(pdev, TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma); ++ lp->tx_ring = NULL; ++ } ++ + return 0; + } + +@@ -598,7 +608,6 @@ + + /* Send to upper layer */ + netif_receive_skb(skb_ptr); +- dev->last_rx = jiffies; + dev->stats.rx_packets++; + dev->stats.rx_bytes += descptr->len - 4; + +@@ -668,7 +677,7 @@ + work_done = r6040_rx(dev, budget); + + if (work_done < budget) { +- netif_rx_complete(dev, napi); ++ napi_complete(napi); + /* Enable RX interrupt */ + iowrite16(ioread16(ioaddr + MIER) | RX_INTS, ioaddr + MIER); + } +@@ -705,7 +714,7 @@ + + /* Mask off RX interrupt */ + misr &= ~RX_INTS; +- netif_rx_schedule(dev, &lp->napi); ++ napi_schedule(&lp->napi); + } + + /* TX interrupt request */ +@@ -1063,20 +1088,20 @@ + /* this should always be supported */ + err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + if (err) { +- printk(KERN_ERR DRV_NAME "32-bit PCI DMA addresses" ++ printk(KERN_ERR DRV_NAME ": 32-bit PCI DMA addresses" + "not supported by the card\n"); + goto err_out; + } + err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); + if (err) { +- printk(KERN_ERR DRV_NAME "32-bit PCI DMA addresses" ++ printk(KERN_ERR DRV_NAME ": 32-bit PCI DMA addresses" + "not supported by the card\n"); + goto err_out; + } + + /* IO Size check */ + if (pci_resource_len(pdev, 0) < io_size) { +- printk(KERN_ERR DRV_NAME "Insufficient PCI resources, aborting\n"); ++ printk(KERN_ERR DRV_NAME ": Insufficient PCI resources, aborting\n"); + err = -EIO; + goto err_out; + } +@@ -1086,7 +1111,7 @@ + + dev = alloc_etherdev(sizeof(struct r6040_private)); + if (!dev) { +- printk(KERN_ERR DRV_NAME "Failed to allocate etherdev\n"); ++ printk(KERN_ERR DRV_NAME ": Failed to allocate etherdev\n"); + err = -ENOMEM; + goto err_out; + } +@@ -1102,11 +1127,15 @@ + + ioaddr = pci_iomap(pdev, bar, io_size); + if (!ioaddr) { +- printk(KERN_ERR "ioremap failed for device %s\n", ++ printk(KERN_ERR DRV_NAME ": ioremap failed for device %s\n", + pci_name(pdev)); + err = -EIO; + goto err_out_free_res; + } ++ /* If PHY status change register is still set to zero it means the ++ * bootloader didn't initialize it */ ++ if (ioread16(ioaddr + PHY_CC) == 0) ++ iowrite16(0x9f07, ioaddr + PHY_CC); + + /* Init system & device */ + lp->base = ioaddr; +@@ -1123,6 +1152,13 @@ + adrp[1] = ioread16(ioaddr + MID_0M); + adrp[2] = ioread16(ioaddr + MID_0H); + ++ /* Some bootloader/BIOSes do not initialize ++ * MAC address, warn about that */ ++ if (!(adrp[0] || adrp[1] || adrp[2])) { ++ printk(KERN_WARNING DRV_NAME ": MAC address not initialized, generating random\n"); ++ random_ether_addr(dev->dev_addr); ++ } ++ + /* Link new device into r6040_root_dev */ + lp->pdev = pdev; + lp->dev = dev;