[U-Boot] [PATCH] Add WinCE image load/boot cmd
Ryan CHEN
ryan.chen at st.com
Fri Aug 22 16:43:47 CEST 2008
The patch is to add support functions which load and boot WinCE image.
It introduces one new CMD macro named 'CONFIG_CMD_WINCE'.
The source codes have tested on STLS board.
Signed-off-by: Ryan Chen <ryan.chen at st.com>
---
common/Makefile | 1 +
common/cmd_bootm.c | 32 ++++++++
common/cmd_wince.c | 193 ++++++++++++++++++++++++++++++++++++++++++++++
include/config_cmd_all.h | 1 +
include/image.h | 1 +
5 files changed, 228 insertions(+), 0 deletions(-)
create mode 100644 common/cmd_wince.c
diff --git a/common/Makefile b/common/Makefile
index 4287108..e427828 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -144,6 +144,7 @@ COBJS-y += cmd_mac.o
COBJS-$(CONFIG_CMD_MFSL) += cmd_mfsl.o
COBJS-$(CONFIG_MP) += cmd_mp.o
COBJS-$(CONFIG_CMD_SF) += cmd_sf.o
+COBJS-$(CONFIG_CMD_WINCE) += cmd_wince.o
COBJS := $(COBJS-y)
SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 1c0a416..e6397d7 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -106,6 +106,10 @@ int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
#if defined(CONFIG_ARTOS) && defined(CONFIG_PPC)
static boot_os_fn do_bootm_artos;
#endif
+#if defined(CONFIG_CMD_WINCE)
+static boot_os_fn do_bootm_wince;
+int do_bootwince (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+#endif
ulong load_addr = CFG_LOAD_ADDR; /* Default Load Address */
static bootm_headers_t images; /* pointers to os/initrd/fdt images */
@@ -358,6 +362,12 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
do_bootm_artos (cmdtp, flag, argc, argv, &images);
break;
#endif
+
+#ifdef CONFIG_CMD_WINCE
+ case IH_OS_WINCE:
+ do_bootm_wince (cmdtp, flag, argc, argv, &images);
+ break;
+#endif
}
show_boot_progress (-9);
@@ -1142,3 +1152,25 @@ static void do_bootm_artos (cmd_tbl_t *cmdtp, int flag,
(*entry) (kbd, cmdline, fwenv, top);
}
#endif
+
+#if defined(CONFIG_CMD_WINCE)
+static void do_bootm_wince (cmd_tbl_t *cmdtp, int flag,
+ int argc, char *argv[],
+ bootm_headers_t *images)
+{
+ char str[80];
+ image_header_t *hdr = &images->legacy_hdr_os_copy;
+
+#if defined(CONFIG_FIT)
+ if (!images->legacy_hdr_valid) {
+ fit_unsupported_reset ("WinCE");
+ do_reset (cmdtp, flag, argc, argv);
+ }
+#endif
+
+ sprintf(str, "%x", image_get_ep (hdr)); /* write entry-point into string */
+ setenv("loadaddr", str);
+ do_bootwince(cmdtp, 0, 0, NULL);
+}
+#endif/* CONFIG_CMD_WINCE */
+
diff --git a/common/cmd_wince.c b/common/cmd_wince.c
new file mode 100644
index 0000000..fdc2e6b
--- /dev/null
+++ b/common/cmd_wince.c
@@ -0,0 +1,193 @@
+/*
+ * 2008 (c) STMicroelectronics, Inc.
+ * Author: Ryan Chen <Ryan.Chen at st.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Opsycon AB, Sweden.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <linux/ctype.h>
+#include <net.h>
+
+/*
+ * Windows CE Binary Image Data Format
+ * The binary image (.bin) file format organizes data by sections. Each section contains
+ * a section header that specifies the starting address, length, and checksum for that
+ * section.
+ *
+ * Refer to <http://msdn.microsoft.com/en-us/library/ms924510.aspx>
+ *
+ * The following table shows the .bin file format.
+ * Field Length (bytes) Description
+ * Sync bytes (optional) 7 Byte 0 is B, indicating a .bin file format.
+ * Bytes 1-6 are reserved and set to 0, 0, 0, F, F, \n.
+ * Run-time image address 4 Physical starting address of the run-time image.
+ * Run-time image length 4 Physical length, in bytes, of the run-time image.
+ * Record Address 4 Physical starting address of data record.
+ * If this value is zero, the Record Address is the end of
+ * the file, and record length contains the starting address
+ * of the run-time image.
+ * Record length 4 Length of record data, in bytes.
+ * Record checksum 4 Signed 32-bit sum of record data bytes.
+ * Record data Record length Record data.
+ */
+#define WINCE_IMAGE_SYNC_SIZE 7
+#define WINCE_IMAGE_SYNC "B000FF\n"
+
+typedef struct {
+ unsigned char sync_bytes[WINCE_IMAGE_SYNC_SIZE];
+ unsigned int img_addr;
+ unsigned int img_length;
+} type_wince_image_header;
+
+int check_sum(unsigned char * buf, int len, unsigned int checksum)
+{
+ unsigned int count,i;
+
+ for (i = 0,count = 0 ; i < len ; i++)
+ count += buf[i];
+
+ if (count == checksum)
+ return 0;
+
+ return 1;
+}
+
+/* ======================================================================
+ * Determine if a valid WinCE image exists at the given memory location.
+ * First looks at the image header field, the makes sure that it is
+ * WinCE image.
+ * ====================================================================== */
+int valid_wince_image (unsigned long addr)
+{
+ type_wince_image_header *p = (type_wince_image_header *)addr;
+
+ if(strcmp((char *)p->sync_bytes, (char *)WINCE_IMAGE_SYNC) != 0)
+ return 0;
+
+ return 1;
+}
+
+/* ======================================================================
+ * A very simple WinCE image loader, assumes the image is valid, returns the
+ * entry point address.
+ * ====================================================================== */
+unsigned long load_wince_image (unsigned long addr)
+{
+ unsigned char *p = (unsigned char *)addr;
+ u32 start_addr, total_length;
+ u32 record_addr, record_length, record_checksum;
+ u32 i = 0;
+
+ if(valid_wince_image(addr) == 0)
+ return ~0;
+
+ printf("WINCE image is found: ");
+ p += WINCE_IMAGE_SYNC_SIZE;
+ start_addr = (u32)(p[3]<<24) + (u32)(p[2]<<16) + (u32)(p[1]<<8) + (u32)p[0];
+ p += 4;
+ total_length = (u32)(p[3]<<24) + (u32)(p[2]<<16) + (u32)(p[1]<<8) + (u32)p[0];
+ printf(" Start Address = 0x%x @ Total Length = 0x%x\n", start_addr, total_length);
+ p += 4;
+
+ /* read each records */
+ while(1) {
+ record_length = (u32)(p[7]<<24) + (u32)(p[6]<<16) + (u32)(p[5]<<8) + (u32)p[4];
+ record_checksum = (u32)(p[11]<<24) + (u32)(p[10]<<16) + (u32)(p[9]<<8) + (u32)p[8];
+ record_addr = (u32)(p[3]<<24) + (u32)(p[2]<<16) + (u32)(p[1]<<8) + (u32)p[0];
+ if(record_addr == 0)
+ break;
+
+ if(check_sum((unsigned char *)&p[12], record_length, record_checksum) != 0) {
+ printf("Checksum Error!\n");
+ return (unsigned long)~0;
+ }
+ memcpy ((void *)record_addr, (const void *)&p[12], (unsigned long)record_length);
+ printf("Region %d: Loading from 0x%x to 0x%x @ Length 0x%x\n", i, (unsigned int)&p[12], \
+ (unsigned int)record_addr, record_length);
+ p = p + 12 + record_length;
+ i++;
+ }
+
+ /* the lastest checksun should be zero */
+ if(record_checksum != 0) {
+ printf("Checksum Error!\n");
+ return (unsigned long)~0;
+ }
+
+ /* the lastest length is entry address */
+ return (unsigned long)record_length;
+}
+
+/* ======================================================================
+ * Interpreter command to boot WinCE from a memory image. The image can
+ * be an WinCE image. WinCE image do not need the
+ * bootline and other parameters.
+ * ====================================================================== */
+int do_bootwince (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ unsigned long addr; /* Address of image */
+
+ /*
+ * Check the loadaddr variable.
+ * If we don't know where the image is then we're done.
+ */
+ if (argc < 2)
+ addr = load_addr;
+ else
+ addr = simple_strtoul (argv[1], NULL, 16);
+
+#if defined(CONFIG_CMD_NET)
+ /* Check to see if we need to tftp the image ourselves before starting */
+ if ((argc == 2) && (strcmp (argv[1], "tftp") == 0)) {
+ if (NetLoop (TFTP) <= 0)
+ return 1;
+ printf ("Automatic boot of WinCE image at address 0x%08lx ... \n", addr);
+ }
+#endif
+
+ /*
+ * If the data at the load address is an WinCE image, then
+ * treat it like an WinCE image. Otherwise, return 1
+ */
+ if (valid_wince_image (addr)) {
+ addr = load_wince_image (addr);
+ } else {
+ puts ("## Not an WinCE image, exit!\n");
+ return 1;
+ /* leave addr as load_addr */
+ }
+
+ printf ("## Starting Wince at 0x%08lx ...\n", addr);
+
+ ((void (*)(void)) addr) ();
+
+ puts ("## WinCE terminated\n");
+ return 1;
+}
+
diff --git a/include/config_cmd_all.h b/include/config_cmd_all.h
index c2bb094..5f6fab5 100644
--- a/include/config_cmd_all.h
+++ b/include/config_cmd_all.h
@@ -81,5 +81,6 @@
#define CONFIG_CMD_VFD /* VFD support (TRAB) */
#define CONFIG_CMD_XIMG /* Load part of Multi Image */
#define CONFIG_CMD_AT91_SPIMUX /* AT91 MMC/SPI Mux Support */
+#define CONFIG_CMD_WINCE /* WinCE load/boot cmd */
#endif /* _CONFIG_CMD_ALL_H */
diff --git a/include/image.h b/include/image.h
index 46138fa..7253278 100644
--- a/include/image.h
+++ b/include/image.h
@@ -85,6 +85,7 @@
#define IH_OS_RTEMS 18 /* RTEMS */
#define IH_OS_ARTOS 19 /* ARTOS */
#define IH_OS_UNITY 20 /* Unity OS */
+#define IH_OS_WINCE 21 /* WinCE OS */
/*
* CPU Architecture Codes (supported by Linux)
--
1.6.0.rc1
More information about the U-Boot
mailing list