All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Glass <sjg@chromium.org>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 20/26] mkimage: Support placing data outside the FIT
Date: Thu, 28 Jan 2016 09:39:40 -0700	[thread overview]
Message-ID: <1453999186-18747-21-git-send-email-sjg@chromium.org> (raw)
In-Reply-To: <1453999186-18747-1-git-send-email-sjg@chromium.org>

One limitation of FIT is that all the data is 'inline' within it, using a
'data' property in each image node. This means that to find out what is in
the FIT it is necessary to scan the entire file. Once loaded it can be
scanned and then the images can be copied to the correct place in memory.

In SPL it can take a significant amount of time to copy images around in
memory. Also loading data that does not end up being used is wasteful. It
would be useful if the FIT were small, acting as a directory, with the
actual data stored elsewhere.

This allows SPL to load the entire FIT, without the images, then load the
images it wants later.

Add a -E option to mkimage to request that it output an 'external' FIT.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 doc/mkimage.1                         |   9 +++
 doc/uImage.FIT/source_file_format.txt |  20 ++++++-
 tools/fit_image.c                     | 109 ++++++++++++++++++++++++++++++++++
 tools/imagetool.h                     |   1 +
 tools/mkimage.c                       |   5 +-
 5 files changed, 142 insertions(+), 2 deletions(-)

diff --git a/doc/mkimage.1 b/doc/mkimage.1
index b1b45d7..d9ffc75 100644
--- a/doc/mkimage.1
+++ b/doc/mkimage.1
@@ -112,6 +112,15 @@ Provide special options to the device tree compiler that is used to
 create the image.
 
 .TP
+.BI "\-E
+After processing, move the image data outside the FIT and store a data offset
+in the FIT. Images will be placed one after the other immediately after the
+FIT, with each one aligned to a 4-byte boundary. The existing 'data' property
+in each image will be replaced with 'data-offset' and 'data-size' properties.
+A 'data-offset' of 0 indicates that it starts in the first (4-byte aligned)
+byte after the FIT.
+
+.TP
 .BI "\-f [" "image tree source file" " | " "auto" "]"
 Image tree source file that describes the structure and contents of the
 FIT image.
diff --git a/doc/uImage.FIT/source_file_format.txt b/doc/uImage.FIT/source_file_format.txt
index 029f481..e39b38c 100644
--- a/doc/uImage.FIT/source_file_format.txt
+++ b/doc/uImage.FIT/source_file_format.txt
@@ -2,6 +2,7 @@ U-boot new uImage source file format (bindings definition)
 ==========================================================
 
 Author: Marian Balakowicz <m8@semihalf.com>
+External data additions, 25/1/16 Simon Glass <sjg@chromium.org>
 
 1) Introduction
 ---------------
@@ -262,7 +263,24 @@ Older, 2.4 kernel and 2.6 non-FDT kernel do not use FDT blob, in such cases
 not* be specified in a configuration node.
 
 
-8) Examples
+8) External data
+----------------
+
+The above format shows a 'data' property which holds the data for each image.
+It is also possible for this data to reside outside the FIT itself. This
+allows the FIT to be quite small, so that it can be loaded and scanned
+without loading a large amount of data. Then when an image is needed it can
+be loaded from an external source.
+
+In this case the 'data' property is omitted. Instead you can use:
+
+  - data-offset : offset of the data in a separate image store. The image
+    store is placed immediately after the last byte of the device tree binary,
+    aligned to a 4-byte boundary.
+  - data-size : size of the data in bytes
+
+
+9) Examples
 -----------
 
 Please see doc/uImage.FIT/*.its for actual image source files.
diff --git a/tools/fit_image.c b/tools/fit_image.c
index 0d8007b..5d087e3 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 5e2e7e1..74bb9b6 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -137,7 +137,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:Fik:K:ln:O:rR:sT:vVx")) != -1) {
+			     "-a:A:bcC:d:D:e:Ef:Fik:K:ln:O:rR:sT:vVx")) != -1) {
 		switch (opt) {
 		case 'a':
 			params.addr = strtoul(optarg, &ptr, 16);
@@ -179,6 +179,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");
-- 
2.7.0.rc3.207.g0ac5344

  parent reply	other threads:[~2016-01-28 16:39 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-28 16:39 [U-Boot] [PATCH 00/26] spl: Support loading a FIT image containing U-Boot Simon Glass
2016-01-28 16:39 ` Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 01/26] mkimage: Move argument processing into its own function Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 02/26] mkimage: Convert to use getopt() Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 03/26] mkimage: Sort the option processing code by option Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 04/26] mkimage: Move usage() up to the top Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 05/26] mkimage: Show an error message when usage() is called Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 06/26] mkimage: Make 'params' static Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 07/26] libfdt: Add a function to write a property placeholder Simon Glass
2016-01-28 16:39   ` Simon Glass
2016-01-29  5:29   ` [U-Boot] " David Gibson
2016-01-29  5:29     ` David Gibson
2016-01-29 18:23     ` [U-Boot] " Simon Glass
2016-01-29 18:23       ` Simon Glass
2016-01-31  9:55       ` [U-Boot] " David Gibson
2016-01-31  9:55         ` David Gibson
2016-01-28 16:39 ` [U-Boot] [PATCH 08/26] Correct defconfig ordering Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 09/26] Move CONFIG_OF_LIBFDT to Kconfig Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 10/26] Kconfig: Move CONFIG_FIT and CONFIG_OF_*_SETUP " Simon Glass
2016-01-29  5:52   ` Heiko Schocher
2016-01-28 16:39 ` [U-Boot] [PATCH 11/26] fdt: Adjust DEFAULT_DEVICE_TREE to device on OF_CONTROL Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 12/26] fdt: Allow libfdt to be used in SPL Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 13/26] sunxi: Display the board model on start-up Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 14/26] tools: Include fdt_sw.o in libfdt for mkimage Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 15/26] mkimage: Allow a FIT to include an image of any type Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 16/26] tools: Add a function to obtain the size of a file Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 17/26] image: Add functions to obtain short names Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 18/26] mkimage: Support automatic creating of a FIT without a .its Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 19/26] mkimage: Support adding device tree files to a FIT Simon Glass
2016-02-11 16:36   ` Tom Rini
2016-02-12 15:54     ` Simon Glass
2016-02-12 16:03       ` Tom Rini
2016-01-28 16:39 ` Simon Glass [this message]
2016-01-28 16:39 ` [U-Boot] [PATCH 21/26] mkimage: Bring data into the FIT before processing Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 22/26] spl: Add a way for boards to select which device tree to load Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 23/26] spl: Add an option to load a FIT containing U-Boot Simon Glass
2016-02-04 15:00   ` Stefano Babic
2016-02-22  4:46     ` Simon Glass
2016-02-22  6:45       ` Stefano Babic
2016-01-28 16:39 ` [U-Boot] [PATCH 24/26] spl: Add a way to specify a list of device trees to include Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 25/26] spl: Support loading a FIT from MMC Simon Glass
2016-01-28 16:39 ` [U-Boot] [PATCH 26/26] RFC: sunxi: Enable SPL FIT support Simon Glass
2016-02-16 11:34 ` [U-Boot] [PATCH 00/26] spl: Support loading a FIT image containing U-Boot Masahiro Yamada
2016-02-16 11:34   ` Masahiro Yamada
2016-02-16 12:17   ` [U-Boot] " Tom Rini
2016-02-16 12:17     ` Tom Rini
2016-02-16 12:30     ` Masahiro Yamada
2016-02-16 12:30       ` Masahiro Yamada
2016-02-16 13:33       ` Tom Rini
2016-02-16 13:33         ` Tom Rini
2016-02-17 11:00 ` Belisko Marek
2016-02-17 11:00   ` Belisko Marek
2016-02-19 20:55   ` Simon Glass
2016-02-19 20:55     ` Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1453999186-18747-21-git-send-email-sjg@chromium.org \
    --to=sjg@chromium.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.