[U-Boot] [Patch 1/1] Spi Flash: Allow auto-booting of images from spi flash load

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@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" );

On Wednesday, July 06, 2011 17:51:58 Andre Renaud wrote:
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).
this looks like largely a copy & paste job from one of the many existing boot funcs. considering the only unique thing here is the spi flash read, seems like it'd make sense to add a new func to common/cmd_bootm.c like bootm_load_image(). it'd take a read callback as well as a pointer to data.
as it stands, this patch breaks configs that enable the spi flash command but disable the bootm command. -mike
participants (2)
-
Andre Renaud
-
Mike Frysinger