Index: /tt-loader/2nd/Makefile
===================================================================
--- /tt-loader/2nd/Makefile	(revision 11)
+++ /tt-loader/2nd/Makefile	(revision 11)
@@ -0,0 +1,49 @@
+CROSS = armv5tel-redhat-linux-gnueabi
+CC = $(CROSS)-gcc
+INCLUDES =
+CFLAGS = -g -Wall -fverbose-asm -march=armv5t -mtune=arm926ej-s \
+	-msoft-float $(INCLUDES)
+LIBS =
+LDFILE = arm.ld
+LDFLAGS = $(LIBS) -T $(LDFILE)
+APP_NAME = 2nd
+OBJ_ADDR ?= 0x10000000
+
+S_SRCS = start.S
+C_SRCS = main.c usb.c
+SRCS = $(S_SRCS) $(C_SRCS)
+
+OBJS = $(S_SRCS:.S=.o) $(C_SRCS:.c=.o)
+ALL = $(APP_NAME).bin $(APP_NAME).asm
+
+all:
+	$(MAKE) $(ALL) DEPEND=.depend
+
+clean:
+	rm -f *.o *.elf *.bin *.map *.asm *.dis .depend *~
+
+$(APP_NAME).elf: $(LDFILE) $(OBJS)
+	$(CROSS)-ld $(LDFLAGS) -Map $(APP_NAME).map -o $@ $(OBJS)
+
+$(APP_NAME).asm: $(APP_NAME).elf
+	$(CROSS)-objdump -d -S $(APP_NAME).elf >$(APP_NAME).asm
+
+%.dis: %.mtd
+	$(CROSS)-objcopy -I binary -O elf32-littlearm -B arm $< $(@F).elf
+	$(CROSS)-objdump -D --adjust-vma=$(OBJ_ADDR) $(@F).elf > $@
+
+%.bin: %.elf
+	$(CROSS)-objcopy -O binary $< $@
+
+dep: .depend
+
+.depend: $(SRCS)
+	$(CC) -M -MG $(INCLUDES) $^ > .depend
+
+ifdef DEPEND
+include $(DEPEND)
+endif
+
+.depend: $(SRCS)
+
+.PHONY: dep all clean
Index: /tt-loader/2nd/arm.ld
===================================================================
--- /tt-loader/2nd/arm.ld	(revision 11)
+++ /tt-loader/2nd/arm.ld	(revision 11)
@@ -0,0 +1,41 @@
+/*STARTUP(main.o)*/
+ENTRY(_start)
+
+MEMORY 
+{
+/*	sram (rwx) : ORIGIN = 0x20000000, LENGTH = 256K */
+	sram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
+}
+
+SECTIONS
+{
+
+/* TEXT */
+	.text 0x20000400 :
+	{
+		*(.text.start)
+		*(.text)
+	} > sram
+
+	.rodata ALIGN(0x04) :
+	{
+		*(.rodata)
+	} > sram
+
+	.data ALIGN(0x04) :
+	{
+		*(.data.pirq)
+		*(.data)
+		*(.sdata)
+	} > sram
+
+	.bss (NOLOAD) :
+	{
+		bstart = . ;
+		*(.ram.start)
+		*(.bss)
+		*(.sbss)
+		*(COMMON)
+		bend = . ;
+	} > sram
+}
Index: /tt-loader/2nd/config.h
===================================================================
--- /tt-loader/2nd/config.h	(revision 11)
+++ /tt-loader/2nd/config.h	(revision 11)
@@ -0,0 +1,44 @@
+/*
+ * 2nd - OMAP "second stage" tt-Loader
+ *
+ * Copyright (C) 2008 Guillaume Bougard <gbougard@pkg.fr>
+ * Copyright (C) 2005 Luis Recuerda <lrec@helios.homeip.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.
+ *
+ * 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 "types.h"
+
+#ifndef _CONFIG_H_
+#define _CONFIG_H_
+
+// Default address in SRAM
+#define CFG_LOADADDR			0x20000400
+
+// Address to find jtag id, to check on which target we are running
+#define OMAP_PRODUCTION_ID_1	0xfffe2004
+#define OMAP32_ID_1				0xfffed404
+
+// Extracted & adapted from linux sources: linux-2.6.24.3/include/asm-arm/arch-omap/io.h
+#define omap_readb(a)		(*(volatile u8    *)(a))
+#define omap_readw(a)		(*(volatile u16   *)(a))
+#define omap_readl(a)		(*(volatile u32   *)(a))
+
+#define omap_writeb(v,a)	(*(volatile u8    *)(a) = (v))
+#define omap_writew(v,a)	(*(volatile u16   *)(a) = (v))
+#define omap_writel(v,a)	(*(volatile u32   *)(a) = (v))
+
+#endif
Index: /tt-loader/2nd/main.c
===================================================================
--- /tt-loader/2nd/main.c	(revision 11)
+++ /tt-loader/2nd/main.c	(revision 11)
@@ -0,0 +1,272 @@
+/*
+ * 2nd - OMAP "second stage" tt-loader
+ *
+ * Copyright (C) 2008 Guillaume Bougard <gbougard@pkg.fr>
+ * Copyright (C) 2005 Luis Recuerda <lrec@helios.homeip.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.
+ *
+ * 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 "config.h"
+#include "usb.h"
+
+#define _LSR_   ((volatile u8 *) 0xfffb0014)
+#define _THR_   ((volatile u8 *) 0xfffb0000)
+#define _RHR_   ((volatile u8 *) 0xfffb0000)
+
+#define MEM_READ_SIZE	32
+
+static char *usb_hdr = "TIS" ;
+static char usb_outbuffer[64];
+
+// limited strcpy
+static u32 strcpy ( char *dest, char *src )
+{
+	u32 count = 0 ;
+	char *tmp = dest, *s = src;
+	
+	while ( ++count < 256 && *s != '\0' )
+		*tmp++ = *s++ ;
+	
+	*tmp = '\0' ;
+	
+	return count ;
+}
+
+static u32 memcpy ( char *dest, char *src, u32 count )
+{
+	char *tmp = dest, *s = src;
+	u32 step = count ;
+
+	while (step--)
+		*tmp++ = *s++;
+	
+	return count ;
+}
+
+static void bsend (char ch)
+{
+	while (!((*_LSR_) & 0x20));
+	*_THR_= ch;
+}
+
+static inline int check_serial (void) { return (*_LSR_) & 0x01; }
+
+static char brecv (void)
+{
+	while (!((*_LSR_) & 0x01));
+	return *_RHR_;
+}
+
+char crecv (void)
+{
+	return brecv ();
+}
+
+void csend (char ch)
+{
+	if (ch == '\n')
+		bsend ('\r');
+	bsend (ch);
+}
+
+void tsend (const char *text)
+{
+	while (*text)
+		csend (*text++);
+}
+
+void xsend (unsigned value)
+{
+	if (value < 10)
+		bsend (value + '0');
+	else
+		bsend (value + ('A'-10));
+}
+
+void x8send (u8 value)
+{
+	xsend (value >> 4);
+	xsend (value & 0xf);
+}
+
+void x16send (u16 value)
+{
+	int	i;
+	for (i= 0; i < 4; ++i)
+	{
+		xsend (value >> 12);
+		value<<= 4;
+	}
+}
+
+void x32send (u32 value)
+{
+	int	i;
+	for (i= 0; i < 8; ++i)
+	{
+		xsend (value >> 28);
+		value<<= 4;
+	}
+}
+
+static void usb_msg (const char cmd, const char *msg)
+{
+	u32 len = strcpy(usb_outbuffer,usb_hdr);
+	usb_outbuffer[len-1] = cmd ;
+	
+	len += strcpy(&usb_outbuffer[len], msg ? (char *)msg : "" );
+
+	usb_send ( usb_outbuffer, len);
+	while (!usb_sent ());
+}
+
+static u32 usb_code (char cmd, u32 code)
+{
+	u32 len = strcpy(usb_outbuffer,usb_hdr);
+	usb_outbuffer[len-1] = cmd ;
+	(*(u32 *)(usb_outbuffer+len)) = code ;
+	len += sizeof(u32);
+
+	usb_send ( usb_outbuffer, len );
+	while (!usb_sent ());
+	return code ;
+}
+
+static void usb_blk (const char cmd, char *mem, u32 size)
+{
+	u32 len = strcpy(usb_outbuffer,usb_hdr);
+	usb_outbuffer[len-1] = cmd ;
+
+	len += memcpy(usb_outbuffer+len,mem,size);
+	
+	usb_send ( usb_outbuffer, len );
+	while (!usb_sent ());
+}
+
+// Code from linux-2.6.24.3/arch/arm/mach-omap1/id.c source
+static u16 omap_get_jtag_id(void)
+{
+	u32 prod_id, jtag_id;
+
+	prod_id = omap_readl(OMAP_PRODUCTION_ID_1);
+	jtag_id = omap_readl(OMAP32_ID_1);
+	
+	/* Check for unusable OMAP_PRODUCTION_ID_1 on 1611B/5912 and 730 */
+	if (((prod_id >> 20) == 0) || (prod_id == jtag_id))
+		prod_id = 0;
+	else
+		prod_id &= 0xffff;
+
+	if (prod_id)
+		return prod_id;
+
+	/* Use OMAP32_ID_1 as fallback */
+	prod_id = ((jtag_id >> 12) & 0xffff);
+
+	return prod_id;
+}
+
+u32 _main (void)
+{	
+	u32 address = CFG_LOADADDR ;
+	usb_msg ('m', "In omap plateform");
+	
+	u16 prod_id = omap_get_jtag_id();
+	switch (prod_id)
+	{
+		case 0xb55f:
+			usb_msg ('m', "Found supported omap730");
+			break;
+		default:
+			usb_msg ('m', "Unsupported plateform found");
+			usb_code ('v', (u32) prod_id);
+			break;
+	}
+	
+	// Ready to manage requests
+	usb_msg ('r', "Waiting first request");
+	
+	for (;;)
+	{
+		u32 total, cmd, index = 0 ;
+		
+		u8 usb_inbuffer[64];
+		usb_recv (usb_inbuffer, sizeof (usb_inbuffer));
+		while (!usb_rcvd ());
+		
+		// Check we are knowing the provided header
+		while ( usb_inbuffer[index] == (u8) usb_hdr[index] && usb_hdr[index] != '\0' )
+			index++ ;
+		
+		if ( usb_hdr[index] != '\0' )
+			continue ;
+		
+		cmd = usb_inbuffer[index++] ;
+		
+		if ((char)cmd == 's') // Ask size to upload
+		{
+			total= *(u32 *) &usb_inbuffer[index];
+			u32 size = 0;
+
+			usb_code ('n', total);
+
+			while (size < total)
+			{
+				u32	r;
+				
+				usb_recv ((u8 *)address, sizeof (usb_inbuffer));
+				while ((r= usb_rcvd ()) == 0);
+								
+				address += r ;
+				size += r ;
+			}
+			
+			usb_code ('o', size);
+			
+		} else
+		if ((char)cmd == 'f') // load file ACK
+		{
+			usb_msg ('f', (const char *)&usb_inbuffer[index]);
+			
+		} else
+		if ((char)cmd == 'M') // dump memory command
+		{
+			usb_blk ('M', (char *)address, MEM_READ_SIZE);
+			address += MEM_READ_SIZE ;
+			
+		} else
+		if ((char)cmd == 'a') // set address command
+		{
+			address = *(u32 *) &usb_inbuffer[index];
+			usb_code ('i', address);
+			
+		} else
+		if ((char)cmd == 'c') // call command
+		{
+			index = ((u32_fnc_t *)address)();
+			usb_code ('i', index);
+			
+		} else
+		if ((char)cmd == 'b') // boot command
+		{
+			usb_code ('b', address );
+			// Just return the address where is store the branch to do
+			u32 bootaddress = (u32) &address ; // Convert/cast address just to avoid gcc warning
+			return bootaddress ;
+		}
+	}
+}
Index: /tt-loader/2nd/start.S
===================================================================
--- /tt-loader/2nd/start.S	(revision 11)
+++ /tt-loader/2nd/start.S	(revision 11)
@@ -0,0 +1,124 @@
+/*
+ * 2nd - OMAP "second stage" tt-loader
+ *
+ * Copyright (C) 2008 Guillaume Bougard <gbougard@pkg.fr>
+ * Copyright (C) 2005 Luis Recuerda <lrec@helios.homeip.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.
+ *
+ * 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.
+ *
+ */
+
+.equ WATCHDOG_VAL1, 0xf5
+.equ WATCHDOG_VAL2, 0xa0
+
+	.code 32
+
+_vectors:
+
+	.extern bend
+
+.word	_start-_vectors
+.word	bend-_start
+.word	0, 0, 0
+.word	0x00444e32
+.word	0, 0
+.word	0xffffffff
+.word	0xffffffff
+.word	0xffffffff
+.word	0xffffffff
+.word	0xffffffff
+.word	0xffffffff
+.word	0xffffffff
+.word	0xffffffff
+
+	.global	_start
+_start:
+	/*
+	 * set the cpu to SVC32 mode as in x-load
+	 */
+	mrs r0, cpsr
+	bic r0, r0, #0x1f
+	orr r0, r0, #0xd3
+	msr cpsr, r0
+
+	// Turn off the watchdog during init...
+	ldr r0, REG_WDT_TIMER_MODE
+	mov r1, #WATCHDOG_VAL1
+	str r1, [r0]
+	mov r1, #WATCHDOG_VAL2
+	str r1, [r0]
+
+	// Mask all IRQs by setting all bits in the INTMR default
+	mov r1, #0xffffffff
+	ldr r0, REG_IHL1_MIR
+	str r1, [r0]
+	ldr r0, REG_IHL2_MIR
+	str r1, [r0]
+
+	// flush v4 I/D caches
+	mov r0, #0
+	mcr p15, 0, r0, c7, c7, 0   // flush v3/v4 cache
+	mcr p15, 0, r0, c8, c7, 0   // flush v4 TLB
+
+	// disable MMU stuff and caches
+	mrc p15, 0, r0, c1, c0, 0
+	bic r0, r0, #0x00002300     // clear bits 13, 9:8 (--V- --RS)
+	bic r0, r0, #0x00000087     // clear bits 7, 2:0 (B--- -CAM)
+	orr r0, r0, #0x00000002     // set bit 2 (A) Align
+	orr r0, r0, #0x00001000     // set bit 12 (I) I-Cache
+	mcr p15, 0, r0, c1, c0, 0
+
+	ldr r0, REG_WSPR
+	ldr r1, WSPR_VAL1
+	str r1, [r0]
+	ldr	r2, REG_WWPS
+
+watch1Wait:
+	ldr	r1, [r2]
+	tst	r1, #0x10
+	bne	watch1Wait
+
+	ldr r1, WSPR_VAL2
+	str r1, [r0]
+watch2Wait:
+	ldr r1, [r2]
+	tst r1, #0x10
+	bne watch2Wait
+
+	ldr sp, _stack
+
+	.extern _main
+	bl _main
+	ldr pc, [r0]			// Branch to content of mem returned as boot command
+
+
+WSPR_VAL1:
+	.word 0x0000aaaa
+WSPR_VAL2:
+	.word 0x00005555
+
+REG_IHL1_MIR:                   // 32 bits
+	.word 0xfffecb04
+REG_IHL2_MIR:                   // 32 bits
+	.word 0xfffe0004
+REG_WDT_TIMER_MODE:				// 16 bits
+	.word 0xfffec808
+REG_WSPR:
+	.word 0xfffeb048
+REG_WWPS:
+	.word 0xfffeb034
+
+_stack:
+	.word	0x2000F000
Index: /tt-loader/2nd/types.h
===================================================================
--- /tt-loader/2nd/types.h	(revision 11)
+++ /tt-loader/2nd/types.h	(revision 11)
@@ -0,0 +1,35 @@
+/*
+ * 2nd - OMAP "second stage" tt-loader
+ *
+ * Copyright (C) 2008 Guillaume Bougard <gbougard@pkg.fr>
+ * Copyright (C) 2005 Luis Recuerda <lrec@helios.homeip.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.
+ *
+ * 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 _TYPES_H_
+#define _TYPES_H_
+
+#define	NULL	((void *) 0)
+
+typedef unsigned char	u8;
+typedef unsigned short	u16;
+typedef unsigned int	u32;
+
+typedef u32 (u32_fnc_t) (void);
+typedef void (init_fnc_t) (void);
+
+#endif
Index: /tt-loader/2nd/usb.c
===================================================================
--- /tt-loader/2nd/usb.c	(revision 11)
+++ /tt-loader/2nd/usb.c	(revision 11)
@@ -0,0 +1,262 @@
+/*
+ * 2nd - OMAP "second stage" Flash Loader
+ *
+ * Copyright (C) 2008 Guillaume Bougard <gbougard@pkg.fr>
+ * Copyright (C) 2005 Luis Recuerda <lrec@helios.homeip.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.
+ *
+ * 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 "types.h"
+#include "usb.h"
+
+#define	USBS_OFFSET	0xfffb4000
+#define	REG8(addr)	(*(volatile u8 *) (addr))
+#define	REG16(addr)	(*(volatile u16 *) (addr))
+#define	REG32(addr)	(*(volatile u32 *) (addr))
+#define	UREG(addr)	REG16 (USBS_OFFSET + (addr))
+#define	UREG8(addr)	REG8 (USBS_OFFSET + (addr))
+
+#define	CLOCK_CTRL_REG	REG16 (0xfffe0830)
+#define	FUNC_MUX_CTRL_D	REG32 (0xfffe1038)
+
+#define	USBS_REV	UREG (0x00)
+#define	USBS_EP_NUM	UREG (0x04)
+#define	USBS_DATA	UREG (0x08)
+#define	USBS_DATA8	UREG8 (0x08)
+#define	USBS_CTRL	UREG (0x0c)
+#define	USBS_STAT_FLG	UREG (0x10)
+#define	USBS_RXFSTAT	UREG (0x14)
+#define	USBS_SYSCON1	UREG (0x18)
+#define	USBS_SYSCON2	UREG (0x1c)
+#define	USBS_DEVSTAT	UREG (0x20)
+#define	USBS_SOF	UREG (0x24)
+#define	USBS_IRQ_EN	UREG (0x28)
+#define	USBS_DMA_IRQ_EN	UREG (0x2c)
+#define	USBS_IRQ_SRC	UREG (0x30)
+#define	USBS_EPN_STAT	UREG (0x34)
+#define	USBS_DMAN_STAT	UREG (0x38)
+#define	USBS_RXDMA_CFG	UREG (0x40)
+#define	USBS_TXDMA_CFG	UREG (0x44)
+#define	USBS_DATA_DMA	UREG (0x48)
+#define	USBS_TXDMA0	UREG (0x50)
+#define	USBS_TXDMA1	UREG (0x54)
+#define	USBS_TXDMA2	UREG (0x58)
+#define	USBS_RXDMA0	UREG (0x60)
+#define	USBS_RXDMA1	UREG (0x64)
+#define	USBS_RXDMA2	UREG (0x68)
+#define	USBS_EP0	UREG (0x80)
+#define	USBS_EP_RX(ep)	UREG (0x80+((ep)<<2))
+#define	USBS_EP_TX(ep)	UREG (0xc0+((ep)<<2))
+
+#define	_SETUP_SEL	0x40
+#define	_EP_SEL	0x20
+#define	_EP_SEL_IN	0x10
+#define	_EP_SEL_OUT	0x00
+
+static u16	old_sel= 0;
+static void inline select (u16 sel)
+{
+	if (old_sel)
+		USBS_EP_NUM= old_sel & ~(_SETUP_SEL | _EP_SEL);
+	USBS_EP_NUM= old_sel= sel;
+}
+static void inline unselect (void)
+{
+	if (old_sel)
+		USBS_EP_NUM= old_sel & ~(_SETUP_SEL | _EP_SEL);
+	old_sel= 0;
+}
+
+#define	SELECT(info)	select (_EP_SEL | (info)->select)
+#define	SELECT_RX(ep)	select (_EP_SEL | _EP_SEL_OUT | (ep))
+#define	SELECT_TX(ep)	select (_EP_SEL | _EP_SEL_IN | (ep))
+#define	SELECT_SETUP()	select (_SETUP_SEL)
+#define	UNSELECT(info)	unselect ()
+#define	UNSELECT_RX(ep)	unselect ()
+#define	UNSELECT_TX(ep)	unselect ()
+#define	UNSELECT_SETUP()	unselect ()
+
+
+// CTRL:
+#define	_CLR_HALT	0x80
+#define	_SET_HALT	0x40
+#define	_SET_FIFO_EN	0x04
+#define	_CLR_EP	0x02
+#define	_RESET_EP	0x01
+#define	STALL_EPn_RX(ep)	do { SELECT_RX (ep); USBS_CTRL= _SET_HALT; UNSELECT_RX (ep); } while (0)
+#define	STALL_EPn_TX(ep)	do { SELECT_TX (ep); USBS_CTRL= _SET_HALT; UNSELECT_TX (ep); } while (0)
+
+// STAT_FLG:
+#define	_STALL	0x20
+#define	_NAK	0x10
+#define	_ACK	0x08
+#define	_FIFO_EN	0x04
+#define	_NI_FIFO_EMPTY	0x02
+#define	_NI_FIFO_FULL	0x01
+
+// SYSCON1:
+#define	_CFG_LOCK	0x0100
+#define	_NAK_EN	0x0010
+#define	_AUTODEC_DIS	0x0008
+#define	_SELF_PWR	0x0004
+#define	_SOFF_DIS	0x0002
+#define	_PULLUP_EN	0x0001
+
+// SYSCON2:
+#define	_STALL_CMD	0x20
+#define	_DEV_CFG	0x08
+#define	_CLR_CFG	0x04
+#define	STALL_EP0()	USBS_SYSCON2= _STALL_CMD
+
+// DEVSTAT:
+#define	_DS_USB_Reset	0x20
+#define	_DS_SUS	0x10
+#define	_DS_CFG	0x08
+#define	_DS_ADD	0x04
+#define	_DS_DEF	0x02
+#define	_DS_ATT	0x01
+
+// IRQ_EN:
+#define	_SOF_IE	0x80
+#define	_EPn_RX_IE	0x20
+#define	_EPn_TX_IE	0x10
+#define	_DS_CHG_IE	0x08
+#define	_EP0_IE	0x01
+
+// IRQ_SRC:
+#define	_IRQ_TXn_DONE	(1<<10)
+#define	_IRQ_RXn_CNT	(1<<9)
+#define	_IRQ_RXn_EOT	(1<<8)
+#define	_IRQ_SOF	(1<<7)
+#define	_IRQ_EPn_RX	(1<<5)
+#define	_IRQ_EPn_TX	(1<<4)
+#define	_IRQ_DS_CHG	(1<<3)
+#define	_IRQ_SETUP	(1<<2)
+#define	_IRQ_EP0_RX	(1<<1)
+#define	_IRQ_EP0_TX	(1<<0)
+
+////////////////////
+
+static const u8	*tx_buffer= 0;
+static int	tx_size= 0;
+static int	tx_complete= 0;
+
+static void write_fifo (void)
+{
+	while (tx_size > 0  &&  (USBS_STAT_FLG & _NI_FIFO_FULL) == 0)
+	{
+		USBS_DATA8= *tx_buffer++;
+		--tx_size;
+	}
+
+	tx_complete= tx_size == 0  &&  (USBS_STAT_FLG & _NI_FIFO_FULL) == 0;
+	USBS_CTRL= _SET_FIFO_EN;
+}
+
+void usb_send (const void *buffer, int size)
+{
+	tx_buffer= buffer;
+	tx_size= size;
+	tx_complete= 0;
+
+	SELECT_TX (1);
+	write_fifo ();
+	UNSELECT_TX (1);
+}
+
+int usb_sent (void)
+{
+	int	result= 0;
+
+	if (USBS_IRQ_SRC & _IRQ_EPn_TX)
+	{
+		int	epnum= USBS_EPN_STAT & 0x000f;
+		USBS_IRQ_SRC= _IRQ_EPn_TX;
+
+		if (epnum == 1)
+		{
+			SELECT_TX (1);
+
+			if (USBS_STAT_FLG & _ACK)
+			{
+				if (tx_complete)
+					result= 1;
+				else
+					write_fifo ();
+			}
+			UNSELECT_TX (1);
+		}
+	}
+
+	return result;
+}
+
+////////////////////
+
+static u8	*rx_buffer= NULL;
+static u8	*rx_buffer0= NULL;
+static int	rx_complete= 0;
+static int	rx_size= 0;
+
+static void read_fifo (void)
+{
+	rx_complete= (USBS_STAT_FLG & _NI_FIFO_FULL) == 0;
+
+	while ((USBS_STAT_FLG & _NI_FIFO_EMPTY) == 0  &&  rx_size-- > 0)
+		*rx_buffer++= USBS_DATA8;
+}
+
+void usb_recv (void *buffer, int size)
+{
+	rx_buffer0= rx_buffer= buffer;
+	rx_size= size;
+
+//static int in_rx= 0;
+//if (!in_rx) { in_rx= 1;
+	SELECT_RX (2);
+	USBS_CTRL= _SET_FIFO_EN;
+	UNSELECT_RX (2);
+//}
+}
+
+int usb_rcvd (void)
+{
+	int	result= 0;
+
+	if (USBS_IRQ_SRC & _IRQ_EPn_RX)
+	{
+		int	epnum= (USBS_EPN_STAT & 0x0f00) >> 8;
+		USBS_IRQ_SRC= _IRQ_EPn_RX;
+
+		if (epnum == 2)
+		{
+			SELECT_RX (2);
+
+			if (USBS_STAT_FLG & _ACK)
+			{
+				read_fifo ();
+				if (rx_complete  ||  rx_size == 0)
+					result= rx_buffer - rx_buffer0;
+				else
+					USBS_CTRL= _SET_FIFO_EN;
+			}
+			UNSELECT_RX (2);
+		}
+	}
+
+	return result;
+}
Index: /tt-loader/2nd/usb.h
===================================================================
--- /tt-loader/2nd/usb.h	(revision 11)
+++ /tt-loader/2nd/usb.h	(revision 11)
@@ -0,0 +1,35 @@
+/*
+ * 2nd - OMAP "second stage" Flash Loader
+ *
+ * Copyright (C) 2005 Luis Recuerda <lrec@helios.homeip.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.
+ *
+ * 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.
+ *
+ * The author may be reached as lrec@helios.homeip.net
+ *
+ */
+
+#ifndef _USB_H_
+#define _USB_H_
+
+void usb_send (const void *buffer, int size);
+int usb_sent (void);
+
+void usb_recv (void *buffer, int size);
+int usb_rcvd (void);
+
+void usb_debug (void);
+
+#endif
Index: /tt-loader/COPYING
===================================================================
--- /tt-loader/COPYING	(revision 11)
+++ /tt-loader/COPYING	(revision 11)
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
Index: /tt-loader/Makefile
===================================================================
--- /tt-loader/Makefile	(revision 11)
+++ /tt-loader/Makefile	(revision 11)
@@ -0,0 +1,38 @@
+CC = gcc
+INCLUDES =
+CFLAGS = -Wall -O2 -g $(INCLUDES)
+LIBS = -lusb
+LDFLAGS = -g $(LIBS)
+APP_NAME = tt-loader
+APP_VERSION = 0.1
+
+# Adapt this to your system
+CROSS ?= armv5tel-redhat-linux-gnueabi
+DIS_ADDR ?= 0
+
+OBJS = main.o
+
+all: $(APP_NAME)
+
+$(APP_NAME): $(OBJS)
+	$(CC) $(LDFLAGS) -o $@ $^
+
+clean:
+	rm -rf $(APP_NAME) *.o *~
+	$(MAKE) -C 2nd clean
+
+2nd:
+	$(MAKE) -C 2nd all
+
+pkg: 2nd
+	rm -f $(APP_NAME)-$(APP_VERSION).tar.gz
+	tar czf $(APP_NAME)-$(APP_VERSION).tar.gz Makefile *.c COPYING README commands.txt \
+		tt-loader.sh 2nd/arm.ld 2nd/*.h 2nd/*.c 2nd/Makefile 2nd/start.S 2nd/2nd.bin
+
+%.dis: %.bin
+	rm -f $@
+	$(CROSS)-objcopy -I binary -O elf32-littlearm -B arm $< $(@F).elf
+	$(CROSS)-objdump -D --adjust-vma=$(DIS_ADDR) $(@F).elf > $@
+	rm -f $(@F).elf
+
+.PHONY: all clean 2nd
Index: /tt-loader/README
===================================================================
--- /tt-loader/README	(revision 11)
+++ /tt-loader/README	(revision 11)
@@ -0,0 +1,81 @@
+TT-Loader
+
+This program is for advanced users. You should consider it as beta software
+and we can't guarantee it will do what it is expected to do. So if you
+use it, you admit you're using it at your own risk.
+
+This is a program loader derivated from OMAP Flash Loader, a replacement
+by Luis Recuerda for the FlashRecoveryUtility program from Tim Rikkers
+(http://tree.celinuxforum.org/CelfPubWiki/FlashRecoveryUtility).
+
+This program can load alternative boot loader on OMAP730 plateform when
+starting the device with an USB cable plugged. It is designed to be used
+with the "TwinTact" (also known as E2831 device), aka TT, a mobile phone
+by neuf, a french telecom company.
+Also, this program is for Linux (and perhaps other Unixes), not for M$-windows.
+And, the better of all, it is GPL, with all its sources, not a binary program.
+
+omapfl program has been developed using reverse engineering on the protocol
+communication between the original program and the internal boot. Luis have not
+totally understood that protocol, but it works. ;)
+
+To compile this program you only need a gcc compiler and the libusb
+(http://sourceforge.net/projects/libusb/) instaled at your system.
+
+To use it, executes the program passing it two arguments. First argument is
+the second stage loader (the included/compiled 2nd.bin file) and second one
+is a text file with a serie of command (example in commands.txt). Then, plug the
+USB cable in the phone, no need to power with the power button. If it doesn't work,
+you will have to unplug the USB cable and remove the phone battery.
+
+You can also have an automatic detection and launch using udev. Get udev twintact.rules from
+tt-tools at http://source.pkg.fr/doc/Projets/tt-tools and the twintact-udev script. In
+that last script, you have to check line 49 to do what you need.
+
+The file "2nd.bin" is the second stage boot loader. The main program (tt-loader)
+send it to the OMAP processor, where it is executed by the internal boot
+loader. Then this last will expect some command to prepare a third stage boot loader.
+
+To process, you will also need some third stage boot loader for upload. The first way
+to get one is to dump it from your own phone from the native linux environment. I
+assume you know how to connect with at least telnet... maybe dropbear from tt-tools...
+If you want to try examples from commands.txt, you will need a x-load.bin & a u-boot.bin
+in the current folder. Here is a short checlist to get that files:
+ * For x-load.bin:
+   * cat /dev/mtdblock/0 >/mnt/fat/x-load.bin
+   * get x-load.bin on your PC
+   * optionnaly, strip any null byte at the end of the file to reduce upload delay
+   * be sure the file path on the PC is the one expected in commands.txt
+ * For u-boot.bin:
+   * cat /dev/mtdblock/1 >/mnt/fat/u-boot.bin
+   
+It should be possible to load and start a linux kernel directly, but the upload could
+take a very long time.
+
+You should find quickly new commands.txt to do fun things with your TT on OpenTwin,
+so check http://www.opentwin.org or ask on the mailing list.
+
+I have added the compiled file "2nd.bin", if you need to recompile the
+second boot loader, you will need a cross compiler, if the name is diferent
+of mine (armv5tel-redhat-linux-gnueabi from F8 packages), change file "2nd/Makefile".
+If your local gcc compiler is not called "gcc", change "Makefile", also if your include
+files for libusb isn't located at /usr/include (add -L/.... to INCLUDES= line at Makefile).
+
+If you need more help about this program, you can contact me on IRC or by OpenTwin ML,
+check http://www.opentwin.org. Also check http://source.pkg.fr and http://www.pkg.fr
+you should find there my mail and more.
+
+Best regards and enjoy it,
+
+Guillaume Bougard
+
+
+Acknowledges:
+
+Thanks Luis Recuerda to have released omapfl under GPL.
+
+To Tim Rikers for the original FlashRecoveryUtility program.
+
+To Texas Instruments: thank you for DO NOT answer any question about the
+internal ROM boot loader, and, thank you for the WORST documentacion about
+a CPU or microprocessor I have ever seen.
Index: /tt-loader/commands.txt
===================================================================
--- /tt-loader/commands.txt	(revision 11)
+++ /tt-loader/commands.txt	(revision 11)
@@ -0,0 +1,64 @@
+//////// X-LOAD
+// Load x-load in the phone
+a 0x20010000
+// Check README to generate x-load.bin
+f x-load.bin
+
+// Boot with x-load
+a 0x20010c00
+b
+
+end
+/////////////////////////////////////////////////////////////////// X-LOAD END
+
+/////////////////////////////////////////////////////////////////// U-BOOT
+// Send an address
+a 0x20010000
+// Load a file in phone memory at the previous given address
+f x-load.bin
+
+// Call a sub from x-load.bin: TT BoardInit (should only work with TT)
+a 0x20010da4
+c
+
+// Load another program to a new address, check README to generate u-boot.bin
+a 0x10280000
+f u-boot.bin
+
+// Send an address and dump the content to check upload has been done
+a 0x10299a50
+M;M;M;M;M;M;M;M
+
+// Send u-boot start address and boot there
+a 0x10280000
+b
+
+end
+/////////////////////////////////////////////////////////////////// U-BOOT END
+
+/////////////////////////////////////////////////////////////////// DUMP MEM
+// Send an address
+a 0x20000000
+
+// Dump 8kB from that address
+M;M;M;M;M;M;M;M;M;M;M;M;M;M;M;M // 512 octets
+M;M;M;M;M;M;M;M;M;M;M;M;M;M;M;M // 1ko
+M;M;M;M;M;M;M;M;M;M;M;M;M;M;M;M // 
+M;M;M;M;M;M;M;M;M;M;M;M;M;M;M;M // 2ko
+M;M;M;M;M;M;M;M;M;M;M;M;M;M;M;M // 
+M;M;M;M;M;M;M;M;M;M;M;M;M;M;M;M // 3ko
+M;M;M;M;M;M;M;M;M;M;M;M;M;M;M;M // 
+M;M;M;M;M;M;M;M;M;M;M;M;M;M;M;M // 4ko
+M;M;M;M;M;M;M;M;M;M;M;M;M;M;M;M // 
+M;M;M;M;M;M;M;M;M;M;M;M;M;M;M;M // 5ko
+M;M;M;M;M;M;M;M;M;M;M;M;M;M;M;M // 
+M;M;M;M;M;M;M;M;M;M;M;M;M;M;M;M // 6ko
+M;M;M;M;M;M;M;M;M;M;M;M;M;M;M;M // 
+M;M;M;M;M;M;M;M;M;M;M;M;M;M;M;M // 7ko
+M;M;M;M;M;M;M;M;M;M;M;M;M;M;M;M // 
+M;M;M;M;M;M;M;M;M;M;M;M;M;M;M;M // 8ko
+
+end
+/////////////////////////////////////////////////////////////////// DUMP MEM END
+
+
Index: /tt-loader/main.c
===================================================================
--- /tt-loader/main.c	(revision 11)
+++ /tt-loader/main.c	(revision 11)
@@ -0,0 +1,623 @@
+/*
+ * tt-loader - A system loader through USB derived from OMAP Flash Loader
+ *
+ * Copyright (C) 2008 Guillaume Bougard <gbougard@pkg.fr>
+ * Copyright (C) 2005 Luis Recuerda <lrec@helios.homeip.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.
+ *
+ * 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 <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/times.h>
+#include <fcntl.h>
+#include <usb.h>
+#include <endian.h>
+#include <byteswap.h>
+#include <errno.h>
+
+/*
+ * Here Vendor/Product detected for the target device
+ */
+#define	OMAP_VENDOR		0x0451
+#define	OMAP_PRODUCT	0x3f01
+
+#define	IN_EP	0x81
+#define	OUT_EP	0x02
+
+/*
+ * Length of memory dump done by 2nd.bin
+ */
+#define MEM_READ_SIZE		32
+
+struct mem_file {
+	void *content ;
+	int size ;
+};
+
+#define	MAX_SIZE	65536
+static char	buffer[MAX_SIZE + 128];
+static int	buffsize = 0;
+static struct mem_file cmdfile = { NULL, 0 };
+static double btime ;
+static double ticks ;
+
+#define log1(X)		fprintf(stderr, "%9.3f: "X,((double)times(NULL)-btime)/ticks)
+#define log2(X,Y) 	fprintf(stderr, "%9.3f: "X,((double)times(NULL)-btime)/ticks,Y)
+#define log3(X,Y,Z)	fprintf(stderr, "%9.3f: "X,((double)times(NULL)-btime)/ticks,Y,Z)
+
+#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
+
+static inline unsigned do_div (unsigned v, unsigned d)
+{
+	v+= --d;
+	return v & ~d;
+}
+
+static int stringcopy( char * dest, const char *src, int max )
+{
+	char *tmp = dest, *s = (char *) src;
+	int count = 0 ;
+	
+	while (count++ < max)
+		if (!(*tmp++ = *s++ ))
+			break ;
+	
+	return count;
+}
+
+static int send_cmd (usb_dev_handle *handle, const char req, const char *src)
+{
+	int	res, len = 5 ;
+	char buffer[64];
+	
+	buffer[0]= 'T';
+	buffer[1]= 'I';
+	buffer[2]= 'S';
+	buffer[3]= req ;
+	buffer[4]= '\0' ;
+	if (src!=NULL)
+		len += stringcopy (&buffer[4], src, 60);
+	buffer[63]= '\0' ; // truncate anyway
+	
+	res= usb_bulk_write (handle, OUT_EP, buffer, len, 1000);
+	if (res < len)
+	{
+		fprintf (stderr, "Error in usb_bulk_write during send_char: %d/4\n", res);
+		return 0;
+	}
+	
+	return 1;
+}
+
+static int send_binsize (usb_dev_handle *handle, int sz)
+{
+	int	res;
+	char	buffer[8];
+	buffer[0]= 'T';
+	buffer[1]= 'I';
+	buffer[2]= 'S';
+	buffer[3]= 's';
+	*(u_int32_t *) &buffer[4]= cpu_to_le32 ((sz>4096)?4096:sz);
+	
+	res= usb_bulk_write (handle, OUT_EP, buffer, 8, 1000);
+	if (res < 8)
+	{
+		fprintf (stderr, "Error in usb_bulk_write during send_binsize: %d/8\n", res);
+		return 0;
+	}
+	
+	return 1;
+}
+
+static int send_address (usb_dev_handle *handle, int addr)
+{
+	int	res;
+	char	buffer[8];
+	buffer[0]= 'T';
+	buffer[1]= 'I';
+	buffer[2]= 'S';
+	buffer[3]= 'a';
+	*(u_int32_t *) &buffer[4]= cpu_to_le32 (addr);
+	
+	res= usb_bulk_write (handle, OUT_EP, buffer, 8, 1000);
+	if (res < 8)
+	{
+		fprintf (stderr, "Error in usb_bulk_write: %d/8\n", res);
+		return 0;
+	}
+	
+	return 1;
+}
+
+static struct mem_file readfile( const char *filename )
+{
+	struct mem_file toread = { NULL, 0 };
+	int fd= open (filename, O_RDONLY);
+	
+	if (fd < 0)
+	{
+		fprintf (stderr, "Error opening %s file\n", filename);
+		return toread;
+	}
+	
+	toread.size = lseek (fd, 0, SEEK_END);
+	if (toread.size < 0  ||  lseek (fd, 0, SEEK_SET) < 0)
+	{
+		fprintf (stderr, "Error with lseek other %s file\n", filename);
+		close (fd);
+		return toread;
+	}
+	
+	toread.content= malloc (do_div (toread.size, 4));
+	if (toread.content == NULL)
+	{
+		fprintf (stderr, "Out of memory requesting %d bytes\n", toread.size);
+		close (fd);
+		return toread;
+	}
+	
+	if ((toread.size= read (fd, toread.content, toread.size)) < 0)
+	{
+		fprintf (stderr, "Error reading %s file\n", filename);
+		close (fd);
+		return toread;
+	}
+	
+	close (fd);
+	
+	return toread ;
+}
+
+static int process (usb_dev_handle *handle)
+{
+	int	err = -1 ;
+	
+	log1("OMAP found, trying to configure it\n");
+	
+	for (;;)
+	{
+		err= usb_set_configuration (handle, 1);
+		if (err == 0)
+			break;
+		
+		if (err == -ENODEV)
+		{
+			log1("OMAP error, retrying\n");
+			return 1;
+		}
+		
+		sleep (1);
+	}
+	
+	err = usb_claim_interface (handle, 0);
+	if ( err < 0)
+		log2("Error in usb_claim_interface (%d)\n",err);
+	else
+	{
+		char	inbuff[256];
+		int	insize= usb_bulk_read (handle, IN_EP,
+			inbuff, sizeof (inbuff), 5000);
+		
+		if (insize < 48)
+			log2("Error in usb_bulk_read: %d\n", insize);
+		else
+		{
+			log1("OMAP 1st boot contacted, sending 2nd boot\n");
+			
+			memcpy (&buffer[20], inbuff, 44);
+			memcpy (&buffer[80], inbuff, 48);
+			
+			char *p	= buffer;
+			int	size= buffsize;
+			while (size > 0)
+			{
+				int	outsize= usb_bulk_write (handle, OUT_EP, p, 64, 5000);
+				if (outsize < 64)
+				{
+					log2("Error in usb_bulk_write: %d/64\n", outsize);
+					break;
+				}
+
+				p+= 64;
+				size-= 64;
+			}
+			
+			if (size <= 0)
+			{
+				log2("Sent %d bytes to OMAP\n",buffsize);
+				usb_bulk_write (handle, OUT_EP, buffer, 0, 1000);
+				
+				p= NULL;
+				size= 0;
+				
+				int	res=1, sz= 0, loop= 1, cmd=0 ;
+				int vendor, device, info ;
+				char *cmdp = cmdfile.content ;
+				struct mem_file current = { NULL, 0 };
+				
+				err = 1 ; // Set error by default
+				
+				while (loop != 0)
+				{
+					if (loop<0) loop++ ; // Avoid infinite loop
+					
+					if (res>0)
+						res= usb_bulk_read (handle, IN_EP,
+							inbuff, sizeof (inbuff), 5000);
+					
+					if (res < 0)
+					{
+						log2("Error in usb_bulk_read: %d\n",res);
+						break;
+					}
+					
+					if (res >= 4)
+					{
+						if (inbuff[0] == 'T'  &&  inbuff[1] == 'I'  &&
+							inbuff[2] == 'S')
+						{
+							switch (inbuff[3])
+							{
+							case 'f':
+								// Target claims a file
+								log3("OMAP File asked: %s (%d bytes)\n", &inbuff[4], size);
+								if (!send_binsize (handle, size))
+									loop = 0 ; // Just quit on error
+								break;
+								
+							case 'o':
+								// Update upload file buffer offset
+								sz= le32_to_cpu (*(u_int32_t *) &inbuff[4]);
+								p+= sz;
+								size-= sz;
+								//log3("OMAP seek %d to 0x%08lX\n", sz, (long)p-(long)current.content); 					// DEBUG
+								if (size > 0  &&  !send_binsize (handle, size))
+									loop = 0 ; // Just quit on error
+								if (size==0)
+									res = 0 ;
+								break;
+								
+							case 'n':
+								// Upload a requested size chunk from the file buffer
+								sz= le32_to_cpu (*(u_int32_t *) &inbuff[4]);
+								//log2("OMAP read %d\n", sz); 					// DEBUG
+								res= usb_bulk_write (handle, OUT_EP, p, sz, 5000);
+								if (res < sz)
+								{
+									log3("Error in usb_bulk_write: %d/%d\n", res, sz);
+									loop = 0 ; // Just quit on error
+								}
+								break;
+								
+							case 'I':
+								info = le32_to_cpu (*(u_int32_t *) &inbuff[4]);
+								log2("OMAP integer info: %d\n", info);
+								break;
+								
+							case 'A':
+								info = le32_to_cpu (*(u_int32_t *) &inbuff[4]);
+								log2("OMAP address info: 0x%08X\n", info);
+								break;
+								
+							case 'i':
+								info = le32_to_cpu (*(u_int32_t *) &inbuff[4]);
+								log2("OMAP Info returned: 0x%08X\n", info);
+								res = 0 ; // Target is waiting a new command
+								break;
+								
+							case 'v':
+								vendor= le32_to_cpu (*(u_int32_t *) &inbuff[4]);
+								log2("Flash Vendor found: 0x%02X\n", vendor);
+								break;
+								
+							case 'd':
+								device= le32_to_cpu (*(u_int32_t *) &inbuff[4]);
+								log2("Flash Device found: 0x%02X\n", device);
+								break;
+								
+							case 'm':
+								log2("OMAP Message: %s\n", &inbuff[4]);
+								break;
+								
+							case 'M':
+								loop=3 ;
+								log2("0x%08X | ",info);
+								while (++loop<36)
+									fprintf (stderr,"%02hhX", inbuff[loop]);
+								loop=3 ;
+								fprintf (stderr, " |");
+								while (++loop<36)
+									if ((int)inbuff[loop]>=0x20 && (int)inbuff[loop]<0x7f)
+										fprintf (stderr,"%c", inbuff[loop]);
+									else
+										fprintf (stderr,".");
+								fprintf (stderr,"|\n");
+								res = 0 ; // Target is waiting a new command
+								info += 32 ;
+								break;
+								
+							case 'r':
+								log2("OMAP is ready: %s\n", &inbuff[4]);
+								res = 0 ; // Target is waiting a new command
+								break;
+
+							case 'b':
+								// Boot command has been received
+								info = le32_to_cpu (*(u_int32_t *) &inbuff[4]);
+								log2("OMAP is booting at address: 0x%08X\n", info);
+								res = 0 ; // Target is waiting a new command
+								break;
+
+							default:
+								log2("Unknown packet type '%c'\n", inbuff[3]);
+								break;
+							}
+						} else {
+							// Fix the string just in case
+							inbuff[res] = '\0' ;
+							log2("Got: %s\n", inbuff);
+						}
+					}
+					else
+					{
+						// Manage commands
+						if (cmd + 1 >= cmdfile.size)
+						{
+							if (loop>0) {
+								log1("Command file read finished\n");
+								loop = 0 ;
+							}
+							
+						} else {
+							// res < 4
+							//log2("Next command is '%c'\n", cmdp[cmd]); 			// DEBUG
+							switch (cmdp[cmd])
+							{
+							case 'f': // Put a file to be uploaded in a memory buffer
+								cmd += 2 ;
+								if (cmd >= cmdfile.size || cmdp[cmd] == '\0')
+								{
+									log1("Bad 'f' format in command file\n");
+									break ;
+								}
+								// Free previously used memory buffer
+								if (current.content != NULL)
+									free((void *)current.content);
+								current = readfile((const char *)&cmdp[cmd]);
+								if (current.content == NULL)
+								{
+									log2("Can't read file '%s'\n",&cmdp[cmd]);
+									loop = 0 ; // Just quit on error
+								}
+								p = current.content ;
+								size = current.size ;
+								// Say to OMAP target it can reclaim the file
+								if (send_cmd (handle,'f',(const char *)&cmdp[cmd]))
+									log1("File loaded and ready for upload\n");
+								else
+								{
+									log1("Can't say we are ready for upload\n");
+									// Just quit on error
+									loop = 0 ;
+								}
+								break;
+							case 'a': // Get an address and send it to target
+								cmd += 2 ;
+								if (sscanf((const char *)&cmdp[cmd], "%i", &info) != 1)
+								{
+									log2("Can't read address '%s'\n",&cmdp[cmd]);
+									loop = 0 ; // Just quit on error
+								}
+								if (send_address (handle, info))
+									log2("Sending address 0x%02X\n", info);
+								else
+								{
+									log2("Can't send address 0x%02X\n", info);
+									loop = 0 ; // Just quit on error
+								}
+								break;
+							case 'M': // Ask memory dump
+								if (!(send_cmd (handle,'M',NULL)))
+								{
+									log1("Can't ask to read memory\n");
+									loop = 0 ; // Just quit on error
+								}
+								break;
+							case 'c': // Make a call to the last given address
+								if (send_cmd (handle,'c',NULL))
+									log1("Asking function call\n");
+								else
+								{
+									log1("Can't ask to call a function\n");
+									loop = 0 ; // Just quit on error
+								}
+								break;
+							case 'b': // Boot the target by just branching to the last given address
+								if (send_cmd (handle,'b',NULL))
+									log1("Asking boot\n");
+								else
+								{
+									log1("Can't ask to boot\n");
+									loop = 0 ; // Just quit on error
+								}
+								break;
+							case 'e': // End of commands
+								log1("Commands read and sent\n");
+								// Quit now witout error set
+								loop = err = 0 ;
+								cmd = cmdfile.size ;
+								res = 1 ;
+								break ;
+							case '#':
+							case '/':
+								// skip comments
+								res -- ;
+								break ;
+								
+							default:
+								log2("Unknown command type '%c'\n",cmdp[cmd]);
+								break;
+							}
+							// kind of readline
+							while (cmdp[++cmd] != '\0' && cmd < cmdfile.size);
+							// point to next line
+							while (cmdp[++cmd] == '\0' && cmd < cmdfile.size);
+							res ++ ;
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	if (err>=0) {
+		err = usb_release_interface (handle, 0);
+		if (err < 0)
+			log2("Error in usb_release_interface (%d)\n",err);
+	}
+	
+	return err ;
+}
+
+enum {
+	ARG_PROGNAME,
+	ARG_2NDFILE,
+	ARG_CMDFILE,
+	NUM_ARGS
+};
+
+int main (int argc, char *argv[])
+{
+	int	size;
+	btime = (double) times(NULL);
+	ticks = (double) sysconf(_SC_CLK_TCK) / 1000 ;
+	
+	if (argc < NUM_ARGS)
+	{
+		log2("Usage: %s <2nd_boot_file> <command_file>\n", argv[ARG_PROGNAME]);
+		return 1;
+	}
+	
+	memset (buffer, 0, 128);
+	
+	u_int32_t	*p= (u_int32_t *) buffer;
+	p[0x00]= cpu_to_le32 (0xf0030002);
+	
+	int	fd= open (argv[ARG_2NDFILE], O_RDONLY);
+	if (fd < 0)
+	{
+		log1("open 2nd boot file\n");
+		return 1;
+	}
+	else
+	{
+		size= read (fd, &buffer[128], MAX_SIZE);
+		if (size < 0)
+		{
+			log1("read 2nd boot file\n");
+			close (fd);
+			return 1;
+		}
+		
+		close (fd);
+		if (size < 1024)
+		{
+			log2("2ndfile is too small! (%d bytes)\n", size);
+			return 1;
+		}
+	}
+	
+	size= do_div (size, 4);
+	
+	p[0x21]= cpu_to_le32 (size - 0x40);
+	
+	p[0x01]= cpu_to_le32 (size);
+	p[0x02]= cpu_to_le32 (size);
+	p[0x03]= cpu_to_le32 (size);
+	p[0x10]= cpu_to_le32 (size);
+	p[0x11]= cpu_to_le32 (size);
+	p[0x12]= cpu_to_le32 (size);
+	
+	buffsize= 128 + do_div (size, 4);
+	
+	cmdfile = readfile(argv[ARG_CMDFILE]);
+	if (cmdfile.content == NULL)
+	{
+		log1("open cmdfile\n");
+		return 1;
+	} else {
+		int i = 0 ;
+		char *cmdbuffer = (char *)cmdfile.content ;
+		do {
+			if (cmdbuffer[i] == '\n' || cmdbuffer[i] == '\r' || cmdbuffer[i] == ';')
+				cmdbuffer[i] = '\0' ;
+		} while ( i++ < cmdfile.size );
+	}
+	
+	usb_init ();
+	usb_find_busses ();
+	
+	log1("Try to found OMAP730-USB connection\n");
+	
+	int	n= usb_find_devices ();
+	if (n)
+	{
+		log1("Searching OMAP730-USB connection...\n");
+		struct usb_bus	*bus;
+		for (bus= usb_get_busses (); bus; bus= bus->next)
+		{
+			struct usb_device	*dev;
+			
+			for (dev= bus->devices; dev; dev= dev->next)
+			{
+				usb_dev_handle	*handle;
+				if (dev->descriptor.idVendor == OMAP_VENDOR  &&
+					dev->descriptor.idProduct == OMAP_PRODUCT  &&
+					(handle= usb_open (dev)) != NULL)
+				{
+					log1("Found OMAP730-USB connection\n");
+					int res= process (handle);
+					usb_close (handle);
+					if (res == 0) {
+						log1("OMAP730-USB connection processed\n");
+						return 0 ;
+					} else
+						log1("OMAP730-USB processing failed\n");
+				}
+			}
+		}
+		
+	} else {
+		log1("No USB bus found\n");
+	}
+	
+	// Free memory
+	if (cmdfile.content!=NULL)
+		free((void *)cmdfile.content);
+	
+	log1("No target connection found\n");
+	return 1 ;
+}
Index: /tt-loader/tt-loader.sh
===================================================================
--- /tt-loader/tt-loader.sh	(revision 11)
+++ /tt-loader/tt-loader.sh	(revision 11)
@@ -0,0 +1,5 @@
+#! /bin/sh
+
+cd /usr/local/libexec/tt-loader
+
+exec ./tt-loader 2nd/2nd.bin commands.txt
