binman: Add 'min-size' entry property
authorSamuel Holland <samuel@sholland.org>
Sat, 21 Jan 2023 23:25:16 +0000 (17:25 -0600)
committerSimon Glass <sjg@chromium.org>
Thu, 26 Jan 2023 17:47:45 +0000 (10:47 -0700)
This property sets the minimum size of an entry, including padding but
not alignment. It can be used to reserve space for growth of an entry,
or to enforce a minimum offset for later entries in the section.

Signed-off-by: Samuel Holland <samuel@sholland.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
tools/binman/binman.rst
tools/binman/entry.py
tools/binman/ftest.py
tools/binman/test/009_pack_extra.dts

index fa8abdc..03a99a1 100644 (file)
@@ -615,6 +615,14 @@ size:
     this size. If this is not provided, it will be set to the size of the
     contents.
 
+min-size:
+    Sets the minimum size of the entry. This size includes explicit padding
+    ('pad-before' and 'pad-after'), but not padding added to meet alignment
+    requirements. While this does not affect the contents of the entry within
+    binman itself (the padding is performed only when its parent section is
+    assembled), the end result will be that the entry ends with the padding
+    bytes, so may grow. Defaults to 0.
+
 pad-before:
     Padding before the contents of the entry. Normally this is 0, meaning
     that the contents start at the beginning of the entry. This can be used
index 5d8696e..5eacc5f 100644 (file)
@@ -49,6 +49,7 @@ class Entry(object):
         offset: Offset of entry within the section, None if not known yet (in
             which case it will be calculated by Pack())
         size: Entry size in bytes, None if not known
+        min_size: Minimum entry size in bytes
         pre_reset_size: size as it was before ResetForPack(). This allows us to
             keep track of the size we started with and detect size changes
         uncomp_size: Size of uncompressed data in bytes, if the entry is
@@ -114,6 +115,7 @@ class Entry(object):
         self.name = node and (name_prefix + node.name) or 'none'
         self.offset = None
         self.size = None
+        self.min_size = 0
         self.pre_reset_size = None
         self.uncomp_size = None
         self.data = None
@@ -270,6 +272,7 @@ class Entry(object):
             self.Raise("Please use 'extend-size' instead of 'expand-size'")
         self.offset = fdt_util.GetInt(self._node, 'offset')
         self.size = fdt_util.GetInt(self._node, 'size')
+        self.min_size = fdt_util.GetInt(self._node, 'min-size', 0)
         self.orig_offset = fdt_util.GetInt(self._node, 'orig-offset')
         self.orig_size = fdt_util.GetInt(self._node, 'orig-size')
         if self.GetImage().copy_to_orig:
@@ -507,6 +510,7 @@ class Entry(object):
             else:
                 self.offset = tools.align(offset, self.align)
         needed = self.pad_before + self.contents_size + self.pad_after
+        needed = max(needed, self.min_size)
         needed = tools.align(needed, self.align_size)
         size = self.size
         if not size:
index 0c4d34d..6b203df 100644 (file)
@@ -883,9 +883,9 @@ class TestFunctional(unittest.TestCase):
         self.assertIn('image', control.images)
         image = control.images['image']
         entries = image.GetEntries()
-        self.assertEqual(5, len(entries))
+        self.assertEqual(6, len(entries))
 
-        # First u-boot with padding before and after
+        # First u-boot with padding before and after (included in minimum size)
         self.assertIn('u-boot', entries)
         entry = entries['u-boot']
         self.assertEqual(0, entry.offset)
@@ -934,8 +934,17 @@ class TestFunctional(unittest.TestCase):
         self.assertEqual(U_BOOT_DATA + tools.get_bytes(0, 64 - len(U_BOOT_DATA)),
                          data[pos:pos + entry.size])
 
+        # Sixth u-boot with both minimum size and aligned size
+        self.assertIn('u-boot-min-size', entries)
+        entry = entries['u-boot-min-size']
+        self.assertEqual(128, entry.offset)
+        self.assertEqual(32, entry.size)
+        self.assertEqual(U_BOOT_DATA, entry.data[:len(U_BOOT_DATA)])
+        self.assertEqual(U_BOOT_DATA + tools.get_bytes(0, 32 - len(U_BOOT_DATA)),
+                         data[pos:pos + entry.size])
+
         self.CheckNoGaps(entries)
-        self.assertEqual(128, image.size)
+        self.assertEqual(160, image.size)
 
         dtb = fdt.Fdt(out_dtb_fname)
         dtb.Scan()
@@ -943,7 +952,7 @@ class TestFunctional(unittest.TestCase):
         expected = {
             'image-pos': 0,
             'offset': 0,
-            'size': 128,
+            'size': 160,
 
             'u-boot:image-pos': 0,
             'u-boot:offset': 0,
@@ -964,6 +973,10 @@ class TestFunctional(unittest.TestCase):
             'u-boot-align-both:image-pos': 64,
             'u-boot-align-both:offset': 64,
             'u-boot-align-both:size': 64,
+
+            'u-boot-min-size:image-pos': 128,
+            'u-boot-min-size:offset': 128,
+            'u-boot-min-size:size': 32,
             }
         self.assertEqual(expected, props)
 
index 1b31555..8d6f491 100644 (file)
@@ -6,6 +6,7 @@
 
        binman {
                u-boot {
+                       min-size = <12>;
                        pad-before = <3>;
                        pad-after = <5>;
                };
                        align = <64>;
                        align-end = <128>;
                };
+
+               u-boot-min-size {
+                       type = "u-boot";
+                       min-size = <24>;
+                       align-size = <16>;
+               };
        };
 };