mkimage: Bring data into the FIT before processing
authorSimon Glass <sjg@chromium.org>
Tue, 23 Feb 2016 05:55:54 +0000 (22:55 -0700)
committerTom Rini <trini@konsulko.com>
Mon, 14 Mar 2016 23:18:30 +0000 (19:18 -0400)
Since we now support data outside the FIT image, bring it into the FIT image
first before we do any processing. This avoids adding new functionality to
the core FIT code for now.

Signed-off-by: Simon Glass <sjg@chromium.org>
tools/fit_image.c

index 06b561d..3ecc88f 100644 (file)
@@ -455,6 +455,98 @@ err:
        return ret;
 }
 
+static int fit_import_data(struct image_tool_params *params, const char *fname)
+{
+       void *fdt, *old_fdt;
+       int fit_size, new_size, size, data_base;
+       int fd;
+       struct stat sbuf;
+       int ret;
+       int images;
+       int node;
+
+       fd = mmap_fdt(params->cmdname, fname, 0, &old_fdt, &sbuf, false);
+       if (fd < 0)
+               return -EIO;
+       fit_size = fdt_totalsize(old_fdt);
+       data_base = (fit_size + 3) & ~3;
+
+       /* Allocate space to hold the new FIT */
+       size = sbuf.st_size + 16384;
+       fdt = malloc(size);
+       if (!fdt) {
+               fprintf(stderr, "%s: Failed to allocate memory (%d bytes)\n",
+                       __func__, size);
+               ret = -ENOMEM;
+               goto err;
+       }
+       ret = fdt_open_into(old_fdt, fdt, size);
+       if (ret) {
+               debug("%s: Failed to expand FIT: %s\n", __func__,
+                     fdt_strerror(errno));
+               ret = -EINVAL;
+               goto err;
+       }
+
+       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)) {
+               int buf_ptr;
+               int len;
+
+               buf_ptr = fdtdec_get_int(fdt, node, "data-offset", -1);
+               len = fdtdec_get_int(fdt, node, "data-size", -1);
+               if (buf_ptr == -1 || len == -1)
+                       continue;
+               debug("Importing data size %x\n", len);
+
+               ret = fdt_setprop(fdt, node, "data", fdt + data_base + buf_ptr,
+                                 len);
+               if (ret) {
+                       debug("%s: Failed to write property: %s\n", __func__,
+                             fdt_strerror(ret));
+                       ret = -EINVAL;
+                       goto err;
+               }
+       }
+
+       munmap(fdt, sbuf.st_size);
+       close(fd);
+
+       /* Pack the FDT and place the data after it */
+       fdt_pack(fdt);
+
+       new_size = fdt_totalsize(fdt);
+       debug("Size expanded from %x to %x\n", fit_size, new_size);
+
+       fd = open(fname, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0666);
+       if (fd < 0) {
+               fprintf(stderr, "%s: Can't open %s: %s\n",
+                       params->cmdname, fname, strerror(errno));
+               goto err;
+       }
+       if (write(fd, fdt, new_size) != new_size) {
+               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
  *
@@ -510,6 +602,11 @@ static int fit_handle_file(struct image_tool_params *params)
                goto err_system;
        }
 
+       /* Move the data so it is internal to the FIT, if needed */
+       ret = fit_import_data(params, tmpfile);
+       if (ret)
+               goto err_system;
+
        /*
         * Set hashes for images in the blob. Unfortunately we may need more
         * space in either FDT, so keep trying until we succeed.