mkimage: Support a load-only FIT

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>
This commit is contained in:
Simon Glass
2025-08-02 06:46:23 +12:00
parent 449c65e028
commit 037a9c0b7f
4 changed files with 71 additions and 31 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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) {