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 <an...@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"
 );
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to