[U-Boot] [Patch 1/1] Spi Flash: Allow auto-booting of images from spi flash load
Andre Renaud
andre at bluewatersys.com
Wed Jul 6 23:51:58 CEST 2011
This allows intelligent booting of FIT (& the legacy style) images from
SPI flash. Basically it means that you don't have to guess at the image
length, so data reads are more optimal (& hopefully faster).
Signed-off-by: Andre Renaud <andre at bluewatersys.com>
---
Index: common/cmd_sf.c
===================================================================
--- common/cmd_sf.c (revision 31)
+++ common/cmd_sf.c (working copy)
@@ -109,6 +109,96 @@
return 0;
}
+static int do_spi_flash_boot(cmd_tbl_t *cmdtp, int argc, char * const argv[])
+{
+ char *ep;
+ size_t cnt;
+ image_header_t *hdr;
+#if defined(CONFIG_FIT)
+ const void *fit_hdr = NULL;
+#endif
+ unsigned long addr;
+ unsigned long offset;
+ char *endp;
+ int ret;
+
+ if (argc < 3)
+ return -1;
+
+ addr = simple_strtoul(argv[1], &endp, 16);
+ if (*argv[1] == 0 || *endp != 0)
+ return -1;
+ offset = simple_strtoul(argv[2], &endp, 16);
+ if (*argv[2] == 0 || *endp != 0)
+ return -1;
+
+ printf("\nLoading from offset 0x%lx\n", offset);
+
+ ret = spi_flash_read(flash, offset, 1024, (u_char *)addr);
+ if (ret) {
+ printf("SPI flash boot failed\n");
+ return 1;
+ }
+
+ switch (genimg_get_format((void *)addr)) {
+ case IMAGE_FORMAT_LEGACY:
+ hdr = (image_header_t *)addr;
+
+ image_print_contents(hdr);
+
+ cnt = image_get_image_size(hdr);
+ break;
+#if defined(CONFIG_FIT)
+ case IMAGE_FORMAT_FIT:
+ fit_hdr = (const void *)addr;
+ puts("Fit image detected...\n");
+
+ cnt = fit_get_size(fit_hdr);
+ break;
+#endif
+ default:
+ puts("** Unknown image type\n");
+ return 1;
+ }
+
+ ret = spi_flash_read(flash, offset, cnt, (u_char *)addr);
+ if (ret) {
+ printf("SPI flash boot failed\n");
+ return 1;
+ }
+
+#if defined(CONFIG_FIT)
+ /* This cannot be done earlier,
+ * we need complete FIT image in RAM first */
+ if (genimg_get_format((void *)addr) == IMAGE_FORMAT_FIT) {
+ if (!fit_check_format(fit_hdr)) {
+ puts("** Bad FIT image format\n");
+ return 1;
+ }
+ fit_print_contents(fit_hdr);
+ }
+#endif
+
+ /* Loading ok, update default load address */
+
+ load_addr = addr;
+
+ /* Check if we should attempt an auto-start */
+ if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) {
+ char *local_args[2];
+
+ local_args[0] = "bootm";
+ local_args[1] = NULL;
+
+ printf("Automatic boot of image at addr 0x%08lx ...\n", addr);
+
+ do_bootm(cmdtp, 0, 1, local_args);
+ return 1;
+ }
+ return 0;
+}
+
+
static int do_spi_flash_read_write(int argc, char * const argv[])
{
unsigned long addr;
@@ -207,6 +297,8 @@
ret = do_spi_flash_read_write(argc, argv);
else if (strcmp(cmd, "erase") == 0)
ret = do_spi_flash_erase(argc, argv);
+ else if (strcmp(cmd, "boot") == 0)
+ ret = do_spi_flash_boot(cmdtp, argc, argv);
else
ret = -1;
@@ -229,4 +321,7 @@
" at `addr' to flash at `offset'\n"
"sf erase offset [+]len - erase `len' bytes from `offset'\n"
" `+len' round up `len' to block size"
+ "sf boot addr offset - read a boot image starting at\n"
+ " `offset' to memory at `addr' and\n"
+ " execute it\n"
);
More information about the U-Boot
mailing list