[PATCH v2] mkimage: fit_image: Make fit header and data align to 512
Punit Agrawal
punit1.agrawal at toshiba.co.jp
Mon Mar 16 08:28:45 CET 2020
Kever Yang <kever.yang at rock-chips.com> writes:
> The image is usually stored in block device like emmc, SD card, make the
> offset of image data aligned to block(512 byte) can avoid data copy
> during boot process.
> eg. SPL boot from FIT image with external data:
> - SPL read the first block of FIT image, and then parse the header;
> - SPL read image data separately;
> - The first image offset is the base_offset which is the header size;
> - The second image offset is just after the first image;
> - If the offset of imge does not aligned, SPL will do memcpy;
> The header size is a ramdon number, which is very possible not aligned, so
> add '-B' to specify the align size in hex for better performance.
>
> example usage:
> ./tools/mkimage -E -f u-boot.its -B 200 u-boot.itb
>
> Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
> ---
>
> Changes in v2:
> - use '-B' to take a argument as a align block lenth;
> - address commens from Heinrich, Rasmus, Tom, Punit;
>
> doc/uImage.FIT/source_file_format.txt | 5 +++++
> tools/fit_image.c | 26 ++++++++++++++++++++------
> tools/imagetool.h | 1 +
> tools/mkimage.c | 14 ++++++++++++--
> 4 files changed, 38 insertions(+), 8 deletions(-)
>
[...]
> diff --git a/tools/fit_image.c b/tools/fit_image.c
> index 6aa4b1c733..6fa2ce328a 100644
> --- a/tools/fit_image.c
> +++ b/tools/fit_image.c
> @@ -23,6 +23,11 @@
>
> static image_header_t header;
>
> +static int get_aligned_size(int size, int aligned_size)
> +{
> + return ((size + aligned_size - 1) & ~(aligned_size - 1));
> +}
> +
Instead of adding another copy of this code (versions of it already
exist in imx8mimage.c, ifwitool.c, aisiamge.c), it would be better to
move the below snippet to imagetool.h.
#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
#define ALIGN(x, a) __ALIGN_MASK((x), (typeof(x))(a) - 1)
With this, you can drop the version in imx8mimage.c which seems to
introduce an unnecessary multiplication / division.
> static int fit_add_file_data(struct image_tool_params *params, size_t size_inc,
> const char *tmpfile)
> {
> @@ -430,8 +435,11 @@ static int fit_extract_data(struct image_tool_params *params, const char *fname)
> return -EIO;
> fit_size = fdt_totalsize(fdt);
>
> - /* Allocate space to hold the image data we will extract */
> - buf = malloc(fit_size);
> + /*
> + * Allocate space to hold the image data we will extract,
> + * 4096 byte extral space allocate for image alignment.
> + */
> + buf = malloc(fit_size + 4096);
I might be missing something but shouldn't the extra allocation depend
on -
* block size
* number of data objects in the FIT
> if (!buf) {
> ret = -ENOMEM;
> goto err_munmap;
> @@ -471,17 +479,23 @@ 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;
> + if (params->bl_len > 0)
> + buf_ptr += get_aligned_size(len, params->bl_len);
> + else
> + buf_ptr += get_aligned_size(len, 4);
> }
>
> /* Pack the FDT and place the data after it */
> fdt_pack(fdt);
>
> + new_size = fdt_totalsize(fdt);
> + if (params->bl_len > 0)
> + new_size = get_aligned_size(new_size, params->bl_len);
> + else
> + new_size = get_aligned_size(new_size, 4);
This condition gets duplicated here and in the loop above. It would be
better to introduce a variable to track alignment requirement (4 or
bl_len) at the start of the function and use them in both places.
What do you think?
Thanks,
Punit
> + 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)) {
> diff --git a/tools/imagetool.h b/tools/imagetool.h
> index e1c778b0df..fd5e4b246c 100644
> --- a/tools/imagetool.h
> +++ b/tools/imagetool.h
> @@ -76,6 +76,7 @@ struct image_tool_params {
> bool external_data; /* Store data outside the FIT */
> bool quiet; /* Don't output text in normal operation */
> unsigned int external_offset; /* Add padding to external data */
> + int bl_len; /* Block length in byte for external data */
> const char *engine_id; /* Engine to use for signing */
> };
>
> diff --git a/tools/mkimage.c b/tools/mkimage.c
> index 5f51d2cc89..584aeff907 100644
> --- a/tools/mkimage.c
> +++ b/tools/mkimage.c
> @@ -97,8 +97,9 @@ static void usage(const char *msg)
> " -i => input filename for ramdisk file\n");
> #ifdef CONFIG_FIT_SIGNATURE
> fprintf(stderr,
> - "Signing / verified boot options: [-E] [-k keydir] [-K dtb] [ -c <comment>] [-p addr] [-r] [-N engine]\n"
> + "Signing / verified boot options: [-E] [-B] [-k keydir] [-K dtb] [ -c <comment>] [-p addr] [-r] [-N engine]\n"
> " -E => place data outside of the FIT structure\n"
> + " -B => align FIT structure and header to block\n"
> " -k => set directory containing private keys\n"
> " -K => write public keys to this .dtb file\n"
> " -c => add comment in signature node\n"
> @@ -143,7 +144,7 @@ static void process_args(int argc, char **argv)
> int opt;
>
> while ((opt = getopt(argc, argv,
> - "a:A:b:c:C:d:D:e:Ef:Fk:i:K:ln:N:p:O:rR:qsT:vVx")) != -1) {
> + "a:A:b:B:c:C:d:D:e:Ef:Fk:i:K:ln:N:p:O:rR:qsT:vVx")) != -1) {
> switch (opt) {
> case 'a':
> params.addr = strtoull(optarg, &ptr, 16);
> @@ -167,6 +168,15 @@ static void process_args(int argc, char **argv)
> params.cmdname, optarg);
> exit(EXIT_FAILURE);
> }
> + break;
> + case 'B':
> + params.bl_len = strtoull(optarg, &ptr, 16);
> + if (*ptr) {
> + fprintf(stderr, "%s: invalid block length %s\n",
> + params.cmdname, optarg);
> + exit(EXIT_FAILURE);
> + }
> +
> break;
> case 'c':
> params.comment = optarg;
More information about the U-Boot
mailing list