]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
binman: Add support for a collection of entries
authorSimon Glass <sjg@chromium.org>
Sun, 21 Mar 2021 05:24:31 +0000 (18:24 +1300)
committerSimon Glass <sjg@chromium.org>
Sat, 27 Mar 2021 03:26:48 +0000 (16:26 +1300)
The vblock entry type includes code to collect the data from a number of
other entries (not necessarily subentries) and concatenating it. This is
a useful feature for other entry types.

Make it a base class, so that vblock can use it, along with other entry
types.

Signed-off-by: Simon Glass <sjg@chromium.org>
tools/binman/entries.rst
tools/binman/entry.py
tools/binman/etype/collection.py [new file with mode: 0644]
tools/binman/etype/vblock.py
tools/binman/ftest.py
tools/binman/test/198_collection.dts [new file with mode: 0644]

index 1a71413f940d08a4465027dc7aa4e5be97252ddc..d5f8d95dc1902563da61c83e03aa734ad9b6440c 100644 (file)
@@ -248,6 +248,19 @@ both of size 1MB.
 
 
 
+Entry: collection: An entry which contains a collection of other entries
+------------------------------------------------------------------------
+
+Properties / Entry arguments:
+    - content: List of phandles to entries to include
+
+This allows reusing the contents of other entries. The contents of the
+listed entries are combined to form this entry. This serves as a useful
+base class for entry types which need to process data from elsewhere in
+the image, not necessarily child entries.
+
+
+
 Entry: cros-ec-rw: A blob entry which contains a Chromium OS read-write EC image
 --------------------------------------------------------------------------------
 
index ac25986ee6e66a6a9901a9fcdf32c939d8b13011..a157038d4e393a7290aca97135b82d77a11ff180 100644 (file)
@@ -438,6 +438,11 @@ class Entry(object):
         """Convenience function to raise an error referencing a node"""
         raise ValueError("Node '%s': %s" % (self._node.path, msg))
 
+    def Info(self, msg):
+        """Convenience function to log info referencing a node"""
+        tag = "Info '%s'" % self._node.path
+        tout.Detail('%30s: %s' % (tag, msg))
+
     def Detail(self, msg):
         """Convenience function to log detail referencing a node"""
         tag = "Node '%s'" % self._node.path
diff --git a/tools/binman/etype/collection.py b/tools/binman/etype/collection.py
new file mode 100644 (file)
index 0000000..c0c552a
--- /dev/null
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2021 Google LLC
+# Written by Simon Glass <sjg@chromium.org>
+#
+
+# Support for a collection of entries from other parts of an image
+
+from collections import OrderedDict
+import os
+
+from binman.entry import Entry
+from dtoc import fdt_util
+
+class Entry_collection(Entry):
+    """An entry which contains a collection of other entries
+
+    Properties / Entry arguments:
+        - content: List of phandles to entries to include
+
+    This allows reusing the contents of other entries. The contents of the
+    listed entries are combined to form this entry. This serves as a useful
+    base class for entry types which need to process data from elsewhere in
+    the image, not necessarily child entries.
+    """
+    def __init__(self, section, etype, node):
+        super().__init__(section, etype, node)
+        self.content = fdt_util.GetPhandleList(self._node, 'content')
+        if not self.content:
+            self.Raise("Collection must have a 'content' property")
+
+    def GetContents(self):
+        """Get the contents of this entry
+
+        Returns:
+            bytes content of the entry
+        """
+        # Join up all the data
+        self.Info('Getting content')
+        data = b''
+        for entry_phandle in self.content:
+            entry_data = self.section.GetContentsByPhandle(entry_phandle, self)
+            if entry_data is None:
+                # Data not available yet
+                return None
+            data += entry_data
+
+        self.Info('Returning contents size %x' % len(data))
+
+        return data
+
+    def ObtainContents(self):
+        data = self.GetContents()
+        if data is None:
+            return False
+        self.SetContents(data)
+        return True
+
+    def ProcessContents(self):
+        # The blob may have changed due to WriteSymbols()
+        data = self.GetContents()
+        return self.ProcessContentsUpdate(data)
index eba5351dd526f708cdb966243fabcc2b646e6b65..d473083cab822d9dcbaa9bd76f23591a4b8264ed 100644 (file)
@@ -9,12 +9,13 @@
 from collections import OrderedDict
 import os
 
-from binman.entry import Entry, EntryArg
+from binman.entry import EntryArg
+from binman.etype.collection import Entry_collection
 
 from dtoc import fdt_util
 from patman import tools
 
-class Entry_vblock(Entry):
+class Entry_vblock(Entry_collection):
     """An entry which contains a Chromium OS verified boot block
 
     Properties / Entry arguments:
@@ -37,9 +38,6 @@ class Entry_vblock(Entry):
     """
     def __init__(self, section, etype, node):
         super().__init__(section, etype, node)
-        self.content = fdt_util.GetPhandleList(self._node, 'content')
-        if not self.content:
-            self.Raise("Vblock must have a 'content' property")
         (self.keydir, self.keyblock, self.signprivate, self.version,
          self.kernelkey, self.preamble_flags) = self.GetEntryArgsOrProps([
             EntryArg('keydir', str),
@@ -50,14 +48,16 @@ class Entry_vblock(Entry):
             EntryArg('preamble-flags', int)])
 
     def GetVblock(self):
+        """Get the contents of this entry
+
+        Returns:
+            bytes content of the entry, which is the signed vblock for the
+                provided data
+        """
         # Join up the data files to be signed
-        input_data = b''
-        for entry_phandle in self.content:
-            data = self.section.GetContentsByPhandle(entry_phandle, self)
-            if data is None:
-                # Data not available yet
-                return False
-            input_data += data
+        input_data = self.GetContents()
+        if input_data is None:
+            return None
 
         uniq = self.GetUniqueName()
         output_fname = tools.GetOutputFilename('vblock.%s' % uniq)
@@ -80,7 +80,7 @@ class Entry_vblock(Entry):
 
     def ObtainContents(self):
         data = self.GetVblock()
-        if data is False:
+        if data is None:
             return False
         self.SetContents(data)
         return True
index cd93dc153a77c030cf88697a35ac86f566924d4a..fdd4f4d2fadc7d7a0d94b16bf1455d3e9d887970 100644 (file)
@@ -1718,7 +1718,7 @@ class TestFunctional(unittest.TestCase):
         """Test we detect a vblock which has no content to sign"""
         with self.assertRaises(ValueError) as e:
             self._DoReadFile('075_vblock_no_content.dts')
-        self.assertIn("Node '/binman/vblock': Vblock must have a 'content' "
+        self.assertIn("Node '/binman/vblock': Collection must have a 'content' "
                       'property', str(e.exception))
 
     def testVblockBadPhandle(self):
@@ -4476,5 +4476,13 @@ class TestFunctional(unittest.TestCase):
                           U_BOOT_SPL_DTB_DATA, 0x38,
                           entry_args=entry_args, use_expanded=True)
 
+    def testCollection(self):
+        """Test a collection"""
+        data = self._DoReadFile('198_collection.dts')
+        self.assertEqual(U_BOOT_NODTB_DATA + U_BOOT_DTB_DATA +
+                         tools.GetBytes(0xff, 2) + U_BOOT_NODTB_DATA +
+                         tools.GetBytes(0xfe, 3) + U_BOOT_DTB_DATA,
+                         data)
+
 if __name__ == "__main__":
     unittest.main()
diff --git a/tools/binman/test/198_collection.dts b/tools/binman/test/198_collection.dts
new file mode 100644 (file)
index 0000000..484a1b0
--- /dev/null
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       binman {
+               collection {
+                       content = <&u_boot_nodtb &dtb>;
+               };
+               fill {
+                       size = <2>;
+                       fill-byte = [ff];
+               };
+               u_boot_nodtb: u-boot-nodtb {
+               };
+               fill2 {
+                       type = "fill";
+                       size = <3>;
+                       fill-byte = [fe];
+               };
+               dtb: u-boot-dtb {
+               };
+       };
+};