]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
binman: Support optional entries
authorSimon Glass <sjg@chromium.org>
Sat, 7 Jan 2023 21:07:12 +0000 (14:07 -0700)
committerSimon Glass <sjg@chromium.org>
Wed, 18 Jan 2023 18:50:01 +0000 (11:50 -0700)
Support entries which can be optional depending on their contents. This
allows special entry types which appear in the image only when needed.

Signed-off-by: Simon Glass <sjg@chromium.org>
tools/binman/binman.rst
tools/binman/control.py
tools/binman/entry.py
tools/binman/etype/_testing.py
tools/binman/etype/section.py
tools/binman/ftest.py
tools/binman/test/262_absent.dts [new file with mode: 0644]

index ef3e5a6d19b258bc19eb3bbf3cabaaf62305e896..5e3961f225529fa298c8c6e4b709140d55267a2d 100644 (file)
@@ -1013,6 +1013,28 @@ For the BSS case, a 'spl-bss-pad' entry arg controls whether it is present. All
 entry args are provided by the U-Boot Makefile.
 
 
+Optional entries
+----------------
+
+Some entries need to exist only if certain conditions are met. For example, an
+entry may want to appear in the image only if a file has a particular format.
+Obviously the entry must exist in the image description for it to be processed
+at all, so a way needs to be found to have the entry remove itself.
+
+To handle this, when entry.ObtainContents() is called, the entry can call
+entry.mark_absent() to mark itself as absent, passing a suitable message as the
+reason.
+
+Any absent entries are dropped immediately after ObtainContents() has been
+called on all entries.
+
+It is not possible for an entry to mark itself absent at any other point in the
+processing. It must happen in the ObtainContents() method.
+
+The effect is as if the entry had never been present at all, since the image
+is packed without it and it disappears from the list of entries.
+
+
 Compression
 -----------
 
index 964c6984f9b44418f0ae476ea17f6b676baa41c8..07225381146b36c9f9fdc6328187a0938843ee15 100644 (file)
@@ -552,6 +552,7 @@ def ProcessImage(image, update_fdt, write_map, get_contents=True,
         image.SetAllowMissing(allow_missing)
         image.SetAllowFakeBlob(allow_fake_blobs)
         image.GetEntryContents()
+        image.drop_absent()
     image.GetEntryOffsets()
 
     # We need to pack the entries to figure out where everything
index 1be31a05e00a8feb650c913116c69236146e0e59..637aece370502db33fd3b02141303029c22e53b6 100644 (file)
@@ -91,6 +91,10 @@ class Entry(object):
             file, or is a binary file produced from an ELF file
         auto_write_symbols (bool): True to write ELF symbols into this entry's
             contents
+        absent (bool): True if this entry is absent. This can be controlled by
+            the entry itself, allowing it to vanish in certain circumstances.
+            An absent entry is removed during processing so that it does not
+            appear in the map
     """
     fake_dir = None
 
@@ -133,6 +137,7 @@ class Entry(object):
         self.comp_bintool = None
         self.elf_fname = None
         self.auto_write_symbols = auto_write_symbols
+        self.absent = False
 
     @staticmethod
     def FindEntryClass(etype, expanded):
@@ -1281,3 +1286,7 @@ features to produce new behaviours.
                 not_present.append(prop)
         if not_present:
             self.Raise(f"'{self.etype}' entry is missing properties: {' '.join(not_present)}")
+
+    def mark_absent(self, msg):
+        tout.info("Entry '%s' marked absent: %s" % (self._node.path, msg))
+        self.absent = True
index 69600487814779dddfda12397cb2255535b33a80..1c1efb21a4476c484d8975f5641d34ff7958dbb5 100644 (file)
@@ -63,6 +63,7 @@ class Entry__testing(Entry):
                                                     'bad-update-contents-twice')
         self.return_contents_later = fdt_util.GetBool(self._node,
                                                      'return-contents-later')
+        self.set_to_absent = fdt_util.GetBool(self._node, 'set-to-absent')
 
         # Set to True when the entry is ready to process the FDT.
         self.process_fdt_ready = False
@@ -119,6 +120,8 @@ class Entry__testing(Entry):
         if self.require_bintool_for_contents:
             if self.bintool_for_contents is None:
                 self.Raise("Required bintool unusable in ObtainContents()")
+        if self.set_to_absent:
+            self.mark_absent('for testing purposes')
         return True
 
     def GetOffsets(self):
index 305155c8461c3dc439d933abec60be2a959fcf35..dcb7a062047ef83e1668d6afcd09892562f6b2b7 100644 (file)
@@ -672,6 +672,9 @@ class Entry_section(Entry):
 
     def GetEntryContents(self, skip_entry=None):
         """Call ObtainContents() for each entry in the section
+
+        Note that this may set entry.absent to True if the entry is not
+        actually needed
         """
         def _CheckDone(entry):
             if entry != skip_entry:
@@ -716,6 +719,10 @@ class Entry_section(Entry):
                        todo)
         return True
 
+    def drop_absent(self):
+        """Drop entries which are absent"""
+        self._entries = {n: e for n, e in self._entries.items() if not e.absent}
+
     def _SetEntryOffsetSize(self, name, offset, size):
         """Set the offset and size of an entry
 
index c3cb32dca26d676cdd469a616a503bb12357b7ce..f47a745f1e17cf7c975f416346f3013b6d117add 100644 (file)
@@ -6090,6 +6090,11 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
         sect_data = tools.read_file(sect_fname)
         self.assertEqual(U_BOOT_DATA, sect_data)
 
+    def testAbsent(self):
+        """Check handling of absent entries"""
+        data = self._DoReadFile('262_absent.dts')
+        self.assertEqual(U_BOOT_DATA + U_BOOT_IMG_DATA, data)
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/tools/binman/test/262_absent.dts b/tools/binman/test/262_absent.dts
new file mode 100644 (file)
index 0000000..2ab8766
--- /dev/null
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       binman {
+               u-boot {
+               };
+
+               _testing {
+                       set-to-absent;
+               };
+
+               u-boot-img {
+               };
+       };
+};