tools: mkimage/dumpimage: Allow to use -l with -T

Currently -l option for mkimage and dumpimage ignores option -T and always
tries to autodetect image type.

With this change it is possible to tell mkimage and dumpimage to parse
image file as specific type (and not random autodetected type). This allows
to use mkimage -l or dumpimage -l as tool for validating image.

params.type for -l option is now by default initialized to zero
(IH_TYPE_INVALID) instead of IH_TYPE_KERNEL. imagetool_get_type() for
IH_TYPE_INVALID returns NULL, which is assigned to tparams. mkimage and
dumpimage code is extended to handle tparams with NULL for -l option. And
imagetool_verify_print_header() is extended to do validation via tparams if
is not NULL.

Signed-off-by: Pali Rohár <pali@kernel.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Pali Rohár 2022-02-13 01:09:46 +01:00 committed by Tom Rini
parent a900c7f816
commit 11f29d4436
5 changed files with 44 additions and 52 deletions

View File

@ -1,10 +1,10 @@
.TH MKIMAGE 1 "2010-05-16" .TH MKIMAGE 1 "2022-02-07"
.SH NAME .SH NAME
mkimage \- Generate image for U-Boot mkimage \- Generate image for U-Boot
.SH SYNOPSIS .SH SYNOPSIS
.B mkimage .B mkimage
.RB "\-l [" "uimage file name" "]" .RB [ \-T " \fItype\fP] " \-l " [\fIuimage file name\fP]"
.B mkimage .B mkimage
.RB [\fIoptions\fP] " \-f [" "image tree source file" "]" " [" "uimage file name" "]" .RB [\fIoptions\fP] " \-f [" "image tree source file" "]" " [" "uimage file name" "]"
@ -47,6 +47,12 @@ supports verified boot.
.BI "\-l [" "uimage file name" "]" .BI "\-l [" "uimage file name" "]"
mkimage lists the information contained in the header of an existing U-Boot image. mkimage lists the information contained in the header of an existing U-Boot image.
.TP
.BI "\-T [" "image type" "]"
Parse image file as type.
Pass \-h as the image to see the list of supported image type.
Without this option image type is autodetected.
.P .P
.B Create old legacy image: .B Create old legacy image:

View File

@ -12,9 +12,7 @@
static void usage(void); static void usage(void);
/* parameters initialized by core will be used by the image type code */ /* parameters initialized by core will be used by the image type code */
static struct image_tool_params params = { static struct image_tool_params params;
.type = IH_TYPE_KERNEL,
};
/* /*
* dumpimage_extract_subimage - * dumpimage_extract_subimage -
@ -110,7 +108,7 @@ int main(int argc, char **argv)
} }
} }
if (argc < 2) if (argc < 2 || (params.iflag && params.lflag))
usage(); usage();
if (optind >= argc) { if (optind >= argc) {
@ -122,7 +120,7 @@ int main(int argc, char **argv)
/* set tparams as per input type_id */ /* set tparams as per input type_id */
tparams = imagetool_get_type(params.type); tparams = imagetool_get_type(params.type);
if (tparams == NULL) { if (!params.lflag && tparams == NULL) {
fprintf(stderr, "%s: unsupported type: %s\n", fprintf(stderr, "%s: unsupported type: %s\n",
params.cmdname, genimg_get_type_name(params.type)); params.cmdname, genimg_get_type_name(params.type));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -132,7 +130,7 @@ int main(int argc, char **argv)
* check the passed arguments parameters meets the requirements * check the passed arguments parameters meets the requirements
* as per image type to be generated/listed * as per image type to be generated/listed
*/ */
if (tparams->check_params) { if (tparams && tparams->check_params) {
if (tparams->check_params(&params)) { if (tparams->check_params(&params)) {
fprintf(stderr, "%s: Parameter check failed\n", fprintf(stderr, "%s: Parameter check failed\n",
params.cmdname); params.cmdname);
@ -159,7 +157,7 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if ((uint32_t)sbuf.st_size < tparams->header_size) { if (tparams && (uint32_t)sbuf.st_size < tparams->header_size) {
fprintf(stderr, "%s: Bad size: \"%s\" is not valid image\n", fprintf(stderr, "%s: Bad size: \"%s\" is not valid image\n",
params.cmdname, params.imagefile); params.cmdname, params.imagefile);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -203,8 +201,9 @@ int main(int argc, char **argv)
static void usage(void) static void usage(void)
{ {
fprintf(stderr, "Usage: %s -l image\n" fprintf(stderr, "Usage: %s [-T type] -l image\n"
" -l ==> list image header information\n", " -l ==> list image header information\n"
" -T ==> parse image file as 'type'\n",
params.cmdname); params.cmdname);
fprintf(stderr, fprintf(stderr,
" %s [-T type] [-p position] [-o outfile] image\n" " %s [-T type] [-p position] [-o outfile] image\n"

View File

@ -26,6 +26,12 @@ struct image_type_params *imagetool_get_type(int type)
return NULL; return NULL;
} }
static int imagetool_verify_print_header_by_type(
void *ptr,
struct stat *sbuf,
struct image_type_params *tparams,
struct image_tool_params *params);
int imagetool_verify_print_header( int imagetool_verify_print_header(
void *ptr, void *ptr,
struct stat *sbuf, struct stat *sbuf,
@ -39,6 +45,9 @@ int imagetool_verify_print_header(
struct image_type_params **start = __start_image_type; struct image_type_params **start = __start_image_type;
struct image_type_params **end = __stop_image_type; struct image_type_params **end = __stop_image_type;
if (tparams)
return imagetool_verify_print_header_by_type(ptr, sbuf, tparams, params);
for (curr = start; curr != end; curr++) { for (curr = start; curr != end; curr++) {
if ((*curr)->verify_header) { if ((*curr)->verify_header) {
retval = (*curr)->verify_header((unsigned char *)ptr, retval = (*curr)->verify_header((unsigned char *)ptr,
@ -65,7 +74,7 @@ int imagetool_verify_print_header(
return retval; return retval;
} }
int imagetool_verify_print_header_by_type( static int imagetool_verify_print_header_by_type(
void *ptr, void *ptr,
struct stat *sbuf, struct stat *sbuf,
struct image_type_params *tparams, struct image_type_params *tparams,

View File

@ -178,33 +178,19 @@ struct image_type_params *imagetool_get_type(int type);
/* /*
* imagetool_verify_print_header() - verifies the image header * imagetool_verify_print_header() - verifies the image header
* *
* Scan registered image types and verify the image_header for each
* supported image type. If verification is successful, this prints
* the respective header.
*
* Return: 0 on success, negative if input image format does not match with
* any of supported image types
*/
int imagetool_verify_print_header(
void *ptr,
struct stat *sbuf,
struct image_type_params *tparams,
struct image_tool_params *params);
/*
* imagetool_verify_print_header_by_type() - verifies the image header
*
* Verify the image_header for the image type given by tparams. * Verify the image_header for the image type given by tparams.
* If tparams is NULL then scan registered image types and verify the
* image_header for each supported image type.
* If verification is successful, this prints the respective header. * If verification is successful, this prints the respective header.
* @ptr: pointer the the image header * @ptr: pointer the the image header
* @sbuf: stat information about the file pointed to by ptr * @sbuf: stat information about the file pointed to by ptr
* @tparams: image type parameters * @tparams: image type parameters or NULL
* @params: mkimage parameters * @params: mkimage parameters
* *
* Return: 0 on success, negative if input image format does not match with * Return: 0 on success, negative if input image format does not match with
* the given image type * the given image type
*/ */
int imagetool_verify_print_header_by_type( int imagetool_verify_print_header(
void *ptr, void *ptr,
struct stat *sbuf, struct stat *sbuf,
struct image_type_params *tparams, struct image_type_params *tparams,

View File

@ -82,8 +82,9 @@ static int show_valid_options(enum ih_category category)
static void usage(const char *msg) static void usage(const char *msg)
{ {
fprintf(stderr, "Error: %s\n", msg); fprintf(stderr, "Error: %s\n", msg);
fprintf(stderr, "Usage: %s -l image\n" fprintf(stderr, "Usage: %s [-T type] -l image\n"
" -l ==> list image header information\n", " -l ==> list image header information\n"
" -T ==> parse image file as 'type'\n",
params.cmdname); params.cmdname);
fprintf(stderr, fprintf(stderr,
" %s [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image\n" " %s [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image\n"
@ -329,7 +330,7 @@ static void process_args(int argc, char **argv)
params.datafile = datafile; params.datafile = datafile;
else if (!params.datafile) else if (!params.datafile)
usage("Missing data file for auto-FIT (use -d)"); usage("Missing data file for auto-FIT (use -d)");
} else if (type != IH_TYPE_INVALID) { } else if (params.lflag || type != IH_TYPE_INVALID) {
if (type == IH_TYPE_SCRIPT && !params.datafile) if (type == IH_TYPE_SCRIPT && !params.datafile)
usage("Missing data file for script (use -d)"); usage("Missing data file for script (use -d)");
params.type = type; params.type = type;
@ -358,7 +359,7 @@ int main(int argc, char **argv)
/* set tparams as per input type_id */ /* set tparams as per input type_id */
tparams = imagetool_get_type(params.type); tparams = imagetool_get_type(params.type);
if (tparams == NULL) { if (tparams == NULL && !params.lflag) {
fprintf (stderr, "%s: unsupported type %s\n", fprintf (stderr, "%s: unsupported type %s\n",
params.cmdname, genimg_get_type_name(params.type)); params.cmdname, genimg_get_type_name(params.type));
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
@ -368,14 +369,14 @@ int main(int argc, char **argv)
* check the passed arguments parameters meets the requirements * check the passed arguments parameters meets the requirements
* as per image type to be generated/listed * as per image type to be generated/listed
*/ */
if (tparams->check_params) if (tparams && tparams->check_params)
if (tparams->check_params (&params)) if (tparams->check_params (&params))
usage("Bad parameters for image type"); usage("Bad parameters for image type");
if (!params.eflag) { if (!params.eflag) {
params.ep = params.addr; params.ep = params.addr;
/* If XIP, entry point must be after the U-Boot header */ /* If XIP, entry point must be after the U-Boot header */
if (params.xflag) if (params.xflag && tparams)
params.ep += tparams->header_size; params.ep += tparams->header_size;
} }
@ -436,7 +437,7 @@ int main(int argc, char **argv)
params.cmdname, params.imagefile); params.cmdname, params.imagefile);
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
#endif #endif
} else if (sbuf.st_size < (off_t)tparams->header_size) { } else if (tparams && sbuf.st_size < (off_t)tparams->header_size) {
fprintf (stderr, fprintf (stderr,
"%s: Bad size: \"%s\" is not valid image: size %llu < %u\n", "%s: Bad size: \"%s\" is not valid image: size %llu < %u\n",
params.cmdname, params.imagefile, params.cmdname, params.imagefile,
@ -455,21 +456,12 @@ int main(int argc, char **argv)
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
if (params.fflag) { /*
/* * Verifies the header format based on the expected header for image
* Verifies the header format based on the expected header for image * type in tparams. If tparams is NULL simply check all image types
* type in tparams * to find one that matches our header.
*/ */
retval = imagetool_verify_print_header_by_type(ptr, &sbuf, retval = imagetool_verify_print_header(ptr, &sbuf, tparams, &params);
tparams, &params);
} else {
/**
* When listing the image, we are not given the image type. Simply check all
* image types to find one that matches our header
*/
retval = imagetool_verify_print_header(ptr, &sbuf,
tparams, &params);
}
(void) munmap((void *)ptr, sbuf.st_size); (void) munmap((void *)ptr, sbuf.st_size);
(void) close (ifd); (void) close (ifd);