[U-Boot] [PATCH 1/4] dumpimage: add 'T' option to explicitly set the image type

From: Guilherme Maciel Ferreira guilherme.maciel@datacom.ind.br
Some image types, like "KeyStone GP", do not have magic numbers to distinguish them from other image types. Thus, the automatic image type discovery does not work correctly.
This patch also fix some integer type mismatches.
Signed-off-by: Guilherme Maciel Ferreira guilherme.maciel.ferreira@gmail.com --- README | 7 ++-- test/image/test-imagetools.sh | 48 +++++++++++++++------------- tools/dumpimage.c | 70 ++++++++++++++++++++-------------------- tools/gpimage-common.c | 3 +- tools/mkimage.c | 3 -- 5 files changed, 67 insertions(+), 64 deletions(-)
diff --git a/README b/README index 0fec497..398b3cc 100644 --- a/README +++ b/README @@ -5900,9 +5900,10 @@ option performs the converse operation of the mkimage's second form (the "-d" option). Given an image built by mkimage, the dumpimage extracts a "data file" from the image:
- tools/dumpimage -i image -p position data_file - -i ==> extract from the 'image' a specific 'data_file', \ - indexed by 'position' + tools/dumpimage -i image -T type -p position data_file + -i ==> extract from the 'image' a specific 'data_file' + -T ==> set image type to 'type' + -p ==> 'position' (starting at 0) of the 'data_file' inside the 'image'
Installing a Linux Image: diff --git a/test/image/test-imagetools.sh b/test/image/test-imagetools.sh index 9e299e1..8aaaade 100755 --- a/test/image/test-imagetools.sh +++ b/test/image/test-imagetools.sh @@ -13,9 +13,9 @@ # ./test/image/test-imagetools.sh
BASEDIR=sandbox -SRCDIR=sandbox/boot +SRCDIR=${BASEDIR}/boot IMAGE_NAME="v1.0-test" -IMAGE=linux.img +IMAGE_MULTI=linux.img DATAFILE0=vmlinuz DATAFILE1=initrd.img DATAFILE2=System.map @@ -34,14 +34,14 @@ cleanup() for file in ${DATAFILES}; do rm -f ${file} ${SRCDIR}/${file} done - rm -f ${IMAGE} ${DUMPIMAGE_LIST} ${MKIMAGE_LIST} ${TEST_OUT} + rm -f ${IMAGE_MULTI} ${DUMPIMAGE_LIST} ${MKIMAGE_LIST} ${TEST_OUT} rmdir ${SRCDIR} }
# Check that two files are the same assert_equal() { - if ! diff $1 $2; then + if ! diff -u $1 $2; then echo "Failed." cleanup exit 1 @@ -82,35 +82,39 @@ do_cmd_redir() ${cmd} >${redir} }
-# Write files into an image -create_image() +# Write files into an multi-file image +create_multi_image() { local files="${SRCDIR}/${DATAFILE0}:${SRCDIR}/${DATAFILE1}" files+=":${SRCDIR}/${DATAFILE2}"
- echo -e "\nBuilding image..." + echo -e "\nBuilding multi-file image..." do_cmd ${MKIMAGE} -A x86 -O linux -T multi -n "${IMAGE_NAME}" \ - -d ${files} ${IMAGE} + -d ${files} ${IMAGE_MULTI} echo "done." }
-# Extract files from an image -extract_image() +# Extract files from an multi-file image +extract_multi_image() { - echo -e "\nExtracting image contents..." - do_cmd ${DUMPIMAGE} -i ${IMAGE} -p 0 ${DATAFILE0} - do_cmd ${DUMPIMAGE} -i ${IMAGE} -p 1 ${DATAFILE1} - do_cmd ${DUMPIMAGE} -i ${IMAGE} -p 2 ${DATAFILE2} - do_cmd ${DUMPIMAGE} -i ${IMAGE} -p 2 ${DATAFILE2} -o ${TEST_OUT} + echo -e "\nExtracting multi-file image contents..." + do_cmd ${DUMPIMAGE} -T multi -i ${IMAGE_MULTI} -p 0 ${DATAFILE0} + do_cmd ${DUMPIMAGE} -T multi -i ${IMAGE_MULTI} -p 1 ${DATAFILE1} + do_cmd ${DUMPIMAGE} -T multi -i ${IMAGE_MULTI} -p 2 ${DATAFILE2} + do_cmd ${DUMPIMAGE} -T multi -i ${IMAGE_MULTI} -p 2 ${DATAFILE2} -o ${TEST_OUT} echo "done." }
# List the contents of a file +# Args: +# image filename list_image() { + local image="$1" + echo -e "\nListing image contents..." - do_cmd_redir ${MKIMAGE_LIST} ${MKIMAGE} -l ${IMAGE} - do_cmd_redir ${DUMPIMAGE_LIST} ${DUMPIMAGE} -l ${IMAGE} + do_cmd_redir ${MKIMAGE_LIST} ${MKIMAGE} -l ${image} + do_cmd_redir ${DUMPIMAGE_LIST} ${DUMPIMAGE} -l ${image} echo "done." }
@@ -120,16 +124,16 @@ main()
create_files
- # Compress and extract multifile images, compare the result - create_image - extract_image + # Compress and extract multi-file images, compare the result + create_multi_image + extract_multi_image for file in ${DATAFILES}; do assert_equal ${file} ${SRCDIR}/${file} done assert_equal ${TEST_OUT} ${DATAFILE2}
- # List contents and compares output fro tools - list_image + # List contents of multi-file image and compares output from tools + list_image ${IMAGE_MULTI} assert_equal ${DUMPIMAGE_LIST} ${MKIMAGE_LIST}
# Remove files created diff --git a/tools/dumpimage.c b/tools/dumpimage.c index 80bf583..8f1527a 100644 --- a/tools/dumpimage.c +++ b/tools/dumpimage.c @@ -12,9 +12,6 @@
static void usage(void);
-/* image_type_params linked list to maintain registered image types supports */ -static struct image_type_params *dumpimage_tparams; - /* parameters initialized by core will be used by the image type code */ static struct image_tool_params params = { .type = IH_TYPE_KERNEL, @@ -31,33 +28,27 @@ static struct image_tool_params params = { * returns negative if input image format does not match with any of * supported image types */ -static int dumpimage_extract_datafile(void *ptr, struct stat *sbuf) +static int dumpimage_extract_datafile(struct image_type_params *tparams, + void *ptr, struct stat *sbuf) { int retval = -1; - struct image_type_params *curr; - struct image_type_params *start = ll_entry_start( - struct image_type_params, image_type); - struct image_type_params *end = ll_entry_end( - struct image_type_params, image_type); - - for (curr = start; curr != end; curr++) { - if (curr->verify_header) { - retval = curr->verify_header((unsigned char *)ptr, - sbuf->st_size, ¶ms); - if (retval != 0) - continue; - /* - * Extract the file from the image - * if verify is successful - */ - if (curr->extract_datafile) { - curr->extract_datafile(ptr, ¶ms); - } else { - fprintf(stderr, - "%s: extract_datafile undefined for %s\n", - params.cmdname, curr->name); - break; - } + + if (tparams->verify_header) { + retval = tparams->verify_header((unsigned char *)ptr, + sbuf->st_size, ¶ms); + if (retval != 0) + return -1; + /* + * Extract the file from the image + * if verify is successful + */ + if (tparams->extract_datafile) { + retval = tparams->extract_datafile(ptr, ¶ms); + } else { + fprintf(stderr, + "%s: extract_datafile undefined for %s\n", + params.cmdname, tparams->name); + return -2; } }
@@ -75,7 +66,7 @@ int main(int argc, char **argv)
params.cmdname = *argv;
- while ((opt = getopt(argc, argv, "li:o:p:V")) != -1) { + while ((opt = getopt(argc, argv, "li:o:T:p:V")) != -1) { switch (opt) { case 'l': params.lflag = 1; @@ -87,6 +78,12 @@ int main(int argc, char **argv) case 'o': params.outfile = optarg; break; + case 'T': + params.type = genimg_get_type_id(optarg); + if (params.type < 0) { + usage(); + } + break; case 'p': params.pflag = strtoul(optarg, &ptr, 10); if (*ptr) { @@ -101,6 +98,7 @@ int main(int argc, char **argv) exit(EXIT_SUCCESS); default: usage(); + break; } }
@@ -110,7 +108,7 @@ int main(int argc, char **argv) /* set tparams as per input type_id */ tparams = imagetool_get_type(params.type); if (tparams == NULL) { - fprintf(stderr, "%s: unsupported type %s\n", + fprintf(stderr, "%s: unsupported type: %s\n", params.cmdname, genimg_get_type_name(params.type)); exit(EXIT_FAILURE); } @@ -147,7 +145,7 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); }
- if ((unsigned)sbuf.st_size < tparams->header_size) { + if ((uint32_t)sbuf.st_size < tparams->header_size) { fprintf(stderr, "%s: Bad size: "%s" is not valid image\n", params.cmdname, params.imagefile); @@ -172,7 +170,8 @@ int main(int argc, char **argv) * Extract the data files from within the matched * image type. Returns the error code if not matched */ - retval = dumpimage_extract_datafile(ptr, &sbuf); + retval = dumpimage_extract_datafile(tparams, ptr, + &sbuf); } else { /* * Print the image information for matched image type @@ -199,9 +198,10 @@ static void usage(void) " -l ==> list image header information\n", params.cmdname); fprintf(stderr, - " %s -i image [-p position] [-o outfile] data_file\n" - " -i ==> extract from the 'image' a specific 'data_file'" - ", indexed by 'position' (starting at 0)\n", + " %s -i image -T type [-p position] [-o outfile] data_file\n" + " -i ==> extract from the 'image' a specific 'data_file'\n" + " -T ==> set image type to 'type'\n" + " -p ==> 'position' (starting at 0) of the 'data_file' inside the 'image'\n", params.cmdname); fprintf(stderr, " %s -V ==> print version information and exit\n", diff --git a/tools/gpimage-common.c b/tools/gpimage-common.c index b343a3a..5ad52be 100644 --- a/tools/gpimage-common.c +++ b/tools/gpimage-common.c @@ -32,7 +32,8 @@ void to_be32(uint32_t *gph_size, uint32_t *gph_load_addr)
int gph_verify_header(struct gp_header *gph, int be) { - uint32_t gph_size = gph->size, gph_load_addr = gph->load_addr; + uint32_t gph_size = gph->size; + uint32_t gph_load_addr = gph->load_addr;
if (be) to_be32(&gph_size, &gph_load_addr); diff --git a/tools/mkimage.c b/tools/mkimage.c index f668487..5ccd951 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -15,9 +15,6 @@ static void copy_file(int, const char *, int); static void usage(void);
-/* image_type_params link list to maintain registered image type supports */ -struct image_type_params *mkimage_tparams = NULL; - /* parameters initialized by core will be used by the image type code */ struct image_tool_params params = { .os = IH_OS_LINUX,

Signed-off-by: Guilherme Maciel Ferreira guilherme.maciel.ferreira@gmail.com --- tools/default_image.c | 6 +++--- tools/dumpimage.c | 12 ++++++------ tools/imagetool.c | 2 +- tools/imagetool.h | 17 +++++++++-------- 4 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/tools/default_image.c b/tools/default_image.c index 0b0e076..2298f91 100644 --- a/tools/default_image.c +++ b/tools/default_image.c @@ -117,7 +117,7 @@ static void image_set_header(void *ptr, struct stat *sbuf, int ifd, image_set_hcrc(hdr, checksum); }
-static int image_extract_datafile(void *ptr, struct image_tool_params *params) +static int image_extract_subimage(void *ptr, struct image_tool_params *params) { const image_header_t *hdr = (const image_header_t *)ptr; ulong file_data; @@ -144,7 +144,7 @@ static int image_extract_datafile(void *ptr, struct image_tool_params *params) }
/* save the "data file" into the file system */ - return imagetool_save_datafile(params->outfile, file_data, file_len); + return imagetool_save_subimage(params->outfile, file_data, file_len); }
/* @@ -159,7 +159,7 @@ U_BOOT_IMAGE_TYPE( image_verify_header, image_print_contents, image_set_header, - image_extract_datafile, + image_extract_subimage, image_check_image_types, NULL, NULL diff --git a/tools/dumpimage.c b/tools/dumpimage.c index 8f1527a..75a5d47 100644 --- a/tools/dumpimage.c +++ b/tools/dumpimage.c @@ -18,7 +18,7 @@ static struct image_tool_params params = { };
/* - * dumpimage_extract_datafile - + * dumpimage_extract_subimage - * * It scans all registered image types, * verifies image_header for each supported image type @@ -28,7 +28,7 @@ static struct image_tool_params params = { * returns negative if input image format does not match with any of * supported image types */ -static int dumpimage_extract_datafile(struct image_type_params *tparams, +static int dumpimage_extract_subimage(struct image_type_params *tparams, void *ptr, struct stat *sbuf) { int retval = -1; @@ -42,11 +42,11 @@ static int dumpimage_extract_datafile(struct image_type_params *tparams, * Extract the file from the image * if verify is successful */ - if (tparams->extract_datafile) { - retval = tparams->extract_datafile(ptr, ¶ms); + if (tparams->extract_subimage) { + retval = tparams->extract_subimage(ptr, ¶ms); } else { fprintf(stderr, - "%s: extract_datafile undefined for %s\n", + "%s: extract_subimage undefined for %s\n", params.cmdname, tparams->name); return -2; } @@ -170,7 +170,7 @@ int main(int argc, char **argv) * Extract the data files from within the matched * image type. Returns the error code if not matched */ - retval = dumpimage_extract_datafile(tparams, ptr, + retval = dumpimage_extract_subimage(tparams, ptr, &sbuf); } else { /* diff --git a/tools/imagetool.c b/tools/imagetool.c index 9d2819e..148e466 100644 --- a/tools/imagetool.c +++ b/tools/imagetool.c @@ -66,7 +66,7 @@ int imagetool_verify_print_header( return retval; }
-int imagetool_save_datafile( +int imagetool_save_subimage( const char *file_name, ulong file_data, ulong file_len) diff --git a/tools/imagetool.h b/tools/imagetool.h index 544f9db..34ff284 100644 --- a/tools/imagetool.h +++ b/tools/imagetool.h @@ -110,14 +110,15 @@ struct image_type_params { void (*set_header) (void *, struct stat *, int, struct image_tool_params *); /* - * This function is used by the command to retrieve a data file from - * the image (i.e. dumpimage -i <image> -p <position> <data_file>). + * This function is used by the command to retrieve a component + * (sub-image) from the image (i.e. dumpimage -i <image> -p <position> + * <sub-image-name>). * Thus the code to extract a file from an image must be put here. * * Returns 0 if the file was successfully retrieved from the image, * or a negative value on error. */ - int (*extract_datafile) (void *, struct image_tool_params *); + int (*extract_subimage)(void *, struct image_tool_params *); /* * Some image generation support for ex (default image type) supports * more than one type_ids, this callback function is used to check @@ -169,18 +170,18 @@ int imagetool_verify_print_header( struct image_tool_params *params);
/** - * imagetool_save_datafile - store data into a file + * imagetool_save_subimage - store data into a file * @file_name: name of the destination file * @file_data: data to be written * @file_len: the amount of data to store * - * imagetool_save_datafile() store file_len bytes of data pointed by file_data + * imagetool_save_subimage() store file_len bytes of data pointed by file_data * into the file name by file_name. * * returns: * zero in case of success or a negative value if fail. */ -int imagetool_save_datafile( +int imagetool_save_subimage( const char *file_name, ulong file_data, ulong file_len); @@ -202,7 +203,7 @@ void pbl_load_uboot(int fd, struct image_tool_params *mparams); _verify_header, \ _print_header, \ _set_header, \ - _extract_datafile, \ + _extract_subimage, \ _check_image_type, \ _fflag_handle, \ _vrec_header \ @@ -215,7 +216,7 @@ void pbl_load_uboot(int fd, struct image_tool_params *mparams); .verify_header = _verify_header, \ .print_header = _print_header, \ .set_header = _set_header, \ - .extract_datafile = _extract_datafile, \ + .extract_subimage = _extract_subimage, \ .check_image_type = _check_image_type, \ .fflag_handle = _fflag_handle, \ .vrec_header = _vrec_header \

On Thu, Jan 15, 2015 at 02:54:41AM -0200, Guilherme Maciel Ferreira wrote:
Signed-off-by: Guilherme Maciel Ferreira guilherme.maciel.ferreira@gmail.com
Applied to u-boot/master, thanks!

The dumpimage is able to extract components contained in a FIT image:
$ ./dumpimage -T flat_dt -i CONTAINER.ITB -p INDEX FILE
The CONTAINER.ITB is a regular FIT container file. The INDEX is the poisition of the sub-image to be retrieved, and FILE is the file (path+name) to save the extracted sub-image.
For example, given the following kernel.its to build a kernel.itb:
/dts-v1/; / { ... images { kernel@1 { description = "Kernel 2.6.32-34"; data = /incbin/("/boot/vmlinuz-2.6.32-34-generic"); type = "kernel"; arch = "ppc"; os = "linux"; compression = "gzip"; load = <00000000>; entry = <00000000>; hash@1 { algo = "md5"; }; }; ... }; ... };
The dumpimage can extract the 'kernel@1' node through the following command:
$ ./dumpimage -T flat_dt -i kernel.itb -p 0 kernel Extracted: Image 0 (kernel@1) Description: Kernel 2.6.32-34 Created: Wed Oct 22 15:50:26 2014 Type: Kernel Image Compression: gzip compressed Data Size: 4040128 Bytes = 3945.44 kB = 3.85 MB Architecture: PowerPC OS: Linux Load Address: 0x00000000 Entry Point: 0x00000000 Hash algo: md5 Hash value: 22352ad39bdc03e2e50f9cc28c1c3652
Which results in the file 'kernel' being exactly the same as '/boot/vmlinuz-2.6.32-34-generic'.
Signed-off-by: Guilherme Maciel Ferreira guilherme.maciel.ferreira@gmail.com --- common/image-fit.c | 30 +++++++++++++- include/image.h | 1 + test/image/test-imagetools.sh | 83 ++++++++++++++++++++++++++++++++++++- tools/fit_image.c | 93 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 204 insertions(+), 3 deletions(-)
diff --git a/common/image-fit.c b/common/image-fit.c index 4ffc5aa..aaf3a81 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -112,6 +112,33 @@ static void fit_get_debug(const void *fit, int noffset, fdt_strerror(err)); }
+/** + * fit_get_subimage_count - get component (sub-image) count + * @fit: pointer to the FIT format image header + * @images_noffset: offset of images node + * + * returns: + * number of image components + */ +int fit_get_subimage_count(const void *fit, int images_noffset) +{ + int noffset; + int ndepth; + int count = 0; + + /* Process its subnodes, print out component images details */ + for (ndepth = 0, count = 0, + noffset = fdt_next_node(fit, images_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node(fit, noffset, &ndepth)) { + if (ndepth == 1) { + count++; + } + } + + return count; +} + #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_FIT_SPL_PRINT) /** * fit_print_contents - prints out the contents of the FIT format image @@ -423,7 +450,8 @@ void fit_image_print(const void *fit, int image_noffset, const char *p) } } } -#endif + +#endif /* !defined(CONFIG_SPL_BUILD) || defined(CONFIG_FIT_SPL_PRINT) */
/** * fit_get_desc - get node description property diff --git a/include/image.h b/include/image.h index aa748fa..f236fdd 100644 --- a/include/image.h +++ b/include/image.h @@ -750,6 +750,7 @@ int fit_parse_conf(const char *spec, ulong addr_curr, int fit_parse_subimage(const char *spec, ulong addr_curr, ulong *addr, const char **image_name);
+int fit_get_subimage_count(const void *fit, int images_noffset); void fit_print_contents(const void *fit); void fit_image_print(const void *fit, int noffset, const char *p);
diff --git a/test/image/test-imagetools.sh b/test/image/test-imagetools.sh index 8aaaade..952f975 100755 --- a/test/image/test-imagetools.sh +++ b/test/image/test-imagetools.sh @@ -16,6 +16,8 @@ BASEDIR=sandbox SRCDIR=${BASEDIR}/boot IMAGE_NAME="v1.0-test" IMAGE_MULTI=linux.img +IMAGE_FIT_ITS=linux.its +IMAGE_FIT_ITB=linux.itb DATAFILE0=vmlinuz DATAFILE1=initrd.img DATAFILE2=System.map @@ -34,7 +36,10 @@ cleanup() for file in ${DATAFILES}; do rm -f ${file} ${SRCDIR}/${file} done - rm -f ${IMAGE_MULTI} ${DUMPIMAGE_LIST} ${MKIMAGE_LIST} ${TEST_OUT} + rm -f ${IMAGE_MULTI} + rm -f ${DUMPIMAGE_LIST} + rm -f ${MKIMAGE_LIST} + rm -f ${TEST_OUT} rmdir ${SRCDIR} }
@@ -105,6 +110,70 @@ extract_multi_image() echo "done." }
+# Write files into a FIT image +create_fit_image() +{ + echo " \ + /dts-v1/; \ + / { \ + description = "FIT image"; \ + #address-cells = <1>; \ + \ + images { \ + kernel@1 { \ + description = "kernel"; \ + data = /incbin/("${DATAFILE0}"); \ + type = "kernel"; \ + arch = "sandbox"; \ + os = "linux"; \ + compression = "gzip"; \ + load = <0x40000>; \ + entry = <0x8>; \ + }; \ + ramdisk@1 { \ + description = "filesystem"; \ + data = /incbin/("${DATAFILE1}"); \ + type = "ramdisk"; \ + arch = "sandbox"; \ + os = "linux"; \ + compression = "none"; \ + load = <0x80000>; \ + entry = <0x16>; \ + }; \ + fdt@1 { \ + description = "device tree"; \ + data = /incbin/("${DATAFILE2}"); \ + type = "flat_dt"; \ + arch = "sandbox"; \ + compression = "none"; \ + }; \ + }; \ + configurations { \ + default = "conf@1"; \ + conf@1 { \ + kernel = "kernel@1"; \ + fdt = "fdt@1"; \ + }; \ + }; \ + }; \ + " > ${IMAGE_FIT_ITS} + + echo -e "\nBuilding FIT image..." + do_cmd ${MKIMAGE} -f ${IMAGE_FIT_ITS} ${IMAGE_FIT_ITB} + echo "done." +} + +# Extract files from a FIT image +extract_fit_image() +{ + echo -e "\nExtracting FIT image contents..." + do_cmd ${DUMPIMAGE} -T flat_dt -i ${IMAGE_FIT_ITB} -p 0 ${DATAFILE0} + do_cmd ${DUMPIMAGE} -T flat_dt -i ${IMAGE_FIT_ITB} -p 1 ${DATAFILE1} + do_cmd ${DUMPIMAGE} -T flat_dt -i ${IMAGE_FIT_ITB} -p 2 ${DATAFILE2} + do_cmd ${DUMPIMAGE} -T flat_dt -i ${IMAGE_FIT_ITB} -p 2 ${DATAFILE2} -o ${TEST_OUT} + echo "done." +} + # List the contents of a file # Args: # image filename @@ -136,6 +205,18 @@ main() list_image ${IMAGE_MULTI} assert_equal ${DUMPIMAGE_LIST} ${MKIMAGE_LIST}
+ # Compress and extract FIT images, compare the result + create_fit_image + extract_fit_image + for file in ${DATAFILES}; do + assert_equal ${file} ${SRCDIR}/${file} + done + assert_equal ${TEST_OUT} ${DATAFILE2} + + # List contents of FIT image and compares output from tools + list_image ${IMAGE_FIT_ITB} + assert_equal ${DUMPIMAGE_LIST} ${MKIMAGE_LIST} + # Remove files created cleanup
diff --git a/tools/fit_image.c b/tools/fit_image.c index 5712842..eb2a25e 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -155,6 +155,97 @@ err_system: return -1; }
+/** + * fit_image_extract - extract a FIT component image + * @fit: pointer to the FIT format image header + * @image_noffset: offset of the component image node + * @file_name: name of the file to store the FIT sub-image + * + * returns: + * zero in case of success or a negative value if fail. + */ +static int fit_image_extract( + const void *fit, + int image_noffset, + const char *file_name) +{ + const void *file_data; + size_t file_size = 0; + + /* get the "data" property of component at offset "image_noffset" */ + fit_image_get_data(fit, image_noffset, &file_data, &file_size); + + /* save the "file_data" into the file specified by "file_name" */ + return imagetool_save_subimage(file_name, (ulong) file_data, file_size); +} + +/** + * fit_extract_contents - retrieve a sub-image component from the FIT image + * @ptr: pointer to the FIT format image header + * @params: command line parameters + * + * returns: + * zero in case of success or a negative value if fail. + */ +static int fit_extract_contents(void *ptr, struct image_tool_params *params) +{ + int images_noffset; + int noffset; + int ndepth; + const void *fit = ptr; + int count = 0; + const char *p; + + /* Indent string is defined in header image.h */ + p = IMAGE_INDENT_STRING; + + if (!fit_check_format(fit)) { + printf("Bad FIT image format\n"); + return -1; + } + + /* Find images parent node offset */ + images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); + if (images_noffset < 0) { + printf("Can't find images parent node '%s' (%s)\n", + FIT_IMAGES_PATH, fdt_strerror(images_noffset)); + return -1; + } + + /* Avoid any overrun */ + count = fit_get_subimage_count(fit, images_noffset); + if ((params->pflag < 0) || (count <= params->pflag)) { + printf("No such component at '%d'\n", params->pflag); + return -1; + } + + /* Process its subnodes, extract the desired component from image */ + for (ndepth = 0, count = 0, + noffset = fdt_next_node(fit, images_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node(fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* + * Direct child node of the images parent node, + * i.e. component image node. + */ + if (params->pflag == count) { + printf("Extracted:\n%s Image %u (%s)\n", p, + count, fit_get_name(fit, noffset, NULL)); + + fit_image_print(fit, noffset, p); + + return fit_image_extract(fit, noffset, + params->outfile); + } + + count++; + } + } + + return 0; +} + static int fit_check_params(struct image_tool_params *params) { return ((params->dflag && (params->fflag || params->lflag)) || @@ -171,7 +262,7 @@ U_BOOT_IMAGE_TYPE( fit_verify_header, fit_print_contents, NULL, - NULL, + fit_extract_contents, fit_check_image_types, fit_handle_file, NULL /* FIT images use DTB header */

On Thu, Jan 15, 2015 at 02:54:42AM -0200, Guilherme Maciel Ferreira wrote:
The dumpimage is able to extract components contained in a FIT image:
$ ./dumpimage -T flat_dt -i CONTAINER.ITB -p INDEX FILE
The CONTAINER.ITB is a regular FIT container file. The INDEX is the poisition of the sub-image to be retrieved, and FILE is the file (path+name) to save the extracted sub-image.
For example, given the following kernel.its to build a kernel.itb:
/dts-v1/; / { ... images { kernel@1 { description = "Kernel 2.6.32-34"; data = /incbin/("/boot/vmlinuz-2.6.32-34-generic"); type = "kernel"; arch = "ppc"; os = "linux"; compression = "gzip"; load = <00000000>; entry = <00000000>; hash@1 { algo = "md5"; }; }; ... }; ... };
The dumpimage can extract the 'kernel@1' node through the following command:
$ ./dumpimage -T flat_dt -i kernel.itb -p 0 kernel Extracted: Image 0 (kernel@1) Description: Kernel 2.6.32-34 Created: Wed Oct 22 15:50:26 2014 Type: Kernel Image Compression: gzip compressed Data Size: 4040128 Bytes = 3945.44 kB = 3.85 MB Architecture: PowerPC OS: Linux Load Address: 0x00000000 Entry Point: 0x00000000 Hash algo: md5 Hash value: 22352ad39bdc03e2e50f9cc28c1c3652
Which results in the file 'kernel' being exactly the same as '/boot/vmlinuz-2.6.32-34-generic'.
Signed-off-by: Guilherme Maciel Ferreira guilherme.maciel.ferreira@gmail.com
Applied to u-boot/master, thanks!

default_image.c and socfpgaimage.c are the only image modules that print error messages during header verification. The verify_header() is used to query if a given image file is processed by the image format. Thus, if the image format can't handle the file, it must simply return an error. Otherwise we pollute the screen with errors messages until we find the image format that handle a given image file.
Signed-off-by: Guilherme Maciel Ferreira guilherme.maciel.ferreira@gmail.com --- tools/default_image.c | 17 ++++++++--------- tools/socfpgaimage.c | 6 ++++-- 2 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/tools/default_image.c b/tools/default_image.c index 2298f91..cf5c0d4 100644 --- a/tools/default_image.c +++ b/tools/default_image.c @@ -15,6 +15,8 @@ */
#include "imagetool.h" +#include "mkimage.h" + #include <image.h> #include <u-boot/crc.h>
@@ -53,9 +55,8 @@ static int image_verify_header(unsigned char *ptr, int image_size, memcpy(hdr, ptr, sizeof(image_header_t));
if (be32_to_cpu(hdr->ih_magic) != IH_MAGIC) { - fprintf(stderr, - "%s: Bad Magic Number: "%s" is no valid image\n", - params->cmdname, params->imagefile); + debug("%s: Bad Magic Number: "%s" is no valid image\n", + params->cmdname, params->imagefile); return -FDT_ERR_BADMAGIC; }
@@ -66,9 +67,8 @@ static int image_verify_header(unsigned char *ptr, int image_size, hdr->ih_hcrc = cpu_to_be32(0); /* clear for re-calculation */
if (crc32(0, data, len) != checksum) { - fprintf(stderr, - "%s: ERROR: "%s" has bad header checksum!\n", - params->cmdname, params->imagefile); + debug("%s: ERROR: "%s" has bad header checksum!\n", + params->cmdname, params->imagefile); return -FDT_ERR_BADSTATE; }
@@ -77,9 +77,8 @@ static int image_verify_header(unsigned char *ptr, int image_size,
checksum = be32_to_cpu(hdr->ih_dcrc); if (crc32(0, data, len) != checksum) { - fprintf(stderr, - "%s: ERROR: "%s" has corrupted data!\n", - params->cmdname, params->imagefile); + debug("%s: ERROR: "%s" has corrupted data!\n", + params->cmdname, params->imagefile); return -FDT_ERR_BADSTRUCTURE; } return 0; diff --git a/tools/socfpgaimage.c b/tools/socfpgaimage.c index 652ae45..8fe91fe 100644 --- a/tools/socfpgaimage.c +++ b/tools/socfpgaimage.c @@ -33,6 +33,8 @@
#include "pbl_crc32.h" #include "imagetool.h" +#include "mkimage.h" + #include <image.h>
#define HEADER_OFFSET 0x40 @@ -133,12 +135,12 @@ static int verify_buffer(const uint8_t *buf)
len = verify_header(buf + HEADER_OFFSET); if (len < 0) { - fprintf(stderr, "Invalid header\n"); + debug("Invalid header\n"); return -1; }
if (len < HEADER_OFFSET || len > PADDED_SIZE) { - fprintf(stderr, "Invalid header length (%i)\n", len); + debug("Invalid header length (%i)\n", len); return -1; }

On Thu, Jan 15, 2015 at 02:54:43AM -0200, Guilherme Maciel Ferreira wrote:
default_image.c and socfpgaimage.c are the only image modules that print error messages during header verification. The verify_header() is used to query if a given image file is processed by the image format. Thus, if the image format can't handle the file, it must simply return an error. Otherwise we pollute the screen with errors messages until we find the image format that handle a given image file.
Signed-off-by: Guilherme Maciel Ferreira guilherme.maciel.ferreira@gmail.com
Applied to u-boot/master, thanks!

On Thu, Jan 15, 2015 at 02:54:40AM -0200, Guilherme Maciel Ferreira wrote:
From: Guilherme Maciel Ferreira guilherme.maciel@datacom.ind.br
Some image types, like "KeyStone GP", do not have magic numbers to distinguish them from other image types. Thus, the automatic image type discovery does not work correctly.
This patch also fix some integer type mismatches.
Signed-off-by: Guilherme Maciel Ferreira guilherme.maciel.ferreira@gmail.com
Applied to u-boot/master, thanks!
participants (2)
-
Guilherme Maciel Ferreira
-
Tom Rini