
From: Simon Glass <sjg@chromium.org> Support creation of a load-only FIT (where there is no OS), with a new --load-only option. Allow FITs to be created without an OS image. Update the auto-generated FIT description to make this clear. Signed-off-by: Simon Glass <sjg@chromium.org> --- doc/mkimage.1 | 13 ++++++++ tools/fit_image.c | 78 +++++++++++++++++++++++++++++------------------ tools/imagetool.h | 1 + tools/mkimage.c | 10 +++++- 4 files changed, 71 insertions(+), 31 deletions(-) diff --git a/doc/mkimage.1 b/doc/mkimage.1 index d0a038a880a..b98d405f424 100644 --- a/doc/mkimage.1 +++ b/doc/mkimage.1 @@ -476,6 +476,19 @@ the timestamp is assumed to have been set previously. This section documents the formats of the primary and secondary configuration options for each image type which supports them. . +.TQ +.B \-\-load\-only +Permit creation of a load-only FIT. +.IP +Normally a FIT has an OS image included and mkimage expects this. With this +option, a special FIT can be created which only has devicetrees. This can be +loaded before the normal 'OS' devicetree. This option sets the load-only +property in each generated configuration and allows the OS image to be missing. +. +.SH CONFIGURATION +This section documents the formats of the primary and secondary configuration +options for each image type which supports them. +. .SS aisimage The primary configuration is a file containing a series of .I AIS diff --git a/tools/fit_image.c b/tools/fit_image.c index c8a8f7e1437..013242cd204 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -100,12 +100,14 @@ err_keydest: static int fit_calc_size(struct imgtool *itl) { struct content_info *cont; - int size, total_size; + int size, total_size = 0; - size = imagetool_get_filesize(itl, itl->datafile); - if (size < 0) - return -1; - total_size = size; + if (itl->datafile) { + size = imagetool_get_filesize(itl, itl->datafile); + if (size < 0) + return -1; + total_size += size; + } if (itl->fit_ramdisk) { size = imagetool_get_filesize(itl, itl->fit_ramdisk); @@ -285,29 +287,33 @@ static int fit_write_images(struct imgtool *itl, char *fdt) fdt_begin_node(fdt, "images"); /* First the main image */ - typename = genimg_get_type_short_name(itl->fit_image_type); - snprintf(str, sizeof(str), "%s-1", typename); - fdt_begin_node(fdt, str); - fdt_property_string(fdt, FIT_DESC_PROP, itl->imagename); - fdt_property_string(fdt, FIT_TYPE_PROP, typename); - fdt_property_string(fdt, FIT_ARCH_PROP, - genimg_get_arch_short_name(itl->arch)); - fdt_property_string(fdt, FIT_OS_PROP, - genimg_get_os_short_name(itl->os)); - fdt_property_string(fdt, FIT_COMP_PROP, - genimg_get_comp_short_name(itl->comp)); - fdt_property_u32(fdt, FIT_LOAD_PROP, itl->addr); - fdt_property_u32(fdt, FIT_ENTRY_PROP, itl->ep); + if (itl->datafile) { + typename = genimg_get_type_short_name(itl->fit_image_type); + snprintf(str, sizeof(str), "%s-1", typename); + fdt_begin_node(fdt, str); + fdt_property_string(fdt, FIT_DESC_PROP, itl->imagename); + fdt_property_string(fdt, FIT_TYPE_PROP, typename); + fdt_property_string(fdt, FIT_ARCH_PROP, + genimg_get_arch_short_name(itl->arch)); + fdt_property_string(fdt, FIT_OS_PROP, + genimg_get_os_short_name(itl->os)); + fdt_property_string(fdt, FIT_COMP_PROP, + genimg_get_comp_short_name(itl->comp)); + fdt_property_u32(fdt, FIT_LOAD_PROP, itl->addr); + fdt_property_u32(fdt, FIT_ENTRY_PROP, itl->ep); - /* - * Put data last since it is large. SPL may only load the first part - * of the DT, so this way it can access all the above fields. - */ - ret = fdt_property_file(itl, fdt, itl->datafile, NULL); - if (ret) - return ret; - fit_add_hash_or_sign(itl, fdt, true); - fdt_end_node(fdt); + /* + * Put data last since it is large. SPL may only load the first + * part of the DT, so this way it can access all the above + * fields. If the FIT is converted to use external data, then + * there is no benefit here, but also no loss. + */ + ret = fdt_property_file(itl, fdt, itl->datafile, NULL); + if (ret) + return ret; + fit_add_hash_or_sign(itl, fdt, true); + fdt_end_node(fdt); + } /* Now the device tree files if available */ upto = 0; @@ -406,6 +412,8 @@ static void fit_write_configs(struct imgtool *itl, char *fdt) snprintf(str, sizeof(str), FIT_FDT_PROP "-%d", upto); fdt_property_string(fdt, FIT_FDT_PROP, str); + if (itl->load_only) + fdt_property(fdt, FIT_LOAD_ONLY_PROP, NULL, 0); if (cont->compat) fdt_property(fdt, FIT_COMPATIBLE_PROP, cont->compat, cont->compat_len); @@ -433,16 +441,26 @@ static void fit_write_configs(struct imgtool *itl, char *fdt) static int fit_build_fdt(struct imgtool *itl, char *fdt, int size) { + const struct content_info *cont; + bool has_fdt; int ret; + has_fdt = false; + for (cont = itl->content_head; cont; cont = cont->next) { + if (cont->type == IH_TYPE_FLATDT) { + has_fdt = true; + break; + } + } + ret = fdt_create(fdt, size); if (ret) return ret; fdt_finish_reservemap(fdt); fdt_begin_node(fdt, ""); - fdt_property_strf(fdt, FIT_DESC_PROP, - "%s image with one or more FDT blobs", - genimg_get_type_name(itl->fit_image_type)); + fdt_property_strf(fdt, FIT_DESC_PROP, "%s image%s", + genimg_get_type_name(itl->fit_image_type), + has_fdt ? " with one or more FDT blobs" : ""); fdt_property_strf(fdt, "creator", "U-Boot mkimage %s", PLAIN_VERSION); fdt_property_u32(fdt, "#address-cells", 1); ret = fit_write_images(itl, fdt); diff --git a/tools/imagetool.h b/tools/imagetool.h index 32694e32963..83812ea0566 100644 --- a/tools/imagetool.h +++ b/tools/imagetool.h @@ -111,6 +111,7 @@ struct imgtool { const char *engine_id; /* Engine to use for signing */ bool reset_timestamp; /* Reset the timestamp on an existing image */ struct image_summary summary; /* results of signing process */ + bool load_only; /* true to create a load-only FIT */ }; /** struct imgtool_funcs - image-type-specific variables and callbacks */ diff --git a/tools/mkimage.c b/tools/mkimage.c index 684e895938b..da629f17972 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -155,6 +155,10 @@ static int add_content(struct imgtool *itl, int type, const char *fname) static const char optstring[] = "a:A:b:B:c:C:d:D:e:Ef:Fg:G:i:k:K:ln:N:o:O:p:qrR:stT:vVx"; +enum { + OPT_LOAD_ONLY = 1, +}; + static const struct option longopts[] = { { "load-address", required_argument, NULL, 'a' }, { "architecture", required_argument, NULL, 'A' }, @@ -189,6 +193,7 @@ static const struct option longopts[] = { { "verbose", no_argument, NULL, 'v' }, { "version", no_argument, NULL, 'V' }, { "xip", no_argument, NULL, 'x' }, + { "load-only", no_argument, NULL, OPT_LOAD_ONLY }, { /* sentinel */ }, }; @@ -360,6 +365,9 @@ static int process_args(struct imgtool *itl, int argc, char **argv) case 'x': itl->xflag++; break; + case OPT_LOAD_ONLY: + itl->load_only = true; + break; default: return usage(itl, "Invalid option"); } @@ -390,7 +398,7 @@ static int process_args(struct imgtool *itl, int argc, char **argv) /* For auto-FIT, datafile has to be provided with -d */ if (!itl->auto_fit) itl->datafile = datafile; - else if (!itl->datafile) + else if (!itl->datafile && type != IH_TYPE_FLATDT) return usage(itl, "Missing data file for auto-FIT (use -d)"); } else if (itl->lflag || type != IH_TYPE_INVALID) { -- 2.43.0