env: Kconfig: cosmetics: update comment for SYS_RELOC_GD_ENV_ADDR
[oweals/u-boot.git] / tools / fit_image.c
index 55efe12eeb8356fa2f12ae47df197c71e27e3ad9..a082d9386d200d095753eae45fec826b1a718269 100644 (file)
@@ -17,6 +17,7 @@
 #include "fit_common.h"
 #include "mkimage.h"
 #include <image.h>
+#include <string.h>
 #include <stdarg.h>
 #include <version.h>
 #include <u-boot/crc.h>
@@ -110,7 +111,7 @@ static int fit_calc_size(struct image_tool_params *params)
                if (size < 0)
                        return -1;
 
-               /* Add space for properties */
+               /* Add space for properties and hash node */
                total_size += size + 300;
        }
 
@@ -191,6 +192,18 @@ static void get_basename(char *str, int size, const char *fname)
        str[len] = '\0';
 }
 
+/**
+ * add_crc_node() - Add a hash node to request a CRC checksum for an image
+ *
+ * @fdt: Device tree to add to (in sequential-write mode)
+ */
+static void add_crc_node(void *fdt)
+{
+       fdt_begin_node(fdt, "hash-1");
+       fdt_property_string(fdt, FIT_ALGO_PROP, "crc32");
+       fdt_end_node(fdt);
+}
+
 /**
  * fit_write_images() - Write out a list of images to the FIT
  *
@@ -229,6 +242,7 @@ static int fit_write_images(struct image_tool_params *params, char *fdt)
        ret = fdt_property_file(params, fdt, FIT_DATA_PROP, params->datafile);
        if (ret)
                return ret;
+       add_crc_node(fdt);
        fdt_end_node(fdt);
 
        /* Now the device tree files if available */
@@ -251,6 +265,7 @@ static int fit_write_images(struct image_tool_params *params, char *fdt)
                                    genimg_get_arch_short_name(params->arch));
                fdt_property_string(fdt, FIT_COMP_PROP,
                                    genimg_get_comp_short_name(IH_COMP_NONE));
+               add_crc_node(fdt);
                fdt_end_node(fdt);
        }
 
@@ -268,7 +283,7 @@ static int fit_write_images(struct image_tool_params *params, char *fdt)
                                        params->fit_ramdisk);
                if (ret)
                        return ret;
-
+               add_crc_node(fdt);
                fdt_end_node(fdt);
        }
 
@@ -422,7 +437,7 @@ err_buf:
  */
 static int fit_extract_data(struct image_tool_params *params, const char *fname)
 {
-       void *buf;
+       void *buf = NULL;
        int buf_ptr;
        int fit_size, new_size;
        int fd;
@@ -431,26 +446,33 @@ static int fit_extract_data(struct image_tool_params *params, const char *fname)
        int ret;
        int images;
        int node;
+       int image_number;
+       int align_size;
 
+       align_size = params->bl_len ? params->bl_len : 4;
        fd = mmap_fdt(params->cmdname, fname, 0, &fdt, &sbuf, false, 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_munmap;
-       }
-       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_munmap;
        }
+       image_number = fdtdec_get_child_count(fdt, images);
+
+       /*
+        * Allocate space to hold the image data we will extract,
+        * extral space allocate for image alignment to prevent overflow.
+        */
+       buf = malloc(fit_size + (align_size * image_number));
+       if (!buf) {
+               ret = -ENOMEM;
+               goto err_munmap;
+       }
+       buf_ptr = 0;
 
        for (node = fdt_first_subnode(fdt, images);
             node >= 0;
@@ -478,17 +500,17 @@ static int fit_extract_data(struct image_tool_params *params, const char *fname)
                                        buf_ptr);
                }
                fdt_setprop_u32(fdt, node, FIT_DATA_SIZE_PROP, len);
-
-               buf_ptr += (len + 3) & ~3;
+               buf_ptr += ALIGN(len, align_size);
        }
 
        /* Pack the FDT and place the data after it */
        fdt_pack(fdt);
 
+       new_size = fdt_totalsize(fdt);
+       new_size = ALIGN(new_size, align_size);
+       fdt_set_totalsize(fdt, new_size);
        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)) {
@@ -527,8 +549,7 @@ static int fit_extract_data(struct image_tool_params *params, const char *fname)
 err_munmap:
        munmap(fdt, sbuf.st_size);
 err:
-       if (buf)
-               free(buf);
+       free(buf);
        close(fd);
        return ret;
 }
@@ -556,21 +577,21 @@ static int fit_import_data(struct image_tool_params *params, const char *fname)
                fprintf(stderr, "%s: Failed to allocate memory (%d bytes)\n",
                        __func__, size);
                ret = -ENOMEM;
-               goto err_has_fd;
+               goto err_munmap;
        }
        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_has_fd;
+               goto err_munmap;
        }
 
        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_has_fd;
+               goto err_munmap;
        }
 
        for (node = fdt_first_subnode(fdt, images);
@@ -591,10 +612,12 @@ static int fit_import_data(struct image_tool_params *params, const char *fname)
                        debug("%s: Failed to write property: %s\n", __func__,
                              fdt_strerror(ret));
                        ret = -EINVAL;
-                       goto err_has_fd;
+                       goto err_munmap;
                }
        }
 
+       munmap(old_fdt, sbuf.st_size);
+
        /* Close the old fd so we can re-use it. */
        close(fd);
 
@@ -609,22 +632,24 @@ static int fit_import_data(struct image_tool_params *params, const char *fname)
                fprintf(stderr, "%s: Can't open %s: %s\n",
                        params->cmdname, fname, strerror(errno));
                ret = -EIO;
-               goto err_no_fd;
+               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_has_fd;
+               goto err;
        }
 
-       ret = 0;
-
-err_has_fd:
+       free(fdt);
        close(fd);
-err_no_fd:
+       return 0;
+
+err_munmap:
        munmap(old_fdt, sbuf.st_size);
+err:
        free(fdt);
+       close(fd);
        return ret;
 }
 
@@ -734,6 +759,9 @@ static int fit_handle_file(struct image_tool_params *params)
                snprintf(cmd, sizeof(cmd), "cp \"%s\" \"%s\"",
                         params->imagefile, tmpfile);
        }
+       if (strlen(cmd) >= MKIMAGE_MAX_DTC_CMDLINE_LEN - 1) {
+               fprintf(stderr, "WARNING: command-line for FIT creation might be truncated and will probably fail.\n");
+       }
 
        if (*cmd && system(cmd) == -1) {
                fprintf (stderr, "%s: system(%s) failed: %s\n",