diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/fit_image.c | 109 | ||||
-rw-r--r-- | tools/imagetool.h | 1 | ||||
-rw-r--r-- | tools/mkimage.c | 5 |
3 files changed, 114 insertions, 1 deletions
diff --git a/tools/fit_image.c b/tools/fit_image.c index 765ff31..06b561d 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -354,6 +354,108 @@ err: } /** + * fit_extract_data() - Move all data outside the FIT + * + * This takes a normal FIT file and removes all the 'data' properties from it. + * The data is placed in an area after the FIT so that it can be accessed + * using an offset into that area. The 'data' properties turn into + * 'data-offset' properties. + * + * This function cannot cope with FITs with 'data-offset' properties. All + * data must be in 'data' properties on entry. + */ +static int fit_extract_data(struct image_tool_params *params, const char *fname) +{ + void *buf; + int buf_ptr; + int fit_size, new_size; + int fd; + struct stat sbuf; + void *fdt; + int ret; + int images; + int node; + + fd = mmap_fdt(params->cmdname, fname, 0, &fdt, &sbuf, false); + if (fd < 0) + return -EIO; + fit_size = fdt_totalsize(fdt); + + /* Allocate space to hold the image data we will extract */ + buf = malloc(fit_size); + if (!buf) { + ret = -ENOMEM; + goto err; + } + buf_ptr = 0; + + images = fdt_path_offset(fdt, FIT_IMAGES_PATH); + if (images < 0) { + debug("%s: Cannot find /images node: %d\n", __func__, images); + ret = -EINVAL; + goto err; + } + + for (node = fdt_first_subnode(fdt, images); + node >= 0; + node = fdt_next_subnode(fdt, node)) { + const char *data; + int len; + + data = fdt_getprop(fdt, node, "data", &len); + if (!data) + continue; + memcpy(buf + buf_ptr, data, len); + debug("Extracting data size %x\n", len); + + ret = fdt_delprop(fdt, node, "data"); + if (ret) { + ret = -EPERM; + goto err; + } + fdt_setprop_u32(fdt, node, "data-offset", buf_ptr); + fdt_setprop_u32(fdt, node, "data-size", len); + + buf_ptr += (len + 3) & ~3; + } + + /* Pack the FDT and place the data after it */ + fdt_pack(fdt); + + debug("Size reduced from %x to %x\n", fit_size, fdt_totalsize(fdt)); + debug("External data size %x\n", buf_ptr); + new_size = fdt_totalsize(fdt); + new_size = (new_size + 3) & ~3; + munmap(fdt, sbuf.st_size); + + if (ftruncate(fd, new_size)) { + debug("%s: Failed to truncate file: %s\n", __func__, + strerror(errno)); + ret = -EIO; + goto err; + } + if (lseek(fd, new_size, SEEK_SET) < 0) { + debug("%s: Failed to seek to end of file: %s\n", __func__, + strerror(errno)); + ret = -EIO; + goto err; + } + if (write(fd, buf, buf_ptr) != buf_ptr) { + debug("%s: Failed to write external data to file %s\n", + __func__, strerror(errno)); + ret = -EIO; + goto err; + } + close(fd); + + ret = 0; + +err: + close(fd); + return ret; +} + +/** * fit_handle_file - main FIT file processing function * * fit_handle_file() runs dtc to convert .its to .itb, includes @@ -430,6 +532,13 @@ static int fit_handle_file(struct image_tool_params *params) goto err_system; } + /* Move the data so it is external to the FIT, if requested */ + if (params->external_data) { + ret = fit_extract_data(params, tmpfile); + if (ret) + goto err_system; + } + if (rename (tmpfile, params->imagefile) == -1) { fprintf (stderr, "%s: Can't rename %s to %s: %s\n", params->cmdname, tmpfile, params->imagefile, diff --git a/tools/imagetool.h b/tools/imagetool.h index 3d30fbe..24f8f4b 100644 --- a/tools/imagetool.h +++ b/tools/imagetool.h @@ -72,6 +72,7 @@ struct image_tool_params { int fit_image_type; /* Image type to put into the FIT */ struct content_info *content_head; /* List of files to include */ struct content_info *content_tail; + bool external_data; /* Store data outside the FIT */ }; /* diff --git a/tools/mkimage.c b/tools/mkimage.c index 22fab1d..2931783 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -138,7 +138,7 @@ static void process_args(int argc, char **argv) expecting = IH_TYPE_COUNT; /* Unknown */ while ((opt = getopt(argc, argv, - "-a:A:bcC:d:D:e:f:Fk:K:ln:O:rR:sT:vVx")) != -1) { + "-a:A:bcC:d:D:e:Ef:Fk:K:ln:O:rR:sT:vVx")) != -1) { switch (opt) { case 'a': params.addr = strtoull(optarg, &ptr, 16); @@ -180,6 +180,9 @@ static void process_args(int argc, char **argv) } params.eflag = 1; break; + case 'E': + params.external_data = true; + break; case 'f': datafile = optarg; params.auto_its = !strcmp(datafile, "auto"); |