Steps:
1. You will need libusb-dev on your host box:
sudo apt-get install libusb-dev
2. Modify u-boot to boot directly if it can't find mmc:
change "run nandboot;" to "run ramboot;"
and add:
"ramboot=setenv bootargs console=ttyO2,115200n8 mem=256M no_console_suspend ramdisk_size=80000 root=/dev/ram0; bootm\0"
in this file u-boot/include/configs/omap3_beagle.h
3. Run minicom to the serial port, unplug USB OTG and brick power to
   the BeagleBoard, remove the SD Card and then run this program like this:
cd scripts
sudo omap3_usbload/omap3_usbload -f ../tftpboot/x-load.bin \
 -a 0x80008000 -f ../tftpboot/u-boot.bin \
 -a 0x82000000 -f ../tftpboot/uMulti -j 0x80008000 -v
Then plug in the USB OTG cable to your host to power the board.
Usage: omap3_usbload -f file1 [-a addr2 -f file2] [-a addr3 -f file3] [etc] [-j addr] [-v]
 NOTE: first file (file1) has no addr
 Load address MUST come before each file2-N
  uMulti is a combined kernel/filesystem.  You can substitute
uImage for uMulti and it will at least boot into the kernel,
but you won't have a filesystem.
Tested on BeagleBoardXM Rev C and Beagleboard Rev B4
  The Rev B4 Beagleboard saves u-boot environment var's in NAND so you will have to interrupt u-boot
and correct them.  Also on Rev B4 you will have to use an older kernel, this one won't work, then
interrupt u-boot and do:
setenv bootargs console=ttyS2,115200n8 mem=128M no_console_suspend ramdisk_size=80000 root=/dev/ram0; bootm 0x82000000
You could load uImage at one address, then the ramdisk file at yet another address (at say 0x830000000) and do:
setenv bootargs console=ttyS2,115200n8 mem=128M no_console_suspend ramdisk_size=80000 root=/dev/ram0 initrd=0x830000000,8M; bootm 0x82000000
http://members.efn.org/~rick/pub/0001-Add-USB-download-capability.patch
From 719f9d4d4bb09fee612abae97b28d630b6d7cfdc Mon Sep 17 00:00:00 2001
From: Rick Bronson <ri...@efn.org>
Date: Sun, 20 Nov 2011 22:22:56 -0800
Subject: [PATCH 1/1] Add USB download capability.
Signed-off-by: Rick Bronson <ri...@efn.org>
---
 board/igep00x0/config.mk         |    4 +-
 board/omap3530beagle/config.mk   |    6 +-
 board/omap3evm/config.mk         |    4 +-
 board/overo/config.mk            |    4 +-
 cpu/omap3/start.S                |   17 ++-
 drivers/Makefile                 |    2 +-
 drivers/usb.c                    |  141 ++++++++++++
 drivers/usb.h                    |   63 ++++++
 include/common.h                 |    1 +
 include/configs/omap3530beagle.h |    2 +
 lib/board.c                      |    5 +
 scripts/Makefile                 |   18 ++
 scripts/omap3_usbload.c          |  442 ++++++++++++++++++++++++++++++++++++++
 scripts/signGP.c                 |    2 +-
 14 files changed, 696 insertions(+), 15 deletions(-)
 create mode 100644 drivers/usb.c
 create mode 100644 drivers/usb.h
 create mode 100644 scripts/Makefile
 create mode 100644 scripts/omap3_usbload.c
diff --git a/board/igep00x0/config.mk b/board/igep00x0/config.mk
index 864b7d0..48f1f4b 100644
--- a/board/igep00x0/config.mk
+++ b/board/igep00x0/config.mk
@@ -14,6 +14,6 @@
 # For XIP in 64K of SRAM or debug (GP device has it all availabe)
 # SRAM 40200000-4020FFFF base
 # initial stack at 0x4020fffc used in s_init (below xloader).
-# The run time stack is (above xloader, 2k below)
+# The run time stack is within xloader (2k)
 # If any globals exist there needs to be room for them also
-TEXT_BASE = 0x40200800
+TEXT_BASE = 0x40200000
diff --git a/board/omap3530beagle/config.mk b/board/omap3530beagle/config.mk
index f271b14..c7100cb 100644
--- a/board/omap3530beagle/config.mk
+++ b/board/omap3530beagle/config.mk
@@ -10,11 +10,11 @@
 # 8000'0000 (bank0)
 
 # For use if you want X-Loader to relocate from SRAM to DDR
-#TEXT_BASE = 0x80e80000
+#TEXT_BASE = 0x40200000
 
 # For XIP in 64K of SRAM or debug (GP device has it all availabe)
 # SRAM 40200000-4020FFFF base
 # initial stack at 0x4020fffc used in s_init (below xloader).
-# The run time stack is (above xloader, 2k below)
+# The run time stack is within xloader (2k)
 # If any globals exist there needs to be room for them also
-TEXT_BASE = 0x40200800
+TEXT_BASE = 0x40200000
diff --git a/board/omap3evm/config.mk b/board/omap3evm/config.mk
index a45ec22..7b4d870 100644
--- a/board/omap3evm/config.mk
+++ b/board/omap3evm/config.mk
@@ -14,6 +14,6 @@
 # For XIP in 64K of SRAM or debug (GP device has it all availabe)
 # SRAM 40200000-4020FFFF base
 # initial stack at 0x4020fffc used in s_init (below xloader).
-# The run time stack is (above xloader, 2k below)
+# The run time stack is within xloader (2k)
 # If any globals exist there needs to be room for them also
-TEXT_BASE = 0x40200800
+TEXT_BASE = 0x40200000
diff --git a/board/overo/config.mk b/board/overo/config.mk
index 7ee3014..3ce87c3 100644
--- a/board/overo/config.mk
+++ b/board/overo/config.mk
@@ -15,6 +15,6 @@
 # For XIP in 64K of SRAM or debug (GP device has it all availabe)
 # SRAM 40200000-4020FFFF base
 # initial stack at 0x4020fffc used in s_init (below xloader).
-# The run time stack is (above xloader, 2k below)
+# The run time stack is within xloader (2k)
 # If any globals exist there needs to be room for them also
-TEXT_BASE = 0x40200800
+TEXT_BASE = 0x40200000
diff --git a/cpu/omap3/start.S b/cpu/omap3/start.S
index 4cbf437..983b065 100644
--- a/cpu/omap3/start.S
+++ b/cpu/omap3/start.S
@@ -142,9 +142,7 @@ copy_loop:
 
 	/* Set up the stack						    */
 stack_setup:
-	ldr	r0, _TEXT_BASE		/* upper 128 KiB: relocated uboot   */
-	sub	sp, r0, #128		/* leave 32 words for abort-stack   */
-	and	sp, sp, #~7		/* 8 byte alinged for (ldr/str)d    */
+	ldr	sp, _abort_stack
 
 	/* Clear BSS (if any).  Is below tx (watch load addr - need space)  */
 clear_bss:
@@ -161,7 +159,18 @@ clbss_l:
 
 _start_armboot:	.word start_armboot
 
-
+/* we can't have the stack at the beginning of SRAM, reset needs to be there */
+	.align  3
+	.octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  /* 256 bytes */
+	.octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  /* 256 bytes */
+	.octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  /* 256 bytes */
+	.octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  /* 256 bytes */
+	.octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  /* 256 bytes */
+	.octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  /* 256 bytes */
+	.octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  /* 256 bytes */
+	.octa 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  /* 256 bytes */
+abort_stack:
+_abort_stack:	.word abort_stack
 /*
  *************************************************************************
  *
diff --git a/drivers/Makefile b/drivers/Makefile
index bd620c2..807beb5 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -37,7 +37,7 @@ COBJS 	+= k9f1g08r0a.o
 endif
 
 ifeq ($(BOARD), omap3530beagle)
-COBJS 	+= k9f1g08r0a.o
+COBJS 	+= k9f1g08r0a.o usb.o
 endif
 
 ifeq ($(BOARD), omap3evm)
diff --git a/drivers/usb.c b/drivers/usb.c
new file mode 100644
index 0000000..cd77f17
--- /dev/null
+++ b/drivers/usb.c
@@ -0,0 +1,141 @@
+/*
+ * USB bootloader
+ *
+ * Copyright (C) 2011 Rick Bronson
+ *
+ * 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.
+ *
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <asm/arch/cpu.h>        /* get chip and board defs */
+#include "usb.h"
+
+extern void udelay (unsigned long usecs);
+
+typedef int boot_os_fn (void);
+
+/* send a buffer via USB */
+int usb_send(unsigned char *buffer, unsigned int buffer_size)
+	{
+	int ret = 0;
+
+	if (!(*peri_txcsr & MUSB_TXCSR_TXPKTRDY))
+		{
+		unsigned int cntr;
+
+		for (cntr = 0; cntr < buffer_size; cntr++)
+			*bulk_fifo = buffer[cntr];
+
+		*peri_txcsr |= MUSB_TXCSR_TXPKTRDY;
+
+		ret = buffer_size;
+		}
+	return ret;
+	}
+
+////////////////////
+
+static int usb_recv (u8 *buffer, int size)
+{
+	int cntr;
+	u16 count = 0;
+
+	if (*peri_rxcsr & MUSB_RXCSR_RXPKTRDY)
+		{
+		count = *rxcount;
+		for (cntr = 0; cntr < count; cntr++)
+			{
+			*buffer++ = *bulk_fifo;
+			}
+			/* Clear the RXPKTRDY bit */
+		*peri_rxcsr &= ~MUSB_RXCSR_RXPKTRDY;
+		}
+	return count;  /* FIXME */
+}
+
+static unsigned char usb_outbuffer[64];
+
+static void usb_msg (unsigned int cmd, const char *msg)
+	{
+	unsigned char *p_char = usb_outbuffer;
+
+	* (int *) p_char = cmd;
+	p_char += sizeof (cmd);
+	if (msg)
+		{
+		while (*msg)
+			*p_char++= *msg++;
+		*p_char++= 0;
+		}
+	usb_send (usb_outbuffer, p_char - usb_outbuffer);
+	}
+
+static void usb_code (unsigned int cmd, u32 code)
+	{
+	unsigned int *p_int = (unsigned int *) usb_outbuffer;
+
+	*p_int++ = cmd;
+	*p_int++ = code;
+	usb_send (usb_outbuffer, ((unsigned char *) p_int) - usb_outbuffer);
+	}
+
+void do_usb (void)
+	{
+	boot_os_fn *boot_fn;
+	int res;
+	u32 usb_inbuffer[16];
+	u32 total;
+	u8 *addr;
+	u32 bytes;
+	int size;
+	int cntr;
+
+	usb_msg (USBLOAD_CMD_FILE_REQ, "file req");
+	for (cntr = 0; cntr < 100000; cntr++)  /* try for 1 second then bail out */
+		{
+		res = usb_recv ((u8 *) usb_inbuffer, sizeof (usb_inbuffer));
+		switch (usb_inbuffer[0])
+			{
+			case USBLOAD_CMD_FILE:
+				printf ("USBLOAD_CMD_FILE total = %d addr = 0x%x val = 0x%x val = 0x%x\n", res, usb_inbuffer[0], usb_inbuffer[1], usb_inbuffer[2]);
+				total = usb_inbuffer[1];  /* get size and address */
+				addr = (u8 *) usb_inbuffer[2];
+				usb_code (USBLOAD_CMD_ECHO_SZ, total);
+
+				bytes = 0;
+				while (bytes < total)
+					{
+					size = usb_recv ((u8 *) usb_inbuffer, sizeof (usb_inbuffer));
+					memcpy(addr, usb_inbuffer, size);
+					addr += size;
+					bytes += size;
+					}
+				usb_code (USBLOAD_CMD_REPORT_SZ, total);  /* tell him we got this many bytes */
+				printf ("got file addr = 0x%x\n", addr);
+				usb_msg (USBLOAD_CMD_FILE_REQ, "file req");  /* see if they have another file for us */
+				break;
+			case USBLOAD_CMD_JUMP:
+				printf ("USBLOAD_CMD_JUMP total = %d addr = 0x%x val = 0x%x\n", res, usb_inbuffer[0], usb_inbuffer[1]);
+				boot_fn = (boot_os_fn *) usb_inbuffer[1];
+				boot_fn();  /* go to u-boot and maybe kernel */
+				break;
+			default:
+				break;
+			}
+		udelay(10);  /* delay 10 us */
+		}
+	}
diff --git a/drivers/usb.h b/drivers/usb.h
new file mode 100644
index 0000000..ba8f495
--- /dev/null
+++ b/drivers/usb.h
@@ -0,0 +1,63 @@
+/*
+ * USB bootloader
+ *
+ * Copyright (C) 2011 Rick Bronson
+ *
+ * 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.
+ *
+ */
+
+#ifndef _USB_H_
+#define _USB_H_
+
+#define OMAP34XX_USB_BASE	   (OMAP34XX_CORE_L4_IO_BASE + 0xAB000)
+
+#define OMAP34XX_USB_EP(n)         (OMAP34XX_USB_BASE + 0x100 + 0x10*(n))
+
+#define MUSB_RXCSR		0x06
+#define MUSB_RXCOUNT		0x08
+#define MUSB_TXCSR		0x02
+#define MUSB_FIFOSIZE		0x0F
+#define OMAP34XX_USB_RXCSR(n)      (OMAP34XX_USB_EP(n) + MUSB_RXCSR)
+#define OMAP34XX_USB_RXCOUNT(n)    (OMAP34XX_USB_EP(n) + MUSB_RXCOUNT)
+#define OMAP34XX_USB_TXCSR(n)      (OMAP34XX_USB_EP(n) + MUSB_TXCSR)
+#define OMAP34XX_USB_FIFOSIZE(n)   (OMAP34XX_USB_EP(n) + MUSB_FIFOSIZE)
+#define OMAP34XX_USB_FIFO(n)       (OMAP34XX_USB_BASE + 0x20 + ((n) * 4))
+
+/* memory mapped registers */
+#define BULK_ENDPOINT 1
+static volatile u16 *peri_rxcsr = (volatile u16 *) OMAP34XX_USB_RXCSR(BULK_ENDPOINT);
+#define MUSB_RXCSR_RXPKTRDY		0x0001
+static volatile u16 *rxcount    = (volatile u16 *) OMAP34XX_USB_RXCOUNT(BULK_ENDPOINT);
+static volatile u16 *peri_txcsr = (volatile u16 *) OMAP34XX_USB_TXCSR(BULK_ENDPOINT);
+#define MUSB_TXCSR_TXPKTRDY		0x0001
+static volatile u8  *bulk_fifo  = (volatile u8  *) OMAP34XX_USB_FIFO(BULK_ENDPOINT);
+
+/* In high speed mode packets are 512
+   In full speed mode packets are 64 */
+#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0  (0x0200)
+#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1  (0x0040)
+
+#define MIN(a,b) ( ((a) < (b)) ? (a) : (b))
+
+#define PACK4(a,b,c,d)     (((d)<<24) | ((c)<<16) | ((b)<<8) | (a))
+#define USBLOAD_CMD_FILE PACK4('U', 'S', 'B', 's')  /* send file size */
+#define USBLOAD_CMD_JUMP PACK4('U', 'S', 'B', 'j')  /* go where I tell you */
+#define USBLOAD_CMD_FILE_REQ PACK4('U', 'S', 'B', 'f')  /* file request */
+#define USBLOAD_CMD_ECHO_SZ PACK4('U', 'S', 'B', 'n')  /* echo file size */
+#define USBLOAD_CMD_REPORT_SZ PACK4('U', 'S', 'B', 'o')  /* report file size */
+#define USBLOAD_CMD_MESSAGE PACK4('U', 'S', 'B', 'm')  /* message for debug */
+
+#endif
diff --git a/include/common.h b/include/common.h
index a3c5092..e21cc23 100644
--- a/include/common.h
+++ b/include/common.h
@@ -111,6 +111,7 @@ void	hang		(void) __attribute__ ((noreturn));
 extern int do_load_serial_bin (ulong offset, int baudrate);
 extern u32 get_mem_type(void);
 extern int mmc_init(int verbose);
+extern void do_usb(void);
 extern int misc_init_r(void);
 
 extern int sprintf (char *__s, const char *__format, ...);
diff --git a/include/configs/omap3530beagle.h b/include/configs/omap3530beagle.h
index 5625417..76e3261 100644
--- a/include/configs/omap3530beagle.h
+++ b/include/configs/omap3530beagle.h
@@ -42,6 +42,8 @@
 
 #define CONFIG_BEAGLE_REV2	1
 
+/* Enable the below macro if you want to use omap3_usbload to download u-boot and linux via USB */
+#define CONFIG_USB 1
 /* Enable the below macro if MMC boot support is required */
 #define CONFIG_MMC	1
 #if defined(CONFIG_MMC)
diff --git a/lib/board.c b/lib/board.c
index 0f6b960..2f1d288 100644
--- a/lib/board.c
+++ b/lib/board.c
@@ -93,6 +93,11 @@ void start_armboot (void)
 
 	misc_init_r();
 
+#ifdef CONFIG_USB
+	printf("Trying load from USB\n");
+	do_usb();  /* check for usb download */
+#endif
+
 	buf =  (uchar*) CFG_LOADADDR;
 	*(int *)buf = 0xffffffff;
 
diff --git a/scripts/Makefile b/scripts/Makefile
new file mode 100644
index 0000000..04c1e55
--- /dev/null
+++ b/scripts/Makefile
@@ -0,0 +1,18 @@
+CC = gcc
+INCLUDES =
+CFLAGS = -Wall -O2 -g $(INCLUDES)
+LIBS = -lusb
+LDFLAGS = -g $(LIBS)
+APP_NAME = omap3_usbload
+
+OBJS = omap3_usbload.o
+
+all: $(APP_NAME)
+
+$(APP_NAME): $(OBJS)
+	$(CC) $(LDFLAGS) -o $@ $^
+
+clean:
+	rm -r $(APP_NAME) *.o
+
+.PHONY: all clean
diff --git a/scripts/omap3_usbload.c b/scripts/omap3_usbload.c
new file mode 100644
index 0000000..4666111
--- /dev/null
+++ b/scripts/omap3_usbload.c
@@ -0,0 +1,442 @@
+/*  $Id:  Exp $
+ *
+ * omap3_usbload, an USB download application for OMAP3 processors
+ * Copyright (C) 2008 Martin Mueller <mart...@pfump.org>
+ * Modified by Rick Bronson 2011
+ *
+ * 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, 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 paparazzi; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.  
+ *
+ */
+
+/* 
+
+  OMAP USB loader.  Using the version of x-loader with CONFIG_USB, you can
+now boot up the BeagleBoard completely into Linux with a ramdisk via USB.
+
+  Steps:
+
+1. You will need libusb-dev on your host box:
+
+sudo apt-get install libusb-dev
+
+2. Modify u-boot to boot directly if it can't find mmc:
+
+change "run nandboot;" to "run ramboot;"
+
+and add:
+
+"ramboot=setenv bootargs console=ttyO2,115200n8 mem=256M no_console_suspend ramdisk_size=80000 root=/dev/ram0; bootm\0"
+
+ in this file u-boot/include/configs/omap3_beagle.h
+
+3. Run minicom to the serial port, unplug USB OTG and brick power to
+   the BeagleBoard, remove the SD Card and then run this program like this:
+
+cd scripts
+sudo omap3_usbload/omap3_usbload -f ../tftpboot/x-load.bin \
+ -a 0x80008000 -f ../tftpboot/u-boot.bin \
+ -a 0x82000000 -f ../tftpboot/uMulti -j 0x80008000 -v
+
+  Then plug in the USB OTG cable to your host to power the board.
+
+Usage: omap3_usbload -f file1 [-a addr2 -f file2] [-a addr3 -f file3] [etc] [-j addr] [-v]
+
+ NOTE: first file (file1) has no addr
+ Load address MUST come before each file2-N
+
+  uMulti is a combined kernel/filesystem.  You can substitute
+uImage for uMulti and it will at least boot into the kernel,
+but you won't have a filesystem.
+
+  Tested on BeagleBoardXM Rev C and Beagleboard Rev B4
+
+  The Rev B4 Beagleboard saves u-boot environment var's in NAND so you will have to interrupt u-boot
+and correct them.  Also on Rev B4 you will have to use an older kernel, this one won't work, then
+interrupt u-boot and do:
+
+setenv bootargs console=ttyS2,115200n8 mem=128M no_console_suspend ramdisk_size=80000 root=/dev/ram0; bootm 0x82000000
+
+  You could load uImage at one address, then the ramdisk file at yet another address (at say 0x830000000) and do:
+
+setenv bootargs console=ttyS2,115200n8 mem=128M no_console_suspend ramdisk_size=80000 root=/dev/ram0 initrd=0x830000000,8M; bootm 0x82000000
+
+*/
+
+#include <getopt.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <usb.h>
+
+#define VERSION "1.1"
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# define cpu_to_le32(x)	(x)
+# define le32_to_cpu(x)	(x)
+#else
+# define cpu_to_le32(x)	bswap_32 (x)
+# define le32_to_cpu(x)	bswap_32 (x)
+#endif
+
+#define VENDOR_ID_TI       0x0451
+#define DEVICE_ID          0xD000
+#define DEVICE_ID_MASK     0xff00
+
+#define OMAP3_BOOT_CMD     0xF0030002  /* see page 3515 sprugn4c.pdf */
+
+#define PACK4(a,b,c,d)     (((d)<<24) | ((c)<<16) | ((b)<<8) | (a))
+#define USBLOAD_CMD_FILE PACK4('U', 'S', 'B', 's')  /* send file size */
+#define USBLOAD_CMD_JUMP PACK4('U', 'S', 'B', 'j')  /* go where I tell you */
+#define USBLOAD_CMD_FILE_REQ PACK4('U', 'S', 'B', 'f')  /* file request */
+#define USBLOAD_CMD_ECHO_SZ PACK4('U', 'S', 'B', 'n')  /* echo file size */
+#define USBLOAD_CMD_REPORT_SZ PACK4('U', 'S', 'B', 'o')  /* report file size */
+#define USBLOAD_CMD_MESSAGE PACK4('U', 'S', 'B', 'm')  /* message for debug */
+
+#define EP_BULK_IN         0x81
+#define EP_BULK_OUT        0x01
+#define BUF_LEN             128
+#define BUF_LEN_SM          256 /* we seem to need this exact size ?? */
+
+#define USB_TIMEOUT 1000  /* time in ms */
+
+#define MAX_FILES 10  /* the max addr/file pairs */
+struct UPLOAD_DATA
+	{
+	int file_cntr;
+	unsigned long addrs[MAX_FILES];
+	int fd[MAX_FILES];
+	int filesize[MAX_FILES];
+	const char *filename[MAX_FILES];  /* file names */
+	unsigned long jump_addr;
+	usb_dev_handle *udev;
+	int verbose;  /* be verbose? */
+	char *p_file;
+	};
+
+struct UPLOAD_DATA upload_data =
+	{
+	.verbose = 0,  /* be verbose? */
+	.filename[0] = NULL,
+	.jump_addr = 0x80008000,
+	.p_file = NULL,
+	};
+
+
+  /* A string listing valid short options letters.  */
+const char* const short_options = "a:f:j:v";
+  /* An array describing valid long options.  */
+const struct option long_options[] = {
+    { "load_addr",     1, NULL, 'a' },
+    { "file",     1, NULL, 'f' },
+    { "jump",      1, NULL, 'j' },
+    { "verbose",   0, NULL, 'v' },
+    { NULL,        0, NULL, 0   }   /* Required at end of array.  */
+  };
+
+/* send a value to x-loader */
+static int send_val (struct UPLOAD_DATA *p_data, unsigned int code, unsigned int val1, unsigned int val2)
+{
+	int	res;
+	int buffer[3];
+
+	buffer[0]= code;
+	buffer[1] = cpu_to_le32 (val1);
+	buffer[2] = cpu_to_le32 (val2);
+
+	if (p_data->verbose)
+		printf ("send_val code = 0x%x, val1 = 0x%x, val2 = 0x%x\n",(int) buffer[0], (int) buffer[1], (int) buffer[2]);
+	res= usb_bulk_write (p_data->udev, EP_BULK_OUT, (const char *) buffer, sizeof (buffer), USB_TIMEOUT);
+	if (res < sizeof (buffer))
+	{
+		printf ("Error in usb_bulk_write1: %d/8\n", res);
+		return 1;
+	}
+
+	return 0;
+}
+
+void print_usage (FILE* stream, int exit_code)
+  {
+  fprintf (stream, "Usage: omap3_usbload -f file1 [-a addr2 -f file2] [-a addr3 -f file3] [etc] [-j addr] [-v]\n");
+  fprintf (stream,
+           "  -f  --file file           File to load, first file (file1) has no addr\n"
+           "  -a  --load_addr addr      Load address, MUST come before each file2-N\n"
+           "  -j  --jump addr           Jump address[0x80008000]\n");
+  exit (exit_code);
+}
+
+enum {  /* subroutine return codes */
+	RET_OK,
+	RET_ERR,
+	RET_IN_LOOP
+};
+
+int do_files(struct UPLOAD_DATA *p_data)
+	{
+	int res, sz, file_cnt, file_len, size, usb_cnt;
+	int dat_buf[BUF_LEN];
+	unsigned int command;
+	int this_file = 1;  /* start with the 2nd file */
+	char *p_file;
+
+	file_cnt = usb_bulk_read(p_data->udev, EP_BULK_IN, (char *) dat_buf, sizeof (dat_buf), USB_TIMEOUT);
+	if (file_cnt <= 0)
+		{
+		printf("could not get ASIC ID\n");
+		return(-1);
+		}
+
+	command = OMAP3_BOOT_CMD;
+	if (sizeof(command) != usb_bulk_write(p_data->udev, EP_BULK_OUT, (char*) &command, sizeof(command), USB_TIMEOUT))
+		{
+		printf("could not send peripheral boot command\n");
+		return(-1);
+		}
+
+	file_len = p_data->filesize[0];
+	if (sizeof(file_len) != usb_bulk_write(p_data->udev, EP_BULK_OUT, (char*) &file_len, sizeof(file_len), USB_TIMEOUT))
+		{
+		printf("could not send length\n");
+		return(-1);
+		}
+
+	do
+		{
+		file_cnt = read(p_data->fd[0], dat_buf, sizeof (dat_buf));
+		if (file_cnt > 0)
+			{
+			usb_cnt = usb_bulk_write(p_data->udev, EP_BULK_OUT, (char *) dat_buf, file_cnt, USB_TIMEOUT);            
+
+			if (usb_cnt != file_cnt)
+				{
+				printf("could not write to usb usb_cnt = %d file_cnt = %d\n", usb_cnt, file_cnt );
+				return(-1);
+				}
+			}
+		} while (file_cnt > 0);
+
+	if (p_data->verbose)
+		printf("download ok\n");
+	close(p_data->fd[0]);
+	p_data->fd[0] = 0;  /* mark as closed */
+
+	/* now wait for x-loader */
+	while ((size = p_data->filesize[this_file]) > 0)
+		{
+		if (p_data->verbose)
+			printf ("while loop size = %d\n", size);
+		p_file = p_data->p_file = malloc (p_data->filesize[this_file]);
+		if (p_file == NULL)
+			{
+			printf ("Out of memory requesting %d bytes\n", p_data->filesize[this_file]);
+			return 1;
+			}
+		/* read whole file in */
+		if ((p_data->filesize[this_file] = read (p_data->fd[this_file], p_file, p_data->filesize[this_file])) < 0)
+			{
+			perror ("read file");
+			return 1;
+			}
+		if (p_data->verbose)
+			printf ("filesize = %d\n", p_data->filesize[this_file]);
+		close (p_data->fd[this_file]);
+
+		while (size > 0)
+			{
+			res= usb_bulk_read (p_data->udev, EP_BULK_IN, (char *) dat_buf, sizeof (dat_buf), USB_TIMEOUT);
+			if (res < 0)
+				{
+				printf("Error in usb_bulk_read: %d\n", res);
+				return 1;
+				}
+			if (res < 8)
+				continue;
+
+			switch (dat_buf[0])
+				{
+				case USBLOAD_CMD_FILE_REQ:
+					if (p_data->verbose)
+						printf("f: size = %d, addr = 0x%x\n", size, (int) p_data->addrs[this_file]);
+					if (send_val (p_data, USBLOAD_CMD_FILE, size, p_data->addrs[this_file]))
+						size= -1;
+					break;
+
+				case USBLOAD_CMD_REPORT_SZ:  /* he tells us how many btyes are left */
+					size -= le32_to_cpu (dat_buf[1]);
+					if (size > 0)
+						size= -1;
+					break;
+
+				case USBLOAD_CMD_ECHO_SZ:  /* he echo's the file size */
+					sz = le32_to_cpu (dat_buf[1]);
+					if (p_data->verbose)
+						printf("sending file, size %d %d\n", sz, res);
+					while (sz > 0)
+						{
+						res = usb_bulk_write(p_data->udev, EP_BULK_OUT, p_file, BUF_LEN_SM, USB_TIMEOUT);
+						if (res != BUF_LEN_SM) {
+							printf("Error in usb_bulk_write3: %d/%d\n", res, sz);
+							size = -1;
+							break;
+							}
+						p_file += res;
+						sz -= res;
+						}
+					break;
+
+				case USBLOAD_CMD_MESSAGE:
+					printf("Message: %s\n", (char *) &dat_buf[1]);
+					break;
+
+				default:
+					printf("Unknown packet type '%s'\n", (char *) dat_buf[1]);
+					break;
+				}
+			}
+		if (size == 0 && p_data->verbose)
+			printf("Program stored in memory: %d bytes\n", p_data->filesize[this_file]);
+		this_file++;  /* next */
+		free (p_data->p_file);
+		p_data->p_file = NULL;  /* mark as freed */
+		}
+	if (p_data->jump_addr)
+		{
+		send_val (p_data, USBLOAD_CMD_JUMP, p_data->jump_addr, 0);  /* go to address */
+		if (p_data->verbose)
+			printf("Sending jump 0x%x\n", (int) p_data->jump_addr);
+		}
+	return 0;
+	}
+
+enum {  /* need to have at least one file to load */
+	ARG_PROGNAME,
+	ARG_BINFILE,
+	NUM_ARGS
+};
+
+int main(int argc, char **argv)
+	{
+	struct UPLOAD_DATA *p_data;
+	int next_option;
+	struct usb_bus *bus;
+	int file_cntr = 0, res = RET_IN_LOOP;
+
+	p_data = &upload_data;
+	do
+		{
+		next_option = getopt_long (argc, argv, short_options,
+			long_options, NULL);
+		switch (next_option)
+			{
+			case 'a':   /* -a or --load_addr */
+			/* This option takes an argument, the address to load the file into.  */
+				p_data->addrs[file_cntr] = strtoul (optarg, NULL, 0);
+				break;
+			case 'f':   /* -f or --file */
+			/* This option takes an argument, the name of the file. */
+				p_data->filename[file_cntr] = optarg;
+				p_data->fd[file_cntr] = open(p_data->filename[file_cntr], O_RDONLY);
+				if (p_data->fd[file_cntr] < 0)
+					{
+					perror("Can't open file");
+					return 1;
+					}
+				p_data->filesize[file_cntr] = lseek (p_data->fd[file_cntr], 0, SEEK_END);
+				if (p_data->filesize[file_cntr] < 0  ||  lseek (p_data->fd[file_cntr], 0, SEEK_SET) < 0)
+					{
+					perror ("lseek binfile");
+					close (p_data->fd[file_cntr]);
+					return 1;
+					}
+				if (p_data->verbose)
+					printf("Opening %s fd = %d, size = %d\n", p_data->filename[file_cntr], p_data->fd[file_cntr], p_data->filesize[file_cntr]);
+				file_cntr++;  /* go to next file */
+				break;
+			case 'j':   /* -j or --jump */
+			/* This option takes an argument, the jump address. */
+				p_data->jump_addr = strtoul (optarg, NULL, 0);
+				break;
+			case 'v':   /* -v or --verbose */
+				p_data->verbose = 1;
+				break;
+			case '?':   /* The user specified an invalid option.  */
+			/* Print usage information to standard error, and exit with exit
+				 code one (indicating abonormal termination).  */
+				print_usage (stderr, 1);
+				break;
+			case -1:    /* Done with options.  */
+				break;
+			default:    /* Something else: unexpected.  */
+				print_usage (stderr, 1);
+			}
+		}
+	while (next_option != -1);
+
+	if (argc < NUM_ARGS) {
+		print_usage (stderr, 1);
+		return(-1);
+		}
+
+	usb_init();
+	usb_find_busses();
+
+	while (res == RET_IN_LOOP)
+		{
+		printf(".");
+		fflush(stdout);
+
+		if (usb_find_devices())
+			{
+			for (bus = usb_get_busses(); bus; bus = bus->next)
+				{
+				struct usb_device *dev;
+
+				for (dev = bus->devices; dev; dev = dev->next)
+					{
+					if (dev->descriptor.idVendor == VENDOR_ID_TI &&
+						(dev->descriptor.idProduct & DEVICE_ID_MASK) == DEVICE_ID)
+						{
+						p_data->udev = usb_open(dev);
+
+						if (p_data->udev)
+							{
+							if (p_data->verbose)
+								printf("\n\nfound device 0x%04x:0x%04x\n", dev->descriptor.idVendor, dev->descriptor.idProduct);
+
+							if (usb_set_configuration(p_data->udev, 1) < 0)
+								{
+								printf("could not set configuration\n");
+								res = RET_ERR;
+								}
+							if (do_files(p_data))  /* if an error occurred */
+								res = RET_ERR;
+							else
+								res = RET_OK;
+							}
+						}
+					}
+				}
+			}
+		usleep(500 * 1000); /* wait until we put another dot */
+		}
+	for (file_cntr = 0; file_cntr < MAX_FILES; file_cntr++)  /* close all files */
+		if (p_data->fd[file_cntr])
+			close(p_data->fd[file_cntr]);
+	if (p_data->p_file)
+		free (p_data->p_file);
+	usb_close(p_data->udev);
+	return(res);
+	}
diff --git a/scripts/signGP.c b/scripts/signGP.c
index ab4715c..a11b533 100644
--- a/scripts/signGP.c
+++ b/scripts/signGP.c
@@ -255,7 +255,7 @@ int main(int argc, char *argv[])
 
 	/* Default to x-load.bin and 0x40200800. */
 	strcpy(ifname, "x-load.bin");
-	loadaddr = 0x40200800;
+	loadaddr = 0x40200000;
 
 	if ((argc == 2) || (argc == 3) || (argc == 4))
 		strcpy(ifname, argv[1]);
-- 
1.7.7.3