mkimage: fit: align DTs in external data to 8 Bytes by default

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 <marek.vasut+renesas@mailbox.org>
This commit is contained in:
Marek Vasut
2026-01-29 04:53:29 +01:00
committed by Tom Rini
parent 8bca63d2ed
commit 22129bf473
2 changed files with 56 additions and 22 deletions

View File

@@ -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)

View File

@@ -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);