]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
mkimage: fit: align DTs in external data to 8 Bytes by default
authorMarek Vasut <marek.vasut+renesas@mailbox.org>
Thu, 29 Jan 2026 03:53:29 +0000 (04:53 +0100)
committerTom Rini <trini@konsulko.com>
Mon, 2 Feb 2026 15:15:52 +0000 (09:15 -0600)
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>
tools/binman/ftest.py
tools/fit_image.c

index 21ec48d86fd154422c92657eafeeea5ec74836dd..a53e37f31b3e2ab85b9277f4e3940b106b3e7574 100644 (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)
 
index e865f65a400abf8abc983e49585b93e611b29a46..1dbc14c63e4879f2d4e5ea485b2faac142fc7ee2 100644 (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);