]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
binman: Support expanding entries
authorSimon Glass <sjg@chromium.org>
Fri, 14 Sep 2018 10:57:29 +0000 (04:57 -0600)
committerSimon Glass <sjg@chromium.org>
Sat, 29 Sep 2018 17:49:35 +0000 (11:49 -0600)
It is useful to have entries which can grow automatically to fill
available space. Add support for this.

Signed-off-by: Simon Glass <sjg@chromium.org>
tools/binman/README
tools/binman/bsection.py
tools/binman/entry.py
tools/binman/etype/_testing.py
tools/binman/etype/section.py
tools/binman/ftest.py
tools/binman/test/88_expand_size.dts [new file with mode: 0644]
tools/binman/test/89_expand_size_bad.dts [new file with mode: 0644]

index d6871946abed62e3ef88bd2bd5223b7c09747f56..6aa5b38419e30e165b6807c8897dc8824c15281c 100644 (file)
@@ -330,6 +330,10 @@ image-pos:
        for each entry. This makes it easy to find out exactly where the entry
        ended up in the image, regardless of parent sections, etc.
 
+expand-size:
+       Expand the size of this entry to fit available space. This space is only
+       limited by the size of the image/section and the position of the next
+       entry.
 
 The attributes supported for images are described below. Several are similar
 to those for entries.
index 4bf206878dca2afc336ad77846c6746e4c3a2706..52ac31a4672ea8ffb678942cdc53a84e22f1d0e7 100644 (file)
@@ -253,10 +253,26 @@ class Section(object):
         for entry in entries:
             self._entries[entry._node.name] = entry
 
+    def _ExpandEntries(self):
+        """Expand any entries that are permitted to"""
+        exp_entry = None
+        for entry in self._entries.values():
+            if exp_entry:
+                exp_entry.ExpandToLimit(entry.offset)
+                exp_entry = None
+            if entry.expand_size:
+                exp_entry = entry
+        if exp_entry:
+            exp_entry.ExpandToLimit(self._size)
+
     def CheckEntries(self):
-        """Check that entries do not overlap or extend outside the section"""
+        """Check that entries do not overlap or extend outside the section
+
+        This also sorts entries, if needed and expands
+        """
         if self._sort:
             self._SortEntries()
+        self._ExpandEntries()
         offset = 0
         prev_name = 'None'
         for entry in self._entries.values():
@@ -419,3 +435,7 @@ class Section(object):
                     return None
                 return entry.data
         source_entry.Raise("Cannot find entry for node '%s'" % node.name)
+
+    def ExpandSize(self, size):
+        if size != self._size:
+            self._size = size
index 7316ad43b5e8cdab57166d1830da63436add1e2c..0915b470b4e93cee9cdc24337189bfb113a53579 100644 (file)
@@ -76,6 +76,7 @@ class Entry(object):
         self.pad_after = 0
         self.offset_unset = False
         self.image_pos = None
+        self._expand_size = False
         if read_node:
             self.ReadNode()
 
@@ -161,6 +162,7 @@ class Entry(object):
                              "of two" % (self._node.path, self.align_size))
         self.align_end = fdt_util.GetInt(self._node, 'align-end')
         self.offset_unset = fdt_util.GetBool(self._node, 'offset-unset')
+        self.expand_size = fdt_util.GetBool(self._node, 'expand-size')
 
     def GetDefaultFilename(self):
         return None
@@ -507,3 +509,12 @@ features to produce new behaviours.
                 break
             name = '%s.%s' % (node.name, name)
         return name
+
+    def ExpandToLimit(self, limit):
+        """Expand an entry so that it ends at the given offset limit"""
+        if self.offset + self.size < limit:
+            self.size = limit - self.offset
+            # Request the contents again, since changing the size requires that
+            # the data grows. This should not fail, but check it to be sure.
+            if not self.ObtainContents():
+                self.Raise('Cannot obtain contents when expanding entry')
index 02c165c0c3e5e95146131ca67616181bfeea0bc0..3e345bd95265c87b203147f1b51020bbea052283 100644 (file)
@@ -48,6 +48,8 @@ class Entry__testing(Entry):
                                                      'return-unknown-contents')
         self.bad_update_contents = fdt_util.GetBool(self._node,
                                                     'bad-update-contents')
+        self.return_contents_once = fdt_util.GetBool(self._node,
+                                                     'return-contents-once')
 
         # Set to True when the entry is ready to process the FDT.
         self.process_fdt_ready = False
@@ -68,12 +70,15 @@ class Entry__testing(Entry):
             EntryArg('test-existing-prop', str)], self.require_args)
         if self.force_bad_datatype:
             self.GetEntryArgsOrProps([EntryArg('test-bad-datatype-arg', bool)])
+        self.return_contents = True
 
     def ObtainContents(self):
-        if self.return_unknown_contents:
+        if self.return_unknown_contents or not self.return_contents:
             return False
         self.data = 'a'
         self.contents_size = len(self.data)
+        if self.return_contents_once:
+            self.return_contents = False
         return True
 
     def GetOffsets(self):
index a30cc915457925a08be118fabf31d7030718398c..005a9f9cb2e73c120a2c29df8d7863939b8b1119 100644 (file)
@@ -40,6 +40,10 @@ class Entry_section(Entry):
     def ProcessFdt(self, fdt):
         return self._section.ProcessFdt(fdt)
 
+    def ExpandEntries(self):
+        Entry.ExpandEntries(self)
+        self._section.ExpandEntries()
+
     def AddMissingProperties(self):
         Entry.AddMissingProperties(self)
         self._section.AddMissingProperties()
@@ -95,3 +99,7 @@ class Entry_section(Entry):
 
     def GetEntries(self):
         return self._section.GetEntries()
+
+    def ExpandToLimit(self, limit):
+        super(Entry_section, self).ExpandToLimit(limit)
+        self._section.ExpandSize(self.size)
index e919e702b5c6a354378b27529536f44f6bb4c845..b1569433234b00e9ee68fb9fe7b68082635e6c36 100644 (file)
@@ -1579,6 +1579,35 @@ class TestFunctional(unittest.TestCase):
         self.assertIn("Node '/binman/files': Missing 'pattern' property",
                       str(e.exception))
 
+    def testExpandSize(self):
+        """Test an expanding entry"""
+        data, _, map_data, _ = self._DoReadFileDtb('88_expand_size.dts',
+                                                   map=True)
+        expect = ('a' * 8 + U_BOOT_DATA +
+                  MRC_DATA + 'b' * 1 + U_BOOT_DATA +
+                  'c' * 8 + U_BOOT_DATA +
+                  'd' * 8)
+        self.assertEqual(expect, data)
+        self.assertEqual('''ImagePos    Offset      Size  Name
+00000000  00000000  00000028  main-section
+00000000   00000000  00000008  fill
+00000008   00000008  00000004  u-boot
+0000000c   0000000c  00000004  section
+0000000c    00000000  00000003  intel-mrc
+00000010   00000010  00000004  u-boot2
+00000014   00000014  0000000c  section2
+00000014    00000000  00000008  fill
+0000001c    00000008  00000004  u-boot
+00000020   00000020  00000008  fill2
+''', map_data)
+
+    def testExpandSizeBad(self):
+        """Test an expanding entry which fails to provide contents"""
+        with self.assertRaises(ValueError) as e:
+            self._DoReadFileDtb('89_expand_size_bad.dts', map=True)
+        self.assertIn("Node '/binman/_testing': Cannot obtain contents when "
+                      'expanding entry', str(e.exception))
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/tools/binman/test/88_expand_size.dts b/tools/binman/test/88_expand_size.dts
new file mode 100644 (file)
index 0000000..c8a0130
--- /dev/null
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
+/ {
+       binman {
+               size = <40>;
+               fill {
+                       expand-size;
+                       fill-byte = [61];
+                       size = <0>;
+               };
+               u-boot {
+                       offset = <8>;
+               };
+               section {
+                       expand-size;
+                       pad-byte = <0x62>;
+                       intel-mrc {
+                       };
+               };
+               u-boot2 {
+                       type = "u-boot";
+                       offset = <16>;
+               };
+               section2 {
+                       type = "section";
+                       fill {
+                               expand-size;
+                               fill-byte = [63];
+                               size = <0>;
+                       };
+                       u-boot {
+                               offset = <8>;
+                       };
+               };
+               fill2 {
+                       type = "fill";
+                       expand-size;
+                       fill-byte = [64];
+                       size = <0>;
+               };
+       };
+};
diff --git a/tools/binman/test/89_expand_size_bad.dts b/tools/binman/test/89_expand_size_bad.dts
new file mode 100644 (file)
index 0000000..edc0e5c
--- /dev/null
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
+/ {
+       binman {
+               _testing {
+                       expand-size;
+                       return-contents-once;
+               };
+               u-boot {
+                       offset = <8>;
+               };
+       };
+};