X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=common%2Fcmd_ximg.c;h=42a7eba76622dd8409381669c147144c25f07666;hb=ced199dc858d57e807d3ec2a511c4bd9a4bd8765;hp=8359153b2b56d78d19cc8649495294696d0f90cd;hpb=48abe7bfab14c1e9bd4a9a1f9d2e094b6d16773c;p=u-boot diff --git a/common/cmd_ximg.c b/common/cmd_ximg.c index 8359153b2b..42a7eba766 100644 --- a/common/cmd_ximg.c +++ b/common/cmd_ximg.c @@ -24,7 +24,6 @@ * MA 02111-1307 USA */ -#if (CONFIG_COMMANDS & CFG_CMD_XIMG) /* * Multi Image extract @@ -32,100 +31,229 @@ #include #include #include +#include +#if defined(CONFIG_BZIP2) +#include +#endif #include -int -do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +#ifndef CONFIG_SYS_XIMG_LEN +/* use 8MByte as default max gunzip size */ +#define CONFIG_SYS_XIMG_LEN 0x800000 +#endif + +static int +do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { - ulong addr = load_addr, dest = 0; - ulong data, len, checksum; - ulong *len_ptr; - int i, verify, part = 0; - char pbuf[10], *s; - image_header_t header; + ulong addr = load_addr; + ulong dest = 0; + ulong data, len, count; + int verify; + int part = 0; + char pbuf[10]; + image_header_t *hdr; +#if defined(CONFIG_FIT) + const char *uname = NULL; + const void* fit_hdr; + int noffset; + const void *fit_data; + size_t fit_len; +#endif + uint unc_len = CONFIG_SYS_XIMG_LEN; + uint8_t comp; - s = getenv("verify"); - verify = (s && (*s == 'n')) ? 0 : 1; + verify = getenv_yesno("verify"); if (argc > 1) { addr = simple_strtoul(argv[1], NULL, 16); } if (argc > 2) { part = simple_strtoul(argv[2], NULL, 16); +#if defined(CONFIG_FIT) + uname = argv[2]; +#endif } if (argc > 3) { dest = simple_strtoul(argv[3], NULL, 16); } - printf("## Copying from image at %08lx ...\n", addr); - - /* Copy header so we can blank CRC field for re-calculation */ - memmove(&header, (char *) addr, sizeof (image_header_t)); + switch (genimg_get_format((void *)addr)) { + case IMAGE_FORMAT_LEGACY: - if (ntohl(header.ih_magic) != IH_MAGIC) { - printf("Bad Magic Number\n"); - return 1; - } + printf("## Copying part %d from legacy image " + "at %08lx ...\n", part, addr); - data = (ulong) & header; - len = sizeof (image_header_t); - - checksum = ntohl(header.ih_hcrc); - header.ih_hcrc = 0; + hdr = (image_header_t *)addr; + if (!image_check_magic(hdr)) { + printf("Bad Magic Number\n"); + return 1; + } - if (crc32(0, (char *) data, len) != checksum) { - printf("Bad Header Checksum\n"); - return 1; - } + if (!image_check_hcrc(hdr)) { + printf("Bad Header Checksum\n"); + return 1; + } #ifdef DEBUG - print_image_hdr((image_header_t *) addr); + image_print_contents(hdr); #endif - data = addr + sizeof (image_header_t); - len = ntohl(header.ih_size); + if (!image_check_type(hdr, IH_TYPE_MULTI)) { + printf("Wrong Image Type for %s command\n", + cmdtp->name); + return 1; + } - if (header.ih_type != IH_TYPE_MULTI) { - printf("Wrong Image Type for %s command\n", cmdtp->name); - return 1; - } + comp = image_get_comp(hdr); + if ((comp != IH_COMP_NONE) && (argc < 4)) { + printf("Must specify load address for %s command " + "with compressed image\n", + cmdtp->name); + return 1; + } - if (header.ih_comp != IH_COMP_NONE) { - printf("Wrong Compression Type for %s command\n", cmdtp->name); - return 1; - } + if (verify) { + printf(" Verifying Checksum ... "); + if (!image_check_dcrc(hdr)) { + printf("Bad Data CRC\n"); + return 1; + } + printf("OK\n"); + } - if (verify) { - printf(" Verifying Checksum ... "); - if (crc32(0, (char *) data, len) != ntohl(header.ih_dcrc)) { - printf("Bad Data CRC\n"); + count = image_multi_count(hdr); + if (part >= count) { + printf("Bad Image Part\n"); return 1; } - printf("OK\n"); - } - len_ptr = (ulong *) data; - - data += 4; /* terminator */ - for (i = 0; len_ptr[i]; ++i) { - data += 4; - if (argc > 2 && part > i) { - u_long tail; - len = ntohl(len_ptr[i]); - tail = len % 4; - data += len; - if (tail) { - data += 4 - tail; + image_multi_getimg(hdr, part, &data, &len); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + if (uname == NULL) { + puts("No FIT subimage unit name\n"); + return 1; + } + + printf("## Copying '%s' subimage from FIT image " + "at %08lx ...\n", uname, addr); + + fit_hdr = (const void *)addr; + if (!fit_check_format(fit_hdr)) { + puts("Bad FIT image format\n"); + return 1; + } + + /* get subimage node offset */ + noffset = fit_image_get_node(fit_hdr, uname); + if (noffset < 0) { + printf("Can't find '%s' FIT subimage\n", uname); + return 1; + } + + if (fit_image_check_comp(fit_hdr, noffset, IH_COMP_NONE) + && (argc < 4)) { + printf("Must specify load address for %s command " + "with compressed image\n", + cmdtp->name); + return 1; + } + + /* verify integrity */ + if (verify) { + if (!fit_image_check_hashes(fit_hdr, noffset)) { + puts("Bad Data Hash\n"); + return 1; } } - } - if (argc > 2 && part >= i) { - printf("Bad Image Part\n"); + + /* get subimage data address and length */ + if (fit_image_get_data(fit_hdr, noffset, + &fit_data, &fit_len)) { + puts("Could not find script subimage data\n"); + return 1; + } + + if (fit_image_get_comp(fit_hdr, noffset, &comp)) { + puts("Could not find script subimage " + "compression type\n"); + return 1; + } + + data = (ulong)fit_data; + len = (ulong)fit_len; + break; +#endif + default: + puts("Invalid image type for imxtract\n"); return 1; } - len = ntohl(len_ptr[part]); if (argc > 3) { - memcpy((char *) dest, (char *) data, len); + switch (comp) { + case IH_COMP_NONE: +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) + { + size_t l = len; + size_t tail; + void *to = (void *) dest; + void *from = (void *)data; + + printf(" Loading part %d ... ", part); + + while (l > 0) { + tail = (l > CHUNKSZ) ? CHUNKSZ : l; + WATCHDOG_RESET(); + memmove(to, from, tail); + to += tail; + from += tail; + l -= tail; + } + } +#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ + printf(" Loading part %d ... ", part); + memmove((char *) dest, (char *)data, len); +#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ + break; +#ifdef CONFIG_GZIP + case IH_COMP_GZIP: + printf(" Uncompressing part %d ... ", part); + if (gunzip((void *) dest, unc_len, + (uchar *) data, &len) != 0) { + puts("GUNZIP ERROR - image not loaded\n"); + return 1; + } + break; +#endif +#if defined(CONFIG_BZIP2) + case IH_COMP_BZIP2: + { + int i; + + printf(" Uncompressing part %d ... ", part); + /* + * If we've got less than 4 MB of malloc() + * space, use slower decompression algorithm + * which requires at most 2300 KB of memory. + */ + i = BZ2_bzBuffToBuffDecompress( + (char *)ntohl(hdr->ih_load), + &unc_len, (char *)data, len, + CONFIG_SYS_MALLOC_LEN < (4096 * 1024), + 0); + if (i != BZ_OK) { + printf("BUNZIP2 ERROR %d - " + "image not loaded\n", i); + return 1; + } + } + break; +#endif /* CONFIG_BZIP2 */ + default: + printf("Unimplemented compression type %d\n", comp); + return 1; + } + puts("OK\n"); } sprintf(pbuf, "%8lx", data); @@ -136,9 +264,19 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return 0; } -U_BOOT_CMD(imxtract, 4, 1, do_imgextract, - "imxtract- extract a part of a multi-image\n", - "addr part [dest]\n" - " - extract from image at and copy to \n"); +#ifdef CONFIG_SYS_LONGHELP +static char imgextract_help_text[] = + "addr part [dest]\n" + " - extract from legacy image at and copy to " +#if defined(CONFIG_FIT) + "\n" + "addr uname [dest]\n" + " - extract subimage from FIT image at and copy to " +#endif + ""; +#endif -#endif /* CONFIG_COMMANDS & CFG_CMD_XIMG */ +U_BOOT_CMD( + imxtract, 4, 1, do_imgextract, + "extract a part of a multi-image", imgextract_help_text +);