All pastes #587217 Raw Edit

Mine

public text v1 · immutable
#587217 ·published 2007-06-24 11:17 UTC
rendered paste body
Index: target/linux/ar7-2.6/files/include/asm-mips/ar7/prom.h
===================================================================
--- target/linux/ar7-2.6/files/include/asm-mips/ar7/prom.h	(revision 0)
+++ target/linux/ar7-2.6/files/include/asm-mips/ar7/prom.h	(revision 0)
@@ -0,0 +1,29 @@
+/*
+ * $Id$
+ * 
+ * Copyright (C) 2006, 2007 OpenWrt.org
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __PROM_H__
+#define __PROM_H__
+
+extern void prom_init(void);
+extern char *prom_getenv(char *name);
+extern void prom_printf(char *fmt, ...);
+
+#endif // __PROM_H__
+
Index: target/linux/ar7-2.6/files/arch/mips/ar7/setup.c
===================================================================
--- target/linux/ar7-2.6/files/arch/mips/ar7/setup.c	(revision 7718)
+++ target/linux/ar7-2.6/files/arch/mips/ar7/setup.c	(working copy)
@@ -110,7 +110,7 @@
 
 	prom_meminit();
 #warning FIXME: clock initialisation
-	//ar7_init_clocks();
+	ar7_init_clocks();
 
 	ioport_resource.start = 0;
 	ioport_resource.end   = ~0;
Index: target/linux/ar7-2.6/files/arch/mips/ar7/platform.c
===================================================================
--- target/linux/ar7-2.6/files/arch/mips/ar7/platform.c	(revision 7718)
+++ target/linux/ar7-2.6/files/arch/mips/ar7/platform.c	(working copy)
@@ -355,6 +355,8 @@
 	if (res)
 		return res;
 
+// TODO: Fritz!Box VLYNQ Init
+#if 0
 	res = platform_device_register(&vlynq_low);
 	if (res)
 		return res;
@@ -366,6 +368,7 @@
 		if (res)
 			return res;
 	}
+#endif // 0
 
 	if (ar7_has_high_cpmac()) {
 		cpmac_get_mac(1, cpmac_high_data.dev_addr);
Index: target/linux/ar7-2.6/files/arch/mips/ar7/clock.c
===================================================================
--- target/linux/ar7-2.6/files/arch/mips/ar7/clock.c	(revision 7718)
+++ target/linux/ar7-2.6/files/arch/mips/ar7/clock.c	(working copy)
@@ -25,6 +25,7 @@
 #include <asm/addrspace.h>
 #include <asm/io.h>
 #include <asm/ar7/ar7.h>
+#include <asm/ar7/prom.h>
 
 #define BOOT_PLL_SOURCE_MASK 0x3
 #define CPU_PLL_SOURCE_SHIFT 16
@@ -70,18 +71,19 @@
 	volatile u32 mul;
 	volatile u32 prediv;
 	volatile u32 postdiv;
-	u32 unused2[7];
+	volatile u32 postdiv2;
+	u32 unused2[6];
 	volatile u32 cmd;
 	volatile u32 status;
 	volatile u32 cmden;
 	u32 padding[15];
-};
+} __attribute__ ((packed));
 
 struct tnetd7200_clocks {
 	struct tnetd7200_clock cpu;
 	struct tnetd7200_clock dsp;
 	struct tnetd7200_clock usb;
-};
+} __attribute__ ((packed));
 
 int ar7_afe_clock = 35328000;
 int ar7_ref_clock = 25000000;
@@ -277,6 +279,36 @@
 	iounmap(bootcr);
 }
 
+/*
+static int tnetd7200_dsp_clock(void)
+{
+    char buffer[20], *p, *hwrev;
+
+    prom_init();
+    hwrev = prom_getenv("HWRevision");
+
+    strcpy(buffer, hwrev);
+    p = strchr(buffer, '.');
+    if(!p) return 0;
+    *p = '\0';
+
+    prom_printf("clocks.c: Device has hardware revision %s\n", hwrev);
+
+    // HWRevs 105, B104, B103 don't have a DSP XTAL, so they are based on 25000000 Hz LAN XTAL
+    if(strcmp(p, "105") == 0 || strcmp(p, "B104") == 0 || strcmp(p, "B103") == 0)
+    {
+        prom_printf("clocks.c: Device has no DSP XTAL\n");
+        // Default clock is 225 MHz (* 9), maximum clock is 250 MHz (* 10)
+        return ar7_ref_clock * 9;
+    }
+    else // All other HWRevs are based on 35328000 Hz DSP XTAL
+    {
+        prom_printf("clocks.c: Device has DSP XTAL\n");
+        // Default clock is 211 MHz (* 6), maximum clock is 247 MHz (* 7)
+        return ar7_afe_clock * 6;
+    }
+}
+*/
 static int tnetd7200_get_clock(int base, struct tnetd7200_clock *clock,
 			       u32 *bootcr, u32 bus_clock)
 {
@@ -289,28 +321,33 @@
 	return base * ((clock->mul & 0xf) + 1) / divisor;
 }
 
+
 static void tnetd7200_set_clock(int base, struct tnetd7200_clock *clock,
-				u32 *bootcr, u32 frequency) 
+				int prediv, int postdiv, int postdiv2, int mul, u32 frequency) 
 {
-	u32 status;
-	int prediv, postdiv, mul;
+    printk("Clocks: base = %d, frequency = %u, prediv = %d, postdiv = %d, postdiv2 = %d, mul = %d\n",
+        base, frequency, prediv, postdiv, postdiv2, mul);
 
-	calculate(base, frequency, &prediv, &postdiv, &mul);
+    clock->ctrl &= ~1;
+    clock->ctrl &= ~2;
 
-	clock->ctrl = 0;
-	clock->prediv = DIVISOR_ENABLE_MASK | prediv;
-	clock->mul = mul;
-	mdelay(1);
-	do {
-		status = clock->status;
-	} while (status & PLL_STATUS);
-	clock->postdiv = DIVISOR_ENABLE_MASK | postdiv;
-	clock->cmden = 1;
-	clock->cmd = 1;
-	do {
-		status = clock->status;
-	} while (status & PLL_STATUS);
-	clock->ctrl = 1;
+    clock->mul = (mul - 1);
+
+	clock->prediv = DIVISOR_ENABLE_MASK | (prediv - 1);
+
+    clock->cmden |= 1;
+    clock->postdiv = DIVISOR_ENABLE_MASK | (postdiv - 1);
+    clock->cmd |= 1;
+
+    if(postdiv2)
+    {
+        clock->cmden |= 1;
+        clock->postdiv2 = DIVISOR_ENABLE_MASK | (postdiv2 - 1);
+        clock->cmd |= 1;
+    }
+
+    clock->ctrl |= 1;
+
 }
 
 static void __init tnetd7200_init_clocks(void)
@@ -318,6 +355,15 @@
 	u32 *bootcr = (u32 *)ioremap_nocache(AR7_REGS_DCL, 4);
 	struct tnetd7200_clocks *clocks = (struct tnetd7200_clocks *)ioremap_nocache(AR7_REGS_POWER + 0x80, sizeof(struct tnetd7200_clocks)); 
 
+    // (((35328000 Hz base / 1) * 6)  / 1)      = 211968000 Hz target
+    tnetd7200_set_clock(ar7_afe_clock,  &clocks->cpu,  1, 1, -1,  6, 211968000);
+    // (((25000000 Hz base / 1) * 10) / 2)      = 125000000 Hz target
+    // (((25000000 Hz base / 1) * 10) / 1)      = 250000000 Hz target
+    tnetd7200_set_clock(ar7_ref_clock,  &clocks->dsp,  1, 2,  1, 10, 125000000);
+    // (((125000000 Hz base / 26) * 10) / 1)    =  48076923 Hz target
+	tnetd7200_set_clock(ar7_bus_clock,  &clocks->usb, 26, 1, -1, 10,  48076923);
+
+    /*
 	ar7_cpu_clock = tnetd7200_get_clock(ar7_afe_clock,
 					    &clocks->cpu,
 					    bootcr, ar7_afe_clock);
@@ -332,12 +378,16 @@
 		}
 	}
 
-	tnetd7200_set_clock(ar7_ref_clock * 5, &clocks->usb,
-			    bootcr, 48000000);
+//	tnetd7200_set_clock(ar7_ref_clock * 5, &clocks->usb,
+//			    bootcr, 48000000);
 
-	if (ar7_dsp_clock == 250000000)
+    if (ar7_dsp_clock == 250000000)
 		tnetd7200_set_clock(ar7_ref_clock, &clocks->dsp,
 				    bootcr, ar7_dsp_clock);
+    else if(ar7_dsp_clock == 125000000)
+		tnetd7200_set_clock(ar7_ref_clock, &clocks->dsp,
+				    bootcr, ar7_dsp_clock);
+    */
 
 	iounmap(clocks);
 	iounmap(bootcr);
Index: target/linux/ar7-2.6/files/arch/mips/ar7/prom.c
===================================================================
--- target/linux/ar7-2.6/files/arch/mips/ar7/prom.c	(revision 7718)
+++ target/linux/ar7-2.6/files/arch/mips/ar7/prom.c	(working copy)
@@ -26,6 +26,7 @@
 #include <linux/serial_reg.h>
 #include <linux/spinlock.h>
 #include <linux/module.h>
+#include <linux/string.h>
 #include <asm/io.h>
 #include <asm/bootinfo.h>
 #include <asm/mips-boards/prom.h>
@@ -245,9 +246,12 @@
 		return;
 
 #ifdef CONFIG_KGDB
-	strcat(prom_getcmdline(), " console=kgdb");
-	kgdb_enabled = 1;
-	return;
+	if (!strstr(prom_getcmdline(), "nokgdb"))
+	{
+            strcat(prom_getcmdline(), " console=kgdb");
+            kgdb_enabled = 1;
+            return;
+	}
 #endif
 
 	if ((s = prom_getenv("modetty0"))) {
@@ -307,6 +311,28 @@
 	return 1;
 }
 
+// from adm5120/prom.c
+void prom_printf(char *fmt, ...)
+{
+    va_list args;
+    int l;
+    char *p, *buf_end;
+    char buf[1024];
+
+    va_start(args, fmt);
+    l = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */
+    va_end(args);
+
+    buf_end = buf + l;
+
+    for (p = buf; p < buf_end; p++) {
+        /* Crude cr/nl handling is better than none */
+        if (*p == '\n')
+            prom_putchar('\r');
+        prom_putchar(*p);
+    }
+}
+
 #ifdef CONFIG_KGDB
 int putDebugChar(char c)
 {
Index: target/linux/ar7-2.6/files/drivers/leds/leds-avm.c
===================================================================
--- target/linux/ar7-2.6/files/drivers/leds/leds-avm.c	(revision 0)
+++ target/linux/ar7-2.6/files/drivers/leds/leds-avm.c	(revision 0)
@@ -0,0 +1,152 @@
+/*
+ * linux/drivers/leds/leds-avm.c
+ * 
+ * Copyright (C) 2007 OpenWrt.org
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/err.h>
+#include <asm/io.h>
+#include <gpio.h>
+
+// Module information
+#define DRVNAME "avm-leds"
+#define LONGNAME "AVM Fritz!Box LEDs driver"
+MODULE_AUTHOR("Axel Gembe <ago@bastart.eu.org>");
+MODULE_DESCRIPTION(LONGNAME);
+MODULE_LICENSE("GPL");
+
+// Number of LEDs in devs
+#define NUM_LEDS 5
+
+// Structure for GPIO port definition
+typedef struct led_gpio_s { int num; int invert; } led_gpio;
+
+#if 1 // Fritz!Box SL
+led_gpio gpios[] = { { 7, 0 }, { 13, 1 }, { 10, 1 }, { 12, 1 }, {  9, 1 } };
+#endif // 0
+
+#if 0 // Fritz!Box Fon ATA
+led_gpio gpios[] = { { 8, 0 }, {  3, 1 }, {  5, 0 }, {  4, 1 }, { 11, 1 } };
+#endif // 0
+
+// Function for implementing LED setters
+#define IMPLEMENT_LED(x) static void avm_led_set_##x(struct led_classdev *pled, enum led_brightness value) { \
+    gpio_set_value(gpios[x].num, value ? (gpios[x].invert ? 0 : 1) : (gpios[x].invert ? 1 : 0)); } \
+    static struct led_classdev avm_led_##x = { .name = "avm:led" #x, .brightness_set = avm_led_set_##x }
+
+// Implement the LED setter code
+IMPLEMENT_LED(0); IMPLEMENT_LED(1); IMPLEMENT_LED(2); IMPLEMENT_LED(3); IMPLEMENT_LED(4);
+
+// Array of all the LED devices
+struct led_classdev *devs[] = { &avm_led_0, &avm_led_1, &avm_led_2, &avm_led_3, &avm_led_4 };
+
+#ifdef CONFIG_PM
+static int avm_leds_suspend(struct platform_device *dev, pm_message_t state)
+{
+    for(int i = 0; i < NUM_LEDS; i++)
+        led_classdev_suspend(devs[i]);
+	return 0;
+}
+
+static int avm_leds_resume(struct platform_device *dev)
+{
+    for(int i = 0; i < NUM_LEDS; i++)
+        led_classdev_resume(devs[i]);
+	return 0;
+}
+#else /* CONFIG_PM */
+#define avm_leds_suspend NULL
+#define avm_leds_resume NULL
+#endif /* CONFIG_PM */
+
+static int avm_leds_probe(struct platform_device *pdev)
+{
+	int rc, i;
+
+    for(i = 0; i < NUM_LEDS; i++)
+    {
+	    rc = led_classdev_register(&pdev->dev, devs[i]);
+	    if( rc < 0 ) goto out;
+
+	    ar7_gpio_enable(gpios[i].num);
+	    gpio_direction_output(gpios[i].num);
+    }
+
+out:
+	return rc;
+}
+
+static int avm_leds_remove(struct platform_device *pdev)
+{
+    int i;
+
+    for(i = 0; i < NUM_LEDS; i++)
+    {
+	    led_classdev_unregister(devs[i]);
+    }
+
+	return 0;
+}
+
+static struct platform_device *avm_leds_device;
+
+static struct platform_driver avm_leds_driver = {
+	.probe		= avm_leds_probe,
+	.remove		= avm_leds_remove,
+	.suspend	= avm_leds_suspend,
+	.resume		= avm_leds_resume,
+	.driver		= {
+		.name		= DRVNAME,
+	},
+};
+
+static int __init avm_leds_init(void)
+{
+	int rc;
+
+	avm_leds_device = platform_device_alloc(DRVNAME, -1);
+	if (!avm_leds_device)
+		return -ENOMEM;
+
+	rc = platform_device_add(avm_leds_device);
+	if (rc < 0)
+		goto out_put;
+
+	rc = platform_driver_register(&avm_leds_driver);
+	if (rc < 0)
+		goto out_put;
+
+	goto out;
+
+out_put:
+	platform_device_put(avm_leds_device);
+out:
+	return rc;
+}
+
+static void __exit avm_leds_exit(void)
+{
+	platform_driver_unregister(&avm_leds_driver);
+	platform_device_unregister(avm_leds_device);
+}
+
+module_init(avm_leds_init);
+module_exit(avm_leds_exit);
Index: target/linux/ar7-2.6/image/src/print.h
===================================================================
--- target/linux/ar7-2.6/image/src/print.h	(revision 0)
+++ target/linux/ar7-2.6/image/src/print.h	(revision 0)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef _print_h_
+#define _print_h_
+
+#include <stdarg.h>
+
+/* this is the maximum width for a variable */
+#define		LP_MAX_BUF	80
+
+/* -*-
+ * output function takes an void pointer which is passed in as the
+ * second argument in lp_Print().  This black-box argument gives output
+ * function a way to track state.
+ *
+ * The second argument in output function is a pointer to char buffer.
+ * The third argument specifies the number of chars to outputed.
+ *
+ * output function cannot assume the buffer is null-terminated after
+ * l number of chars.
+ */
+void lp_Print(void (*output)(void *, char *, int), 
+	      void * arg,
+	      char *fmt, 
+	      va_list ap);
+
+#endif
Index: target/linux/ar7-2.6/image/src/uart16550.h
===================================================================
--- target/linux/ar7-2.6/image/src/uart16550.h	(revision 0)
+++ target/linux/ar7-2.6/image/src/uart16550.h	(revision 0)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef _uart16550_h_
+#define _uart16550_h_
+
+#define UART16550_BAUD_2400     2400
+#define UART16550_BAUD_4800     4800
+#define UART16550_BAUD_9600     9600
+#define UART16550_BAUD_19200    19200
+#define UART16550_BAUD_38400    38400
+#define UART16550_BAUD_57600    57600
+#define UART16550_BAUD_115200   115200
+
+#define UART16550_PARITY_NONE   0
+#define UART16550_PARITY_ODD    0x08
+#define UART16550_PARITY_EVEN   0x18
+#define UART16550_PARITY_MARK   0x28
+#define UART16550_PARITY_SPACE	0x38
+
+#define UART16550_DATA_5BIT     0x0
+#define UART16550_DATA_6BIT     0x1
+#define UART16550_DATA_7BIT     0x2
+#define UART16550_DATA_8BIT     0x3
+
+#define UART16550_STOP_1BIT     0x0
+#define	UART16550_STOP_2BIT     0x4
+
+unsigned char Uart16550GetPoll(void);
+void Uart16550Put(unsigned char byte);
+void Uart16550Init(unsigned int baud, unsigned char data, unsigned char parity, unsigned char stop);
+
+#endif // _uart16550_h_
Index: target/linux/ar7-2.6/image/src/printf.c
===================================================================
--- target/linux/ar7-2.6/image/src/printf.c	(revision 0)
+++ target/linux/ar7-2.6/image/src/printf.c	(revision 0)
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include "printf.h"
+#include "print.h"
+#include "uart16550.h"
+
+static void myoutput(void *arg, char *s, int l)
+{
+    int i;
+
+    // special termination call
+    if ((l==1) && (s[0] == '\0')) return;
+    
+    for (i=0; i< l; i++) {
+	Uart16550Put(s[i]);
+	if (s[i] == '\n') Uart16550Put('\r');
+    }
+}
+
+void ldr_printf(char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    lp_Print(myoutput, 0, fmt, ap);
+    va_end(ap);
+}
Index: target/linux/ar7-2.6/image/src/zimage.script.in
===================================================================
--- target/linux/ar7-2.6/image/src/zimage.script.in	(revision 0)
+++ target/linux/ar7-2.6/image/src/zimage.script.in	(revision 0)
@@ -0,0 +1,11 @@
+	OUTPUT_FORMAT("@@OUTPUT_FORMAT@@")
+OUTPUT_ARCH(mips)
+	SECTIONS
+{
+	.data :
+	{
+		kernelimage = .;
+		*(.data)
+		kernelimage_end = .;
+	}
+}
Index: target/linux/ar7-2.6/image/src/decompress.c
===================================================================
--- target/linux/ar7-2.6/image/src/decompress.c	(revision 0)
+++ target/linux/ar7-2.6/image/src/decompress.c	(revision 0)
@@ -0,0 +1,205 @@
+/*
+ * LZMA compressed kernel decompressor for bcm947xx boards
+ *
+ * Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ * Please note, this was code based on the bunzip2 decompressor code
+ * by Manuel Novoa III  (mjn3@codepoet.org), although the only thing left
+ * is an idea and part of original vendor code
+ *
+ * 13-Jun-2007  Axel Gembe <ago@bastart.eu.org>
+ *   added debug output for diagnosing loader problems
+ *   added optional OpenWRT ASCII art logo
+ *
+ * 12-Mar-2005  Mineharu Takahara <mtakahar@yahoo.com>
+ *   pass actual output size to decoder (stream mode
+ *   compressed input is not a requirement anymore)
+ *
+ * 24-Apr-2005 Oleg I. Vdovikin
+ *   reordered functions using lds script, removed forward decl
+ *
+ * ??-Nov-2005 Mike Baker
+ *   reorder the script as an lzma wrapper; do not depend on flash access
+ */
+
+#include "LzmaDecode.h"
+
+#define DEBUG_OUTPUT
+#define DEBUG_OUTPUT_LOGO
+
+#ifdef DEBUG_OUTPUT
+#include "uart16550.h"
+#include "printf.h"
+#define DBG_OUT_1(a)        ldr_printf(a)
+#define DBG_OUT_2(a, b)     ldr_printf(a, b)
+#define DBG_OUT_3(a, b, c)  ldr_printf(a, b, c)
+#else // !DEBUG_OUTPUT
+#define DBG_OUT_1(a)
+#define DBG_OUT_2(a, b)
+#define DBG_OUT_3(a, b, c)
+#endif // DEBUG_OUTPUT
+
+#define KSEG0                   0x80000000
+#define KSEG1                   0xa0000000
+#define KSEG1ADDR(a)            ((((unsigned)(a)) & 0x1fffffffU) | KSEG1)
+#define Index_Invalidate_I      0x00
+#define Index_Writeback_Inv_D   0x01
+
+#define cache_unroll(base,op)	\
+	__asm__ __volatile__(		\
+		".set noreorder;\n"		\
+		".set mips3;\n"			\
+		"cache %1, (%0);\n"		\
+		".set mips0;\n"			\
+		".set reorder\n"		\
+		:						\
+		: "r" (base),			\
+		  "i" (op));
+
+
+static __inline__ void blast_icache(unsigned long size, unsigned long lsize)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = (start + size);
+
+    DBG_OUT_3("Blasting icache, size=%u, lsize=%u...\n", size, lsize);
+    
+	while(start < end) {
+		cache_unroll(start,Index_Invalidate_I);
+		start += lsize;
+	}
+}
+
+static __inline__ void blast_dcache(unsigned long size, unsigned long lsize)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = (start + size);
+
+    DBG_OUT_3("Blasting dcache, size=%u, lsize=%u...\n", size, lsize);
+    
+	while(start < end) {
+		cache_unroll(start,Index_Writeback_Inv_D);
+		start += lsize;
+	}
+}
+/* Compressed kernel comes from here */
+unsigned char *inputData;
+unsigned int inputSize;
+/* Uncompressed kernel will go here */
+unsigned char *outputData;
+
+/* Gets the next byte from inputData */
+static unsigned char get_byte(void)
+{
+    unsigned char retVal;
+    retVal = *inputData;
+    inputData++;
+    return retVal;
+}
+
+int decompress(void)
+{
+    extern unsigned int workspace; /* LZMA workspace */
+	unsigned int i;  /* temp value */
+	unsigned int lc; /* literal context bits */
+	unsigned int lp; /* literal pos state bits */
+	unsigned int pb; /* pos state bits */
+	unsigned int osize; /* uncompressed size */
+	
+	/* lzma args */
+	i = get_byte();
+	lc = i % 9, i = i / 9;
+	lp = i % 5, pb = i / 5;
+
+	/* skip rest of the LZMA coder property */
+	for (i = 0; i < 4; i++)
+		get_byte();
+	
+	/* read the lower half of uncompressed size in the header */
+	osize = ((unsigned int)get_byte()) +
+		((unsigned int)get_byte() << 8) +
+		((unsigned int)get_byte() << 16) +
+		((unsigned int)get_byte() << 24);
+        
+	/* skip rest of the header (upper half of uncompressed size) */
+	for (i = 0; i < 4; i++)
+		get_byte();
+        
+    DBG_OUT_2("Output size = %u bytes.\n", osize);
+    DBG_OUT_1("Calling LzmaDecode.\n");
+    return LzmaDecode(  (unsigned char*)&workspace,
+                        ((LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp))) * sizeof(CProb)),
+                        lc, lp, pb,
+                        inputData, inputSize - 13,
+                        outputData, osize, &i) == LZMA_RESULT_OK ? 1 : 0;
+}
+
+/* Kernel entry function definition */
+void kernel_entry(int, char *[], char *[]);
+
+/* should be the first function */
+void entry(int argc, char *argv[], char *arge[])
+{
+    /* LZMA compressed kernel image start and end */
+    extern unsigned char kernelimage[], kernelimage_end[];
+    unsigned int i;
+
+//    Uart16550Init(UART16550_BAUD_38400, UART16550_DATA_8BIT, UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+
+    /* print some info */
+    DBG_OUT_1("LZMA loader for AR7, Copyright (C) 2007 OpenWrt.org\n\n");
+
+#ifdef DEBUG_OUTPUT_LOGO
+    DBG_OUT_1("   _______                     ________        __\n");
+    DBG_OUT_1("  |       |.-----.-----.-----.|  |  |  |.----.|  |_\n");
+    DBG_OUT_1("  |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|\n");
+    DBG_OUT_1("  |_______||   __|_____|__|__||________||__|  |____|\n");
+    DBG_OUT_1("           |__| A R 7   F R E E D O M (TI, you suck!)\n\n");
+#endif // DEBUG_OUTPUT_LOGO
+
+    DBG_OUT_2(" - Loader entry point address    = 0x%8.8X\n", &entry);
+    DBG_OUT_2(" - Kernel entry point address    = 0x%8.8X\n", &kernel_entry);
+    DBG_OUT_2(" - Kernel load address           = 0x%8.8X\n", LOADADDR);
+    DBG_OUT_2(" - LZMA data start address       = 0x%8.8X\n", &kernelimage[0]);
+    DBG_OUT_2(" - LZMA data end address         = 0x%8.8X\n", &kernelimage_end[0]);
+
+    DBG_OUT_1("Decompressing kernel now...");
+
+    inputData = &kernelimage[0];
+    inputSize = kernelimage_end - kernelimage;
+    outputData = (unsigned char*)LOADADDR;
+
+	/* decompress kernel */
+    if(decompress() == 1)
+	{
+        DBG_OUT_1(" success.\n");
+
+        DBG_OUT_1("Calling kernel entry point... loader says: goodbye!\n");
+		/* Jump to load address */
+//        entry_ptr = (ke)LOADADDR;
+//        entry_ptr(arg0, arg1, arg2, arg3);
+		kernel_entry(argc, argv, arge);
+	}
+    else
+    {
+        /* Output error */
+        DBG_OUT_1(" failed (system halt)!\n");
+        /* Halt system */
+        while(1);
+    }
+}
Index: target/linux/ar7-2.6/image/src/ld.script.in
===================================================================
--- target/linux/ar7-2.6/image/src/ld.script.in	(revision 0)
+++ target/linux/ar7-2.6/image/src/ld.script.in	(revision 0)
@@ -0,0 +1,34 @@
+	OUTPUT_FORMAT("@@OUTPUT_FORMAT@@")
+	OUTPUT_ARCH(mips)
+ENTRY(entry)
+	SECTIONS
+{
+
+	/* Allocate memory space on top of kernel bss space */
+	. = 0x94400000;
+	.text :
+	{
+		*(.text)
+		*(.rodata)
+		*(.rodata1)
+		*(.gnu.warning)
+		*(.text.init)
+		*(.data.init)
+	}                    
+
+	.data :
+	{
+		*(*)
+	}
+
+	.bss :
+	{
+		*(.dynbss)
+		*(COMMON)
+		*(.bss)
+		*(.sbss)
+		*(.scommon)
+		. = ALIGN (0x8000);
+		workspace = .;
+	}
+}
Index: target/linux/ar7-2.6/image/src/printf.h
===================================================================
--- target/linux/ar7-2.6/image/src/printf.h	(revision 0)
+++ target/linux/ar7-2.6/image/src/printf.h	(revision 0)
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef _printf_h_
+#define _printf_h_
+
+#include <stdarg.h>
+void ldr_printf(char *fmt, ...);
+
+#endif /* _printf_h_ */
Index: target/linux/ar7-2.6/image/src/LzmaDecode.c
===================================================================
--- target/linux/ar7-2.6/image/src/LzmaDecode.c	(revision 0)
+++ target/linux/ar7-2.6/image/src/LzmaDecode.c	(revision 0)
@@ -0,0 +1,681 @@
+/*
+  LzmaDecode.c
+  LZMA Decoder
+  
+  LZMA SDK 4.05 Copyright (c) 1999-2004 Igor Pavlov (2004-08-25)
+  http://www.7-zip.org/
+
+  LZMA SDK is licensed under two licenses:
+  1) GNU Lesser General Public License (GNU LGPL)
+  2) Common Public License (CPL)
+  It means that you can select one of these two licenses and 
+  follow rules of that license.
+
+  SPECIAL EXCEPTION:
+  Igor Pavlov, as the author of this code, expressly permits you to 
+  statically or dynamically link your code (or bind by name) to the 
+  interfaces of this file without subjecting your linked code to the 
+  terms of the CPL or GNU LGPL. Any modifications or additions 
+  to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#include "LzmaDecode.h"
+
+#ifndef Byte
+#define Byte unsigned char
+#endif
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+typedef struct _CRangeDecoder
+{
+  Byte *Buffer;
+  Byte *BufferLim;
+  UInt32 Range;
+  UInt32 Code;
+  #ifdef _LZMA_IN_CB
+  ILzmaInCallback *InCallback;
+  int Result;
+  #endif
+  int ExtraBytes;
+} CRangeDecoder;
+
+Byte RangeDecoderReadByte(CRangeDecoder *rd)
+{
+  if (rd->Buffer == rd->BufferLim)
+  {
+    #ifdef _LZMA_IN_CB
+    UInt32 size;
+    rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size);
+    rd->BufferLim = rd->Buffer + size;
+    if (size == 0)
+    #endif
+    {
+      rd->ExtraBytes = 1;
+      return 0xFF;
+    }
+  }
+  return (*rd->Buffer++);
+}
+
+/* #define ReadByte (*rd->Buffer++) */
+#define ReadByte (RangeDecoderReadByte(rd))
+
+void RangeDecoderInit(CRangeDecoder *rd,
+  #ifdef _LZMA_IN_CB
+    ILzmaInCallback *inCallback
+  #else
+    Byte *stream, UInt32 bufferSize
+  #endif
+    )
+{
+  int i;
+  #ifdef _LZMA_IN_CB
+  rd->InCallback = inCallback;
+  rd->Buffer = rd->BufferLim = 0;
+  #else
+  rd->Buffer = stream;
+  rd->BufferLim = stream + bufferSize;
+  #endif
+  rd->ExtraBytes = 0;
+  rd->Code = 0;
+  rd->Range = (0xFFFFFFFF);
+  for(i = 0; i < 5; i++)
+    rd->Code = (rd->Code << 8) | ReadByte;
+}
+
+#define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code;        
+#define RC_FLUSH_VAR rd->Range = range; rd->Code = code;
+#define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; }
+
+UInt32 RangeDecoderDecodeDirectBits(CRangeDecoder *rd, int numTotalBits)
+{
+  RC_INIT_VAR
+  UInt32 result = 0;
+  int i;
+  for (i = numTotalBits; i > 0; i--)
+  {
+    /* UInt32 t; */
+    range >>= 1;
+
+    result <<= 1;
+    if (code >= range)
+    {
+      code -= range;
+      result |= 1;
+    }
+    /*
+    t = (code - range) >> 31;
+    t &= 1;
+    code -= range & (t - 1);
+    result = (result + result) | (1 - t);
+    */
+    RC_NORMALIZE
+  }
+  RC_FLUSH_VAR
+  return result;
+}
+
+int RangeDecoderBitDecode(CProb *prob, CRangeDecoder *rd)
+{
+  UInt32 bound = (rd->Range >> kNumBitModelTotalBits) * *prob;
+  if (rd->Code < bound)
+  {
+    rd->Range = bound;
+    *prob += (kBitModelTotal - *prob) >> kNumMoveBits;
+    if (rd->Range < kTopValue)
+    {
+      rd->Code = (rd->Code << 8) | ReadByte;
+      rd->Range <<= 8;
+    }
+    return 0;
+  }
+  else
+  {
+    rd->Range -= bound;
+    rd->Code -= bound;
+    *prob -= (*prob) >> kNumMoveBits;
+    if (rd->Range < kTopValue)
+    {
+      rd->Code = (rd->Code << 8) | ReadByte;
+      rd->Range <<= 8;
+    }
+    return 1;
+  }
+}
+
+#define RC_GET_BIT2(prob, mi, A0, A1) \
+  UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \
+  if (code < bound) \
+    { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \
+  else \
+    { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \
+  RC_NORMALIZE
+
+#define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;)               
+
+int RangeDecoderBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
+{
+  int mi = 1;
+  int i;
+  #ifdef _LZMA_LOC_OPT
+  RC_INIT_VAR
+  #endif
+  for(i = numLevels; i > 0; i--)
+  {
+    #ifdef _LZMA_LOC_OPT
+    CProb *prob = probs + mi;
+    RC_GET_BIT(prob, mi)
+    #else
+    mi = (mi + mi) + RangeDecoderBitDecode(probs + mi, rd);
+    #endif
+  }
+  #ifdef _LZMA_LOC_OPT
+  RC_FLUSH_VAR
+  #endif
+  return mi - (1 << numLevels);
+}
+
+int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
+{
+  int mi = 1;
+  int i;
+  int symbol = 0;
+  #ifdef _LZMA_LOC_OPT
+  RC_INIT_VAR
+  #endif
+  for(i = 0; i < numLevels; i++)
+  {
+    #ifdef _LZMA_LOC_OPT
+    CProb *prob = probs + mi;
+    RC_GET_BIT2(prob, mi, ; , symbol |= (1 << i))
+    #else
+    int bit = RangeDecoderBitDecode(probs + mi, rd);
+    mi = mi + mi + bit;
+    symbol |= (bit << i);
+    #endif
+  }
+  #ifdef _LZMA_LOC_OPT
+  RC_FLUSH_VAR
+  #endif
+  return symbol;
+}
+
+Byte LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd)
+{ 
+  int symbol = 1;
+  #ifdef _LZMA_LOC_OPT
+  RC_INIT_VAR
+  #endif
+  do
+  {
+    #ifdef _LZMA_LOC_OPT
+    CProb *prob = probs + symbol;
+    RC_GET_BIT(prob, symbol)
+    #else
+    symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
+    #endif
+  }
+  while (symbol < 0x100);
+  #ifdef _LZMA_LOC_OPT
+  RC_FLUSH_VAR
+  #endif
+  return symbol;
+}
+
+Byte LzmaLiteralDecodeMatch(CProb *probs, CRangeDecoder *rd, Byte matchByte)
+{ 
+  int symbol = 1;
+  #ifdef _LZMA_LOC_OPT
+  RC_INIT_VAR
+  #endif
+  do
+  {
+    int bit;
+    int matchBit = (matchByte >> 7) & 1;
+    matchByte <<= 1;
+    #ifdef _LZMA_LOC_OPT
+    {
+      CProb *prob = probs + ((1 + matchBit) << 8) + symbol;
+      RC_GET_BIT2(prob, symbol, bit = 0, bit = 1)
+    }
+    #else
+    bit = RangeDecoderBitDecode(probs + ((1 + matchBit) << 8) + symbol, rd);
+    symbol = (symbol << 1) | bit;
+    #endif
+    if (matchBit != bit)
+    {
+      while (symbol < 0x100)
+      {
+        #ifdef _LZMA_LOC_OPT
+        CProb *prob = probs + symbol;
+        RC_GET_BIT(prob, symbol)
+        #else
+        symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
+        #endif
+      }
+      break;
+    }
+  }
+  while (symbol < 0x100);
+  #ifdef _LZMA_LOC_OPT
+  RC_FLUSH_VAR
+  #endif
+  return symbol;
+}
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols) 
+
+int LzmaLenDecode(CProb *p, CRangeDecoder *rd, int posState)
+{
+  if(RangeDecoderBitDecode(p + LenChoice, rd) == 0)
+    return RangeDecoderBitTreeDecode(p + LenLow +
+        (posState << kLenNumLowBits), kLenNumLowBits, rd);
+  if(RangeDecoderBitDecode(p + LenChoice2, rd) == 0)
+    return kLenNumLowSymbols + RangeDecoderBitTreeDecode(p + LenMid +
+        (posState << kLenNumMidBits), kLenNumMidBits, rd);
+  return kLenNumLowSymbols + kLenNumMidSymbols + 
+      RangeDecoderBitTreeDecode(p + LenHigh, kLenNumHighBits, rd);
+}
+
+#define kNumStates 12
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+#ifdef _LZMA_OUT_READ
+
+typedef struct _LzmaVarState
+{
+  CRangeDecoder RangeDecoder;
+  Byte *Dictionary;
+  UInt32 DictionarySize;
+  UInt32 DictionaryPos;
+  UInt32 GlobalPos;
+  UInt32 Reps[4];
+  int lc;
+  int lp;
+  int pb;
+  int State;
+  int PreviousIsMatch;
+  int RemainLen;
+} LzmaVarState;
+
+int LzmaDecoderInit(
+    unsigned char *buffer, UInt32 bufferSize,
+    int lc, int lp, int pb,
+    unsigned char *dictionary, UInt32 dictionarySize,
+    #ifdef _LZMA_IN_CB
+    ILzmaInCallback *inCallback
+    #else
+    unsigned char *inStream, UInt32 inSize
+    #endif
+    )
+{
+  LzmaVarState *vs = (LzmaVarState *)buffer;
+  CProb *p = (CProb *)(buffer + sizeof(LzmaVarState));
+  UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp));
+  UInt32 i;
+  if (bufferSize < numProbs * sizeof(CProb) + sizeof(LzmaVarState))
+    return LZMA_RESULT_NOT_ENOUGH_MEM;
+  vs->Dictionary = dictionary;
+  vs->DictionarySize = dictionarySize;
+  vs->DictionaryPos = 0;
+  vs->GlobalPos = 0;
+  vs->Reps[0] = vs->Reps[1] = vs->Reps[2] = vs->Reps[3] = 1;
+  vs->lc = lc;
+  vs->lp = lp;
+  vs->pb = pb;
+  vs->State = 0;
+  vs->PreviousIsMatch = 0;
+  vs->RemainLen = 0;
+  dictionary[dictionarySize - 1] = 0;
+  for (i = 0; i < numProbs; i++)
+    p[i] = kBitModelTotal >> 1; 
+  RangeDecoderInit(&vs->RangeDecoder, 
+      #ifdef _LZMA_IN_CB
+      inCallback
+      #else
+      inStream, inSize
+      #endif
+  );
+  return LZMA_RESULT_OK;
+}
+
+int LzmaDecode(unsigned char *buffer, 
+    unsigned char *outStream, UInt32 outSize,
+    UInt32 *outSizeProcessed)
+{
+  LzmaVarState *vs = (LzmaVarState *)buffer;
+  CProb *p = (CProb *)(buffer + sizeof(LzmaVarState));
+  CRangeDecoder rd = vs->RangeDecoder;
+  int state = vs->State;
+  int previousIsMatch = vs->PreviousIsMatch;
+  Byte previousByte;
+  UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
+  UInt32 nowPos = 0;
+  UInt32 posStateMask = (1 << (vs->pb)) - 1;
+  UInt32 literalPosMask = (1 << (vs->lp)) - 1;
+  int lc = vs->lc;
+  int len = vs->RemainLen;
+  UInt32 globalPos = vs->GlobalPos;
+
+  Byte *dictionary = vs->Dictionary;
+  UInt32 dictionarySize = vs->DictionarySize;
+  UInt32 dictionaryPos = vs->DictionaryPos;
+
+  if (len == -1)
+  {
+    *outSizeProcessed = 0;
+    return LZMA_RESULT_OK;
+  }
+
+  while(len > 0 && nowPos < outSize)
+  {
+    UInt32 pos = dictionaryPos - rep0;
+    if (pos >= dictionarySize)
+      pos += dictionarySize;
+    outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
+    if (++dictionaryPos == dictionarySize)
+      dictionaryPos = 0;
+    len--;
+  }
+  if (dictionaryPos == 0)
+    previousByte = dictionary[dictionarySize - 1];
+  else
+    previousByte = dictionary[dictionaryPos - 1];
+#else
+
+//#define DEBUG_OUTPUT
+
+#ifdef DEBUG_OUTPUT
+#include "uart16550.h"
+#include "printf.h"
+#define DBG_OUT_1(a)        ldr_printf(a)
+#define DBG_OUT_2(a, b)     ldr_printf(a, b)
+#define DBG_OUT_3(a, b, c)  ldr_printf(a, b, c)
+#else // !DEBUG_OUTPUT
+#define DBG_OUT_1(a)
+#define DBG_OUT_2(a, b)
+#define DBG_OUT_3(a, b, c)
+#endif // DEBUG_OUTPUT
+
+int LzmaDecode(
+    Byte *buffer, UInt32 bufferSize,
+    int lc, int lp, int pb,
+    #ifdef _LZMA_IN_CB
+    ILzmaInCallback *inCallback,
+    #else
+    unsigned char *inStream, UInt32 inSize,
+    #endif
+    unsigned char *outStream, UInt32 outSize,
+    UInt32 *outSizeProcessed)
+{
+  UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp));
+  CProb *p = (CProb *)buffer;
+  CRangeDecoder rd;
+  UInt32 i;
+  int state = 0;
+  int previousIsMatch = 0;
+  Byte previousByte = 0;
+  UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
+  UInt32 nowPos = 0;
+  UInt32 posStateMask = (1 << pb) - 1;
+  UInt32 literalPosMask = (1 << lp) - 1;
+  int len = 0;
+  if (bufferSize < numProbs * sizeof(CProb))
+    return LZMA_RESULT_NOT_ENOUGH_MEM;
+  for (i = 0; i < numProbs; i++)
+    p[i] = kBitModelTotal >> 1; 
+  RangeDecoderInit(&rd, 
+      #ifdef _LZMA_IN_CB
+      inCallback
+      #else
+      inStream, inSize
+      #endif
+      );
+#endif
+
+  *outSizeProcessed = 0;
+  while(nowPos < outSize)
+  {
+    if(nowPos % 1024 == 0)
+    {
+        DBG_OUT_3("%u/%u\n", nowPos, outSize);
+    }
+    int posState = (int)(
+        (nowPos 
+        #ifdef _LZMA_OUT_READ
+        + globalPos
+        #endif
+        )
+        & posStateMask);
+    #ifdef _LZMA_IN_CB
+    if (rd.Result != LZMA_RESULT_OK)
+      return rd.Result;
+    #endif
+    if (rd.ExtraBytes != 0)
+      return LZMA_RESULT_DATA_ERROR;
+    if (RangeDecoderBitDecode(p + IsMatch + (state << kNumPosBitsMax) + posState, &rd) == 0)
+    {
+      CProb *probs = p + Literal + (LZMA_LIT_SIZE * 
+        (((
+        (nowPos 
+        #ifdef _LZMA_OUT_READ
+        + globalPos
+        #endif
+        )
+        & literalPosMask) << lc) + (previousByte >> (8 - lc))));
+
+      if (state < 4) state = 0;
+      else if (state < 10) state -= 3;
+      else state -= 6;
+      if (previousIsMatch)
+      {
+        Byte matchByte;
+        #ifdef _LZMA_OUT_READ
+        UInt32 pos = dictionaryPos - rep0;
+        if (pos >= dictionarySize)
+          pos += dictionarySize;
+        matchByte = dictionary[pos];
+        #else
+        matchByte = outStream[nowPos - rep0];
+        #endif
+        previousByte = LzmaLiteralDecodeMatch(probs, &rd, matchByte);
+        previousIsMatch = 0;
+      }
+      else
+        previousByte = LzmaLiteralDecode(probs, &rd);
+      outStream[nowPos++] = previousByte;
+      #ifdef _LZMA_OUT_READ
+      dictionary[dictionaryPos] = previousByte;
+      if (++dictionaryPos == dictionarySize)
+        dictionaryPos = 0;
+      #endif
+    }
+    else             
+    {
+      previousIsMatch = 1;
+      if (RangeDecoderBitDecode(p + IsRep + state, &rd) == 1)
+      {
+        if (RangeDecoderBitDecode(p + IsRepG0 + state, &rd) == 0)
+        {
+          if (RangeDecoderBitDecode(p + IsRep0Long + (state << kNumPosBitsMax) + posState, &rd) == 0)
+          {
+            #ifdef _LZMA_OUT_READ
+            UInt32 pos;
+            #endif
+            if (
+               (nowPos 
+                #ifdef _LZMA_OUT_READ
+                + globalPos
+                #endif
+               )
+               == 0)
+              return LZMA_RESULT_DATA_ERROR;
+            state = state < 7 ? 9 : 11;
+            #ifdef _LZMA_OUT_READ
+            pos = dictionaryPos - rep0;
+            if (pos >= dictionarySize)
+              pos += dictionarySize;
+            previousByte = dictionary[pos];
+            dictionary[dictionaryPos] = previousByte;
+            if (++dictionaryPos == dictionarySize)
+              dictionaryPos = 0;
+            #else
+            previousByte = outStream[nowPos - rep0];
+            #endif
+            outStream[nowPos++] = previousByte;
+            continue;
+          }
+        }
+        else
+        {
+          UInt32 distance;
+          if(RangeDecoderBitDecode(p + IsRepG1 + state, &rd) == 0)
+            distance = rep1;
+          else 
+          {
+            if(RangeDecoderBitDecode(p + IsRepG2 + state, &rd) == 0)
+              distance = rep2;
+            else
+            {
+              distance = rep3;
+              rep3 = rep2;
+            }
+            rep2 = rep1;
+          }
+          rep1 = rep0;
+          rep0 = distance;
+        }
+        len = LzmaLenDecode(p + RepLenCoder, &rd, posState);
+        state = state < 7 ? 8 : 11;
+      }
+      else
+      {
+        int posSlot;
+        rep3 = rep2;
+        rep2 = rep1;
+        rep1 = rep0;
+        state = state < 7 ? 7 : 10;
+        len = LzmaLenDecode(p + LenCoder, &rd, posState);
+        posSlot = RangeDecoderBitTreeDecode(p + PosSlot +
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << 
+            kNumPosSlotBits), kNumPosSlotBits, &rd);
+        if (posSlot >= kStartPosModelIndex)
+        {
+          int numDirectBits = ((posSlot >> 1) - 1);
+          rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits);
+          if (posSlot < kEndPosModelIndex)
+          {
+            rep0 += RangeDecoderReverseBitTreeDecode(
+                p + SpecPos + rep0 - posSlot - 1, numDirectBits, &rd);
+          }
+          else
+          {
+            rep0 += RangeDecoderDecodeDirectBits(&rd, 
+                numDirectBits - kNumAlignBits) << kNumAlignBits;
+            rep0 += RangeDecoderReverseBitTreeDecode(p + Align, kNumAlignBits, &rd);
+          }
+        }
+        else
+          rep0 = posSlot;
+        rep0++;
+      }
+      if (rep0 == (UInt32)(0))
+      {
+        /* it's for stream version */
+        len = -1;
+        break;
+      }
+      if (rep0 > nowPos 
+        #ifdef _LZMA_OUT_READ
+        + globalPos
+        #endif
+        )
+      {
+        return LZMA_RESULT_DATA_ERROR;
+      }
+      len += kMatchMinLen;
+      do
+      {
+        #ifdef _LZMA_OUT_READ
+        UInt32 pos = dictionaryPos - rep0;
+        if (pos >= dictionarySize)
+          pos += dictionarySize;
+        previousByte = dictionary[pos];
+        dictionary[dictionaryPos] = previousByte;
+        if (++dictionaryPos == dictionarySize)
+          dictionaryPos = 0;
+        #else
+        previousByte = outStream[nowPos - rep0];
+        #endif
+        outStream[nowPos++] = previousByte;
+        len--;
+      }
+      while(len > 0 && nowPos < outSize);
+    }
+  }
+
+  #ifdef _LZMA_OUT_READ
+  vs->RangeDecoder = rd;
+  vs->DictionaryPos = dictionaryPos;
+  vs->GlobalPos = globalPos + nowPos;
+  vs->Reps[0] = rep0;
+  vs->Reps[1] = rep1;
+  vs->Reps[2] = rep2;
+  vs->Reps[3] = rep3;
+  vs->State = state;
+  vs->PreviousIsMatch = previousIsMatch;
+  vs->RemainLen = len;
+  #endif
+
+  *outSizeProcessed = nowPos;
+  return LZMA_RESULT_OK;
+}
Index: target/linux/ar7-2.6/image/src/uart16550.c
===================================================================
--- target/linux/ar7-2.6/image/src/uart16550.c	(revision 0)
+++ target/linux/ar7-2.6/image/src/uart16550.c	(revision 0)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+
+#include "uart16550.h"
+
+/* === CONFIG === */
+
+//#define REG_BASE                0xb8058000 // RouterBoard
+#define REG_BASE                0xa8610e00 // Texas Instruments AR7/Ohio/Sangam
+#define MAX_BAUD                1152000
+#define REG_OFFSET              4
+
+/* === END OF CONFIG === */
+
+/* register offset */
+#define OFS_RCV_BUFFER          (0 * REG_OFFSET)
+#define OFS_SEND_BUFFER         (0 * REG_OFFSET)
+#define OFS_INTR_ENABLE         (1 * REG_OFFSET)
+#define OFS_DATA_FORMAT         (3 * REG_OFFSET)
+#define OFS_LINE_CONTROL        (3 * REG_OFFSET)
+#define OFS_LINE_STATUS         (5 * REG_OFFSET)
+
+#define OFS_DIVISOR_LSB         (0 * REG_OFFSET)
+#define OFS_DIVISOR_MSB         (1 * REG_OFFSET)
+
+/* memory-mapped read/write of the port */
+#define UART16550_READ(y)       ( *((volatile unsigned int*)(REG_BASE + y)))
+#define UART16550_WRITE(y, z)   ((*((volatile unsigned int*)(REG_BASE + y))) = z)
+
+void Uart16550Init(unsigned int baud, unsigned char data, unsigned char parity, unsigned char stop)
+{
+    /* disable interrupts */
+    UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+    /* set up buad rate */
+    { 
+        unsigned int divisor;
+       
+        /* set DIAB bit */
+        UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+        
+        /* set divisor */
+        divisor = MAX_BAUD / baud;
+        UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+        UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00)>>8);
+
+        /* clear DIAB bit */
+        UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+    }
+
+    /* set data format */
+    UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+}
+
+unsigned char Uart16550GetPoll()
+{
+    while((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
+    return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+
+void Uart16550Put(unsigned char byte)
+{
+    while ((UART16550_READ(OFS_LINE_STATUS) &0x20) == 0);
+    UART16550_WRITE(OFS_SEND_BUFFER, byte);
+}
+
Index: target/linux/ar7-2.6/image/src/LzmaDecode.h
===================================================================
--- target/linux/ar7-2.6/image/src/LzmaDecode.h	(revision 0)
+++ target/linux/ar7-2.6/image/src/LzmaDecode.h	(revision 0)
@@ -0,0 +1,100 @@
+/* 
+  LzmaDecode.h
+  LZMA Decoder interface
+
+  LZMA SDK 4.05 Copyright (c) 1999-2004 Igor Pavlov (2004-08-25)
+  http://www.7-zip.org/
+
+  LZMA SDK is licensed under two licenses:
+  1) GNU Lesser General Public License (GNU LGPL)
+  2) Common Public License (CPL)
+  It means that you can select one of these two licenses and 
+  follow rules of that license.
+
+  SPECIAL EXCEPTION:
+  Igor Pavlov, as the author of this code, expressly permits you to 
+  statically or dynamically link your code (or bind by name) to the 
+  interfaces of this file without subjecting your linked code to the 
+  terms of the CPL or GNU LGPL. Any modifications or additions 
+  to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#ifndef __LZMADECODE_H
+#define __LZMADECODE_H
+
+/* #define _LZMA_IN_CB */
+/* Use callback for input data */
+
+/* #define _LZMA_OUT_READ */
+/* Use read function for output data */
+
+/* #define _LZMA_PROB32 */
+/* It can increase speed on some 32-bit CPUs, 
+   but memory usage will be doubled in that case */
+
+/* #define _LZMA_LOC_OPT */
+/* Enable local speed optimizations inside code */
+
+#ifndef UInt32
+#ifdef _LZMA_UINT32_IS_ULONG
+#define UInt32 unsigned long
+#else
+#define UInt32 unsigned int
+#endif
+#endif
+
+#ifdef _LZMA_PROB32
+#define CProb UInt32
+#else
+#define CProb unsigned short
+#endif
+
+#define LZMA_RESULT_OK 0
+#define LZMA_RESULT_DATA_ERROR 1
+#define LZMA_RESULT_NOT_ENOUGH_MEM 2
+
+#ifdef _LZMA_IN_CB
+typedef struct _ILzmaInCallback
+{
+  int (*Read)(void *object, unsigned char **buffer, UInt32 *bufferSize);
+} ILzmaInCallback;
+#endif
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+/* 
+bufferSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)))* sizeof(CProb)
+bufferSize += 100 in case of _LZMA_OUT_READ
+by default CProb is unsigned short, 
+but if specify _LZMA_PROB_32, CProb will be UInt32(unsigned int)
+*/
+
+#ifdef _LZMA_OUT_READ
+int LzmaDecoderInit(
+    unsigned char *buffer, UInt32 bufferSize,
+    int lc, int lp, int pb,
+    unsigned char *dictionary, UInt32 dictionarySize,
+  #ifdef _LZMA_IN_CB
+    ILzmaInCallback *inCallback
+  #else
+    unsigned char *inStream, UInt32 inSize
+  #endif
+);
+#endif
+
+int LzmaDecode(
+    unsigned char *buffer, 
+  #ifndef _LZMA_OUT_READ
+    UInt32 bufferSize,
+    int lc, int lp, int pb,
+  #ifdef _LZMA_IN_CB
+    ILzmaInCallback *inCallback,
+  #else
+    unsigned char *inStream, UInt32 inSize,
+  #endif
+  #endif
+    unsigned char *outStream, UInt32 outSize,
+    UInt32 *outSizeProcessed);
+
+#endif
Index: target/linux/ar7-2.6/image/src/print.c
===================================================================
--- target/linux/ar7-2.6/image/src/print.c	(revision 0)
+++ target/linux/ar7-2.6/image/src/print.c	(revision 0)
@@ -0,0 +1,324 @@
+/*
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include	"print.h"
+
+/* macros */
+#define		IsDigit(x)	( ((x) >= '0') && ((x) <= '9') )
+#define		Ctod(x)		( (x) - '0')
+
+/* forward declaration */
+extern int PrintChar(char *, char, int, int);
+extern int PrintString(char *, char *, int, int);
+extern int PrintNum(char *, unsigned long, int, int, int, int, char, int);
+
+/* private variable */
+static const char theFatalMsg[] = "fatal error in lp_Print!";
+
+/* -*-
+ * A low level printf() function.
+ */
+void
+lp_Print(void (*output)(void *, char *, int), 
+	 void * arg,
+	 char *fmt, 
+	 va_list ap)
+{
+
+#define 	OUTPUT(arg, s, l)  \
+  { if (((l) < 0) || ((l) > LP_MAX_BUF)) { \
+       (*output)(arg, (char*)theFatalMsg, sizeof(theFatalMsg)-1); for(;;); \
+    } else { \
+      (*output)(arg, s, l); \
+    } \
+  }
+    
+    char buf[LP_MAX_BUF];
+
+    char c;
+    char *s;
+    long int num;
+
+    int longFlag;
+    int negFlag;
+    int width;
+    int prec;
+    int ladjust;
+    char padc;
+
+    int length;
+
+    for(;;) {
+	{ 
+	    /* scan for the next '%' */
+	    char *fmtStart = fmt;
+	    while ( (*fmt != '\0') && (*fmt != '%')) {
+		fmt ++;
+	    }
+
+	    /* flush the string found so far */
+	    OUTPUT(arg, fmtStart, fmt-fmtStart);
+
+	    /* are we hitting the end? */
+	    if (*fmt == '\0') break;
+	}
+
+	/* we found a '%' */
+	fmt ++;
+	
+	/* check for long */
+	if (*fmt == 'l') {
+	    longFlag = 1;
+	    fmt ++;
+	} else {
+	    longFlag = 0;
+	}
+
+	/* check for other prefixes */
+	width = 0;
+	prec = -1;
+	ladjust = 0;
+	padc = ' ';
+
+	if (*fmt == '-') {
+	    ladjust = 1;
+	    fmt ++;
+	}
+
+	if (*fmt == '0') {
+	    padc = '0';
+	    fmt++;
+	}
+
+	if (IsDigit(*fmt)) {
+	    while (IsDigit(*fmt)) {
+		width = 10 * width + Ctod(*fmt++);
+	    }
+	}
+
+	if (*fmt == '.') {
+	    fmt ++;
+	    if (IsDigit(*fmt)) {
+		prec = 0;
+		while (IsDigit(*fmt)) {
+		    prec = prec*10 + Ctod(*fmt++);
+		}
+	    }
+	}
+
+
+	/* check format flag */
+	negFlag = 0;
+	switch (*fmt) {
+	 case 'b':
+	    if (longFlag) { 
+		num = va_arg(ap, long int); 
+	    } else { 
+		num = va_arg(ap, int);
+	    }
+	    length = PrintNum(buf, num, 2, 0, width, ladjust, padc, 0);
+	    OUTPUT(arg, buf, length);
+	    break;
+
+	 case 'd':
+	 case 'D':
+	    if (longFlag) { 
+		num = va_arg(ap, long int);
+	    } else { 
+		num = va_arg(ap, int); 
+	    }
+	    if (num < 0) {
+		num = - num;
+		negFlag = 1;
+	    }
+	    length = PrintNum(buf, num, 10, negFlag, width, ladjust, padc, 0);
+	    OUTPUT(arg, buf, length);
+	    break;
+
+	 case 'o':
+	 case 'O':
+	    if (longFlag) { 
+		num = va_arg(ap, long int);
+	    } else { 
+		num = va_arg(ap, int); 
+	    }
+	    length = PrintNum(buf, num, 8, 0, width, ladjust, padc, 0);
+	    OUTPUT(arg, buf, length);
+	    break;
+
+	 case 'u':
+	 case 'U':
+	    if (longFlag) { 
+		num = va_arg(ap, long int);
+	    } else { 
+		num = va_arg(ap, int); 
+	    }
+	    length = PrintNum(buf, num, 10, 0, width, ladjust, padc, 0);
+	    OUTPUT(arg, buf, length);
+	    break;
+	    
+	 case 'x':
+	    if (longFlag) { 
+		num = va_arg(ap, long int);
+	    } else { 
+		num = va_arg(ap, int); 
+	    }
+	    length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 0);
+	    OUTPUT(arg, buf, length);
+	    break;
+
+	 case 'X':
+	    if (longFlag) { 
+		num = va_arg(ap, long int);
+	    } else { 
+		num = va_arg(ap, int); 
+	    }
+	    length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 1);
+	    OUTPUT(arg, buf, length);
+	    break;
+
+	 case 'c':
+	    c = (char)va_arg(ap, int);
+	    length = PrintChar(buf, c, width, ladjust);
+	    OUTPUT(arg, buf, length);
+	    break;
+
+	 case 's':
+	    s = (char*)va_arg(ap, char *);
+	    length = PrintString(buf, s, width, ladjust);
+	    OUTPUT(arg, buf, length);
+	    break;
+
+	 case '\0':
+	    fmt --;
+	    break;
+
+	 default:
+	    /* output this char as it is */
+	    OUTPUT(arg, fmt, 1);
+	}	/* switch (*fmt) */
+
+	fmt ++;
+    }		/* for(;;) */
+
+    /* special termination call */
+    OUTPUT(arg, "\0", 1);
+}
+
+
+/* --------------- local help functions --------------------- */
+int
+PrintChar(char * buf, char c, int length, int ladjust)
+{
+    int i;
+    
+    if (length < 1) length = 1;
+    if (ladjust) {
+	*buf = c;
+	for (i=1; i< length; i++) buf[i] = ' ';
+    } else {
+	for (i=0; i< length-1; i++) buf[i] = ' ';
+	buf[length - 1] = c;
+    }
+    return length;
+}
+
+int
+PrintString(char * buf, char* s, int length, int ladjust)
+{
+    int i;
+    int len=0;
+    char* s1 = s;
+    while (*s1++) len++;
+    if (length < len) length = len;
+
+    if (ladjust) {
+	for (i=0; i< len; i++) buf[i] = s[i];
+	for (i=len; i< length; i++) buf[i] = ' ';
+    } else {
+	for (i=0; i< length-len; i++) buf[i] = ' ';
+	for (i=length-len; i < length; i++) buf[i] = s[i-length+len];
+    }
+    return length;
+}
+
+int
+PrintNum(char * buf, unsigned long u, int base, int negFlag, 
+	 int length, int ladjust, char padc, int upcase)
+{
+    /* algorithm :
+     *  1. prints the number from left to right in reverse form.
+     *  2. fill the remaining spaces with padc if length is longer than
+     *     the actual length
+     *     TRICKY : if left adjusted, no "0" padding.
+     *		    if negtive, insert  "0" padding between "0" and number.
+     *  3. if (!ladjust) we reverse the whole string including paddings
+     *  4. otherwise we only reverse the actual string representing the num.
+     */
+
+    int actualLength =0;
+    char *p = buf;
+    int i;
+
+    do {
+	int tmp = u %base;
+	if (tmp <= 9) {
+	    *p++ = '0' + tmp;
+	} else if (upcase) {
+	    *p++ = 'A' + tmp - 10;
+	} else {
+	    *p++ = 'a' + tmp - 10;
+	}
+	u /= base;
+    } while (u != 0);
+
+    if (negFlag) {
+	*p++ = '-';
+    }
+
+    /* figure out actual length and adjust the maximum length */
+    actualLength = p - buf;
+    if (length < actualLength) length = actualLength;
+
+    /* add padding */
+    if (ladjust) {
+	padc = ' ';
+    }
+    if (negFlag && !ladjust && (padc == '0')) {
+	for (i = actualLength-1; i< length-1; i++) buf[i] = padc;
+	buf[length -1] = '-';
+    } else {
+	for (i = actualLength; i< length; i++) buf[i] = padc;
+    }
+	    
+
+    /* prepare to reverse the string */
+    {
+	int begin = 0;
+	int end;
+	if (ladjust) {
+	    end = actualLength - 1;
+	} else {
+	    end = length -1;
+	}
+
+	while (end > begin) {
+	    char tmp = buf[begin];
+	    buf[begin] = buf[end];
+	    buf[end] = tmp;
+	    begin ++;
+	    end --;
+	}
+    }
+
+    /* adjust the string pointer */
+    return length;
+}
Index: target/linux/ar7-2.6/image/Makefile
===================================================================
--- target/linux/ar7-2.6/image/Makefile	(revision 7718)
+++ target/linux/ar7-2.6/image/Makefile	(working copy)
@@ -7,38 +7,69 @@
 include $(TOPDIR)/rules.mk
 include $(INCLUDE_DIR)/image.mk
 
+PKG_BUILD_DIR:=$(BUILD_DIR)/ar7loader
+
+LOADADDR := 0x94100000
+OUTPUT_FORMAT := elf32-tradlittlemips
+#CROSS_COMPILE = mips-linux-
+
 DROP_SECTIONS := .reginfo .mdebug .comment .note .pdr .options .MIPS.options
 OBJCOPY_SREC := $(TARGET_CROSS)objcopy -S -O srec $(addprefix --remove-section=,$(DROP_SECTIONS))
 
-LOADADDR := 0x94600000
-KERNEL_ENTRY := 0x94100000
-RAMSTART := 0x94000000
-RAMSIZE := 0x00100000
-
-LOADER_MAKEOPTS= \
-		KDIR=$(KDIR) \
-		LOADADDR=$(LOADADDR) \
-		KERNEL_ENTRY=$(KERNEL_ENTRY) \
-		RAMSTART=$(RAMSTART) \
-		RAMSIZE=$(RAMSIZE)
-
 CFLAGS := -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -Os \
 	-fno-strict-aliasing -fno-common -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic \
 	-pipe -mlong-calls -fno-common \
 	-mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap \
 	-DLOADADDR=$(LOADADDR)
 
+$(PKG_BUILD_DIR)/LzmaDecode.o: src/LzmaDecode.c
+	$(TARGET_CC) $(CFLAGS) -c -o $@ $<
+
+$(PKG_BUILD_DIR)/print.o: src/print.c
+	$(TARGET_CC) $(CFLAGS) -c -o $@ $<
+
+$(PKG_BUILD_DIR)/printf.o: src/printf.c
+	$(TARGET_CC) $(CFLAGS) -c -o $@ $<
+
+$(PKG_BUILD_DIR)/uart16550.o: src/uart16550.c
+	$(TARGET_CC) $(CFLAGS) -c -o $@ $<
+
+$(PKG_BUILD_DIR)/decompress.o: src/decompress.c
+	$(TARGET_CC) $(CFLAGS) -c -o $@ $<
+
+define Build/Compile
+	mkdir -p $(PKG_BUILD_DIR)
+	sed -e 's/@@OUTPUT_FORMAT@@/$(OUTPUT_FORMAT)/' \
+	    -e 's/@@LOADADDR@@/$(LOADADDR)/' \
+			< src/zimage.script.in \
+			> $(PKG_BUILD_DIR)/zimage.script
+	sed -e 's/@@OUTPUT_FORMAT@@/$(OUTPUT_FORMAT)/' \
+	    -e 's/@@LOADADDR@@/$(LOADADDR)/' \
+			< src/ld.script.in \
+			> $(PKG_BUILD_DIR)/ld.script
+	$(MAKE) $(PKG_BUILD_DIR)/decompress.o \
+	        $(PKG_BUILD_DIR)/uart16550.o \
+	        $(PKG_BUILD_DIR)/printf.o \
+	        $(PKG_BUILD_DIR)/print.o \
+	        $(PKG_BUILD_DIR)/LzmaDecode.o
+endef
+
 define Build/Clean
-	$(MAKE) -C $(GENERIC_PLATFORM_DIR)/image/lzma-loader $(LOADER_MAKEOPTS) clean
+	rm -rf $(PKG_BUILD_DIR)
 endef
 
 define Image/Prepare
-	cat $(KDIR)/vmlinux | $(STAGING_DIR)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $(KDIR)/vmlinux.lzma
-
-	$(MAKE) -C $(GENERIC_PLATFORM_DIR)/image/lzma-loader \
-		$(LOADER_MAKEOPTS) \
-		clean compile
-	$(OBJCOPY_SREC) $(KDIR)/loader.elf $(KDIR)/loader.srec
+	$(STAGING_DIR)/bin/lzma e -lc1 -lp2 -pb2 $(KDIR)/vmlinux $(KDIR)/vmlinux.lzma
+	$(TARGET_CROSS)ld -T $(PKG_BUILD_DIR)/zimage.script -r -b binary $(KDIR)/vmlinux.lzma -o $(KDIR)/zimage.o
+	$(TARGET_CROSS)ld -static -G 0 --defsym kernel_entry=0x$${shell $(TARGET_CROSS)nm $(KDIR)/linux-*/vmlinux | grep kernel_entry | cut -d' ' -f1} -T $(PKG_BUILD_DIR)/ld.script \
+		$(PKG_BUILD_DIR)/decompress.o \
+	    $(PKG_BUILD_DIR)/uart16550.o \
+	    $(PKG_BUILD_DIR)/printf.o \
+	    $(PKG_BUILD_DIR)/print.o \
+		$(PKG_BUILD_DIR)/LzmaDecode.o \
+		$(KDIR)/zimage.o \
+		-o $(KDIR)/loader
+	$(OBJCOPY_SREC) $(KDIR)/loader $(KDIR)/loader.srec
 	srec2bin $(KDIR)/loader.srec $(KDIR)/loader.bin
 endef
 
@@ -50,6 +81,10 @@
 bs=131072 conv=sync
 endef
 
+define align/squashfs
+bs=65536 conv=sync
+endef
+
 define Image/Build/CyberTAN
 	(dd if=/dev/zero bs=16 count=1; cat $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(1).bin) | \
 		$(STAGING_DIR)/bin/addpattern -p $(3) -o $(BIN_DIR)/openwrt-$(2)-$(KERNEL)-$(4).bin
Index: target/linux/ar7-2.6/config/default
===================================================================
--- target/linux/ar7-2.6/config/default	(revision 7718)
+++ target/linux/ar7-2.6/config/default	(working copy)
@@ -3,11 +3,11 @@
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_AR7=y
 CONFIG_AR7_GPIO=y
-CONFIG_AR7_WDT=y
+CONFIG_AR7_WDT=n
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
+# CONFIG_ATMEL is not set
 CONFIG_ATM_DRIVERS=y
-# CONFIG_ATMEL is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_BCM43XX is not set
 CONFIG_BITREVERSE=y
@@ -46,13 +46,33 @@
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_DDB5477 is not set
+CONFIG_DEBUG_DEVRES=n
+CONFIG_DEBUG_DRIVER=n
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_KOBJECT=n
+CONFIG_DEBUG_LIST=n
+CONFIG_DEBUG_LOCKING_API_SELFTESTS=n
+CONFIG_DEBUG_LOCK_ALLOC=n
+CONFIG_DEBUG_MUTEXES=n
+CONFIG_DEBUG_RT_MUTEXES=n
+CONFIG_DEBUG_SHIRQ=n
+CONFIG_DEBUG_SLAB=n
+CONFIG_DEBUG_SPINLOCK=n
+CONFIG_DEBUG_SPINLOCK_SLEEP=n
+CONFIG_DEBUG_STACK_USAGE=n
+CONFIG_DEBUG_VM=n
+CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_DM9000 is not set
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_FAULT_INJECTION=n
 CONFIG_FIXED_MII_100_FDX=y
 # CONFIG_FIXED_MII_10_FDX is not set
 CONFIG_FIXED_PHY=y
+CONFIG_FORCED_INLINING=y
 CONFIG_FS_POSIX_ACL=y
+CONFIG_GDB_CONSOLE=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_GPIO=y
 # CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
@@ -68,12 +88,16 @@
 # CONFIG_IDE is not set
 # CONFIG_IPW2100 is not set
 # CONFIG_IPW2200 is not set
+CONFIG_IP_DCCP_DEBUG=n
 CONFIG_IRQ_CPU=y
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=n
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_KGDB=y
 CONFIG_LEDS_AR7=y
+CONFIG_LEDS_AVM=y
 # CONFIG_MACH_ALCHEMY is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
@@ -102,6 +126,7 @@
 # CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_SEAD is not set
 # CONFIG_MIPS_SIM is not set
+CONFIG_MIPS_UNCACHED=n
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
@@ -158,25 +183,31 @@
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_SLRAM is not set
 CONFIG_NEED_MULTIPLE_NODES=y
+# CONFIG_NETDEV_1000 is not set
 # CONFIG_NET_PCI is not set
 CONFIG_NET_SCH_FIFO=y
 # CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_NETDEV_1000 is not set
 CONFIG_NODES_SHIFT=6
 # CONFIG_PAGE_SIZE_16KB is not set
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PCIPCWATCHDOG is not set
+CONFIG_PCI_DEBUG=n
 CONFIG_PHYLIB=y
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_PNPACPI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_PRISM54 is not set
+CONFIG_PROVE_LOCKING=n
 # CONFIG_QSEMI_PHY is not set
+CONFIG_RCU_TORTURE_TEST=n
 # CONFIG_RTC is not set
+CONFIG_RT_MUTEX_TESTER=n
+CONFIG_RUNTIME_DEBUG=n
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_SCHEDSTATS=n
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 # CONFIG_SERIAL_8250_EXTENDED is not set
 CONFIG_SERIAL_8250_PCI=y
@@ -201,6 +232,7 @@
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
 CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
 CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_TIMER_STATS=n
 # CONFIG_TOSHIBA_JMR3927 is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
 # CONFIG_TOSHIBA_RBTX4938 is not set
Index: target/linux/ar7-2.6/patches/100-board_support.patch
===================================================================
--- target/linux/ar7-2.6/patches/100-board_support.patch	(revision 7718)
+++ target/linux/ar7-2.6/patches/100-board_support.patch	(working copy)
@@ -1,7 +1,7 @@
 diff -Nru linux-2.6.19.2/arch/mips/Kconfig linux-ar7/arch/mips/Kconfig
 --- linux-2.6.19.2/arch/mips/Kconfig	2006-12-12 02:32:53.000000000 +0700
 +++ linux-ar7/arch/mips/Kconfig	2007-01-29 21:52:21.000000000 +0700
-@@ -16,6 +16,20 @@
+@@ -16,6 +16,21 @@
  	prompt "System type"
  	default SGI_IP22
  
@@ -16,6 +16,7 @@
 +	select SYS_HAS_EARLY_PRINTK
 +	select SYS_SUPPORTS_32BIT_KERNEL
 +	select SYS_SUPPORTS_LITTLE_ENDIAN
++	select SYS_SUPPORTS_KGDB
 +	select NEED_MULTIPLE_NODES
 +	select GENERIC_GPIO
 +
Index: target/linux/ar7-2.6/patches/131-leds-avm.patch
===================================================================
--- target/linux/ar7-2.6/patches/131-leds-avm.patch	(revision 0)
+++ target/linux/ar7-2.6/patches/131-leds-avm.patch	(revision 0)
@@ -0,0 +1,25 @@
+--- linux-old/drivers/leds/Kconfig	2007-06-23 16:49:13.000000000 +0200
++++ linux-new/drivers/leds/Kconfig	2007-06-23 16:50:00.000000000 +0200
+@@ -25,6 +25,12 @@
+ 	help
+ 	  This option enables support for the LEDs on TI AR7.
+ 
++config LEDS_AVM
++	tristate "LED Support for the AVM Fritz!Box"
++	depends LEDS_CLASS && AR7
++	help
++	  This option enables support for the LEDs on the AVM Fritz!Box.
++
+ config LEDS_CORGI
+ 	tristate "LED Support for the Sharp SL-C7x0 series"
+ 	depends on LEDS_CLASS && PXA_SHARP_C7xx
+--- linux-old/drivers/leds/Makefile	2007-06-23 16:50:40.000000000 +0200
++++ linux-new/drivers/leds/Makefile	2007-06-23 16:50:58.000000000 +0200
+@@ -6,6 +6,7 @@
+ 
+ # LED Platform Drivers
+ obj-$(CONFIG_LEDS_AR7)			+= leds-ar7.o
++obj-$(CONFIG_LEDS_AVM)			+= leds-avm.o
+ obj-$(CONFIG_LEDS_CORGI)		+= leds-corgi.o
+ obj-$(CONFIG_LEDS_LOCOMO)		+= leds-locomo.o
+ obj-$(CONFIG_LEDS_SPITZ)		+= leds-spitz.o