Unless specified otherwise using the mkimage -B n option, align DTs in fitImage external data to 8 Bytes, and retain alignment of everything else to 4 Bytes. This should fulfill the DTspec requirement, that DTs must be placed at 8 Byte aligned addresses, even for DTs that are part of fitImage with external data. For fitImage with embedded data, there is nothing we can do, as the embedded data are aligned to 4 Bytes, just like any other DT property.
Replace fdtdec_get_child_count() counting of images with counting of padding using fdt_for_each_subnode(). This is much more useful, as the added up padding can be passed directly to calloc() when allocating the buffer which holds the external data. The image count is no longer needed. Adjust the image layouting such, that buf_ptr is incremented to place the next image at align_size aligned offset. This is done at the beginning of the loop, once the align_size for current image can be determined from the current image type. Update binman test to validate the new 8 Byte alignment. Signed-off-by: Marek Vasut <[email protected]> --- Cc: Alper Nebi Yasak <[email protected]> Cc: Anshul Dalal <[email protected]> Cc: Aristo Chen <[email protected]> Cc: Beleswar Padhi <[email protected]> Cc: Bryan Brattlof <[email protected]> Cc: Paul HENRYS <[email protected]> Cc: Quentin Schulz <[email protected]> Cc: Rasmus Villemoes <[email protected]> Cc: Simon Glass <[email protected]> Cc: Tom Rini <[email protected]> Cc: Wolfgang Wallner <[email protected]> Cc: Yannic Moog <[email protected]> --- tools/binman/ftest.py | 20 +++++++-------- tools/fit_image.c | 58 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 22 deletions(-) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 21ec48d86fd..a53e37f31b3 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -4073,7 +4073,7 @@ class TestFunctional(unittest.TestCase): external_data_size = len(U_BOOT_DATA) + 2 expected_size = (len(U_BOOT_DATA) + 0x400 + tools.align(external_data_size, 4) + - len(U_BOOT_NODTB_DATA)) + len(U_BOOT_NODTB_DATA) + 8) # The data should be outside the FIT dtb = fdt.Fdt.FromData(fit_data) @@ -4089,8 +4089,8 @@ class TestFunctional(unittest.TestCase): self.assertEqual(expected_size, len(data)) actual_pos = len(U_BOOT_DATA) + fit_pos - self.assertEqual(U_BOOT_DATA + b'aa', - data[actual_pos:actual_pos + external_data_size]) + self.assertEqual(U_BOOT_DATA + b'\x00\x00\x00\x00aa', + data[actual_pos:actual_pos + 4 + external_data_size]) def testFitExternalImagePos(self): """Test that we have correct image-pos for external FIT subentries""" @@ -4103,13 +4103,13 @@ class TestFunctional(unittest.TestCase): self.assertEqual({ 'image-pos': 0, 'offset': 0, - 'size': 1082, + 'size': 1090, 'u-boot:image-pos': 0, 'u-boot:offset': 0, 'u-boot:size': 4, - 'fit:size': 1032, + 'fit:size': 1040, 'fit:offset': 4, 'fit:image-pos': 4, @@ -4122,15 +4122,15 @@ class TestFunctional(unittest.TestCase): 'fit/images/kernel/u-boot:image-pos': 1028, 'fit/images/fdt-1:size': 2, - 'fit/images/fdt-1:offset': 1028, - 'fit/images/fdt-1:image-pos': 1032, + 'fit/images/fdt-1:offset': 1032, + 'fit/images/fdt-1:image-pos': 1036, 'fit/images/fdt-1/_testing:size': 2, 'fit/images/fdt-1/_testing:offset': 0, - 'fit/images/fdt-1/_testing:image-pos': 1032, + 'fit/images/fdt-1/_testing:image-pos': 1036, - 'u-boot-nodtb:image-pos': 1036, - 'u-boot-nodtb:offset': 1036, + 'u-boot-nodtb:image-pos': 1044, + 'u-boot-nodtb:offset': 1044, 'u-boot-nodtb:size': 46, }, props) diff --git a/tools/fit_image.c b/tools/fit_image.c index e865f65a400..1dbc14c63e4 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -651,10 +651,9 @@ 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; + int align_size = 0; + int len = 0; - 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; @@ -666,24 +665,58 @@ static int fit_extract_data(struct image_tool_params *params, const char *fname) ret = -EINVAL; goto err_munmap; } - image_number = fdtdec_get_child_count(fdt, images); + + /* Add up all the alignments, we no longer need to count images. */ + fdt_for_each_subnode(node, fdt, images) { + const char *type; + int len; + + if (params->bl_len) { + align_size += params->bl_len; + continue; + } + + type = fdt_getprop(fdt, node, FIT_TYPE_PROP, &len); + if (type && len == sizeof("flat_dt") && !memcmp(type, "flat_dt", len)) { + align_size += 8; + continue; + } + + /* Default alignment to 4 Bytes */ + align_size += 4; + } /* * Allocate space to hold the image data we will extract, * extral space allocate for image alignment to prevent overflow. */ - buf = calloc(1, fit_size + (align_size * image_number)); + buf = calloc(1, fit_size + align_size); if (!buf) { ret = -ENOMEM; goto err_munmap; } buf_ptr = 0; - for (node = fdt_first_subnode(fdt, images); - node >= 0; - node = fdt_next_subnode(fdt, node)) { - const char *data; - int len; + fdt_for_each_subnode(node, fdt, images) { + const char *data, *type; + int pl; + + if (params->bl_len) { + align_size = params->bl_len; + } else { + type = fdt_getprop(fdt, node, FIT_TYPE_PROP, &pl); + if (type && pl == sizeof("flat_dt") && !memcmp(type, "flat_dt", pl)) + align_size = 8; + else /* Default alignment to 4 Bytes */ + align_size = 4; + } + + /* + * The 'len' is 0 in the first round, so 'buf_ptr' is + * not incremented. Otherwise, 'len' is passed over + * from the previous round. + */ + buf_ptr += ALIGN(len, align_size); data = fdt_getprop(fdt, node, FIT_DATA_PROP, &len); if (!data) @@ -716,10 +749,11 @@ static int fit_extract_data(struct image_tool_params *params, const char *fname) ret = -EINVAL; goto err_munmap; } - - buf_ptr += ALIGN(len, align_size); } + /* Increment 'buf_ptr' for the trailing image. */ + buf_ptr += ALIGN(len, align_size); + /* Pack the FDT and place the data after it */ fdt_pack(fdt); -- 2.51.0

