[U-Boot] [PATCH 1/3] spl: add ymodem support

Mikhail Kshevetskiy mikhail.kshevetskiy at gmail.com
Tue Mar 6 21:54:05 CET 2012


We have an omap l138 based board without jtag and empty spi flash.
UART is an only way to load something on this board, so we are using
uart to load spl image u-boot and then we are using ymodem to load
the rest part of u-boot.
---
 arch/arm/cpu/arm926ejs/davinci/spl.c |   25 +++++++++++++++
 common/Makefile                      |    4 ++-
 common/xyzModem.c                    |   55 ++++++++++++++++++++++++++++++++++
 include/xyzModem.h                   |    5 +++
 lib/Makefile                         |    1 +
 5 files changed, 89 insertions(+), 1 deletions(-)

Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy at gmail.com>

diff --git a/arch/arm/cpu/arm926ejs/davinci/spl.c b/arch/arm/cpu/arm926ejs/davinci/spl.c
index 74632e5..1fedf7d 100644
--- a/arch/arm/cpu/arm926ejs/davinci/spl.c
+++ b/arch/arm/cpu/arm926ejs/davinci/spl.c
@@ -28,6 +28,7 @@
 #include <ns16550.h>
 #include <malloc.h>
 #include <spi_flash.h>
+#include <xyzModem.h>
 
 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
 
@@ -93,4 +94,28 @@ void board_init_r(gd_t *id, ulong dummy)
 	puts("SPI boot...\n");
 	spi_boot();
 #endif
+#ifdef CONFIG_SPL_YMODEM_LOAD
+	mem_malloc_init(CONFIG_SYS_TEXT_BASE - CONFIG_SYS_MALLOC_LEN,
+			CONFIG_SYS_MALLOC_LEN);
+
+	gd = &gdata;
+	gd->bd = &bdata;
+	gd->flags |= GD_FLG_RELOC;
+	gd->baudrate = CONFIG_BAUDRATE;
+	serial_init();          /* serial communications setup */
+	gd->have_console = 1;
+
+	while(1){
+		char	ch;
+
+		while(!tstc()){
+			puts("Ymodem boot: press Enter to continue...\n");
+			mdelay(1000);
+		}
+		ch = getc();
+		if ((ch == '\r') || (ch == '\n')) break;
+	}
+	puts("Ymodem boot...\n");
+	ymodem_boot();
+#endif
 }
diff --git a/common/Makefile b/common/Makefile
index 2a31c62..417a517 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -188,7 +188,9 @@ COBJS-y += console.o
 COBJS-y += dlmalloc.o
 COBJS-y += memsize.o
 COBJS-y += stdio.o
-
+ifdef CONFIG_SPL_BUILD
+COBJS-$(CONFIG_SPL_YMODEM_LOAD) += xyzModem.o
+endif
 
 COBJS	:= $(sort $(COBJS-y))
 XCOBJS	:= $(sort $(XCOBJS-y))
diff --git a/common/xyzModem.c b/common/xyzModem.c
index a1f955b..8e024d0 100644
--- a/common/xyzModem.c
+++ b/common/xyzModem.c
@@ -847,3 +847,58 @@ GETC_IO_FUNCS (xyzModem_io, xyzModem_stream_open, xyzModem_stream_close,
 RedBoot_load (xmodem, xyzModem_io, false, false, xyzModem_xmodem);
 RedBoot_load (ymodem, xyzModem_io, false, false, xyzModem_ymodem);
 #endif
+
+
+#ifdef CONFIG_SPL_BUILD
+#ifdef CONFIG_SPL_YMODEM_LOAD
+static int getcxmodem(void) {
+	if (tstc())
+		return (getc());
+	return -1;
+}
+
+/*
+ * The main entry for YMODEM booting. It's necessary that SDRAM is already
+ * configured and available since this code loads the main U-Boot image
+ * from serial line into SDRAM and starts it from there.
+ */
+void ymodem_boot(void)
+{
+	int size;
+	int err;
+	int res;
+	connection_info_t info;
+	void (*uboot)(void) __noreturn;
+	ulong store_addr = ~0;
+
+	/*
+	 * Load U-Boot image from serial line into RAM
+	 */
+	size = 0;
+	info.mode = xyzModem_ymodem;
+	res = xyzModem_stream_open (&info, &err);
+	if (!res) {
+		store_addr = CONFIG_SYS_TEXT_BASE;
+		while ((res =
+			xyzModem_stream_read (store_addr, 1024, &err)) > 0) {
+			store_addr += res;
+			size += res;
+		}
+	} else {
+		printf ("%s\n", xyzModem_error (err));
+		hang();
+	}
+
+	xyzModem_stream_close (&err);
+	xyzModem_stream_terminate (false, &getcxmodem);
+
+	printf ("## Total Size      = 0x%08x = %d Bytes\n", size, size);
+
+	/*
+	 * Jump to U-Boot image
+	 */
+	uboot = (void *) CONFIG_SYS_TEXT_BASE;
+	(*uboot)();
+}
+#endif /* CONFIG_SPL_YMODEM_LOAD */
+#endif /* CONFIG_SPL_BUILD */
diff --git a/include/xyzModem.h b/include/xyzModem.h
index f437bbd..275894c 100644
--- a/include/xyzModem.h
+++ b/include/xyzModem.h
@@ -58,6 +58,9 @@
 #ifndef _XYZMODEM_H_
 #define _XYZMODEM_H_
 
+#include <linux/types.h>
+#include <linux/compiler.h>
+
 #define xyzModem_xmodem 1
 #define xyzModem_ymodem 2
 /* Don't define this until the protocol support is in place */
@@ -114,4 +117,6 @@ void  xyzModem_stream_terminate(bool method, int (*getc)(void));
 int   xyzModem_stream_read(char *buf, int size, int *err);
 char *xyzModem_error(int err);
 
+void  ymodem_boot(void) __noreturn;
+
 #endif /* _XYZMODEM_H_ */
diff --git a/lib/Makefile b/lib/Makefile
index e6e6ec6..2983530 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -52,6 +52,7 @@ COBJS-$(CONFIG_SHA256) += sha256.o
 COBJS-y	+= strmhz.o
 COBJS-$(CONFIG_RBTREE)	+= rbtree.o
 else
+COBJS-$(CONFIG_SPL_YMODEM_LOAD) += crc16.o
 COBJS-$(CONFIG_SPL_SPI_FLASH_SUPPORT) += display_options.o
 endif
 
-- 
1.7.9.1



More information about the U-Boot mailing list