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