binman: Support adding sections to FMAPs
authorSimon Glass <sjg@chromium.org>
Fri, 2 Apr 2021 22:05:10 +0000 (11:05 +1300)
committerSimon Glass <sjg@chromium.org>
Thu, 29 Apr 2021 10:23:39 +0000 (03:23 -0700)
When used with hierarchical images, use the Chromium OS convention of
adding a section before all the subentries it contains.

Signed-off-by: Simon Glass <sjg@chromium.org>
tools/binman/entries.rst
tools/binman/etype/fmap.py
tools/binman/ftest.py
tools/binman/test/095_fmap_x86_section.dts

index a91211e..f1c3b7d 100644 (file)
@@ -461,8 +461,12 @@ see www.flashrom.org/Flashrom for more information.
 
 When used, this entry will be populated with an FMAP which reflects the
 entries in the current image. Note that any hierarchy is squashed, since
 
 When used, this entry will be populated with an FMAP which reflects the
 entries in the current image. Note that any hierarchy is squashed, since
-FMAP does not support this. Also, CBFS entries appear as a single entry -
-the sub-entries are ignored.
+FMAP does not support this. Sections are represented as an area appearing
+before its contents, so that it is possible to reconstruct the hierarchy
+from the FMAP by using the offset information. This convention does not
+seem to be documented, but is used in Chromium OS.
+
+CBFS entries appear as a single entry, i.e. the sub-entries are ignored.
 
 
 
 
 
 
@@ -804,6 +808,11 @@ Properties:
         missing their contents. The second will produce an image but of
         course it will not work.
 
         missing their contents. The second will produce an image but of
         course it will not work.
 
+Properties:
+    _allow_missing: True if this section permits external blobs to be
+        missing their contents. The second will produce an image but of
+        course it will not work.
+
 Since a section is also an entry, it inherits all the properies of entries
 too.
 
 Since a section is also an entry, it inherits all the properies of entries
 too.
 
index fe81c6f..cac99b6 100644 (file)
@@ -28,8 +28,12 @@ class Entry_fmap(Entry):
 
     When used, this entry will be populated with an FMAP which reflects the
     entries in the current image. Note that any hierarchy is squashed, since
 
     When used, this entry will be populated with an FMAP which reflects the
     entries in the current image. Note that any hierarchy is squashed, since
-    FMAP does not support this. Also, CBFS entries appear as a single entry -
-    the sub-entries are ignored.
+    FMAP does not support this. Sections are represented as an area appearing
+    before its contents, so that it is possible to reconstruct the hierarchy
+    from the FMAP by using the offset information. This convention does not
+    seem to be documented, but is used in Chromium OS.
+
+    CBFS entries appear as a single entry, i.e. the sub-entries are ignored.
     """
     def __init__(self, section, etype, node):
         super().__init__(section, etype, node)
     """
     def __init__(self, section, etype, node):
         super().__init__(section, etype, node)
@@ -45,6 +49,17 @@ class Entry_fmap(Entry):
             tout.Debug("fmap: Add entry '%s' type '%s' (%s subentries)" %
                        (entry.GetPath(), entry.etype, ToHexSize(entries)))
             if entries and entry.etype != 'cbfs':
             tout.Debug("fmap: Add entry '%s' type '%s' (%s subentries)" %
                        (entry.GetPath(), entry.etype, ToHexSize(entries)))
             if entries and entry.etype != 'cbfs':
+                # Create an area for the section, which encompasses all entries
+                # within it
+                if entry.image_pos is None:
+                    pos = 0
+                else:
+                    pos = entry.image_pos - entry.GetRootSkipAtStart()
+
+                # Drop @ symbols in name
+                name = entry.name.replace('@', '')
+                areas.append(
+                    fmap_util.FmapArea(pos, entry.size or 0, name, 0))
                 for subentry in entries.values():
                     _AddEntries(areas, subentry)
             else:
                 for subentry in entries.values():
                     _AddEntries(areas, subentry)
             else:
index d0a1d99..f36823f 100644 (file)
@@ -1595,19 +1595,31 @@ class TestFunctional(unittest.TestCase):
         self.assertEqual(1, fhdr.ver_major)
         self.assertEqual(0, fhdr.ver_minor)
         self.assertEqual(0, fhdr.base)
         self.assertEqual(1, fhdr.ver_major)
         self.assertEqual(0, fhdr.ver_minor)
         self.assertEqual(0, fhdr.base)
-        expect_size = fmap_util.FMAP_HEADER_LEN + fmap_util.FMAP_AREA_LEN * 3
+        expect_size = fmap_util.FMAP_HEADER_LEN + fmap_util.FMAP_AREA_LEN * 5
         self.assertEqual(16 + 16 + expect_size, fhdr.image_size)
         self.assertEqual(b'FMAP', fhdr.name)
         self.assertEqual(16 + 16 + expect_size, fhdr.image_size)
         self.assertEqual(b'FMAP', fhdr.name)
-        self.assertEqual(3, fhdr.nareas)
+        self.assertEqual(5, fhdr.nareas)
         fiter = iter(fentries)
 
         fentry = next(fiter)
         fiter = iter(fentries)
 
         fentry = next(fiter)
+        self.assertEqual(b'SECTION0', fentry.name)
+        self.assertEqual(0, fentry.offset)
+        self.assertEqual(16, fentry.size)
+        self.assertEqual(0, fentry.flags)
+
+        fentry = next(fiter)
         self.assertEqual(b'RO_U_BOOT', fentry.name)
         self.assertEqual(0, fentry.offset)
         self.assertEqual(4, fentry.size)
         self.assertEqual(0, fentry.flags)
 
         fentry = next(fiter)
         self.assertEqual(b'RO_U_BOOT', fentry.name)
         self.assertEqual(0, fentry.offset)
         self.assertEqual(4, fentry.size)
         self.assertEqual(0, fentry.flags)
 
         fentry = next(fiter)
+        self.assertEqual(b'SECTION1', fentry.name)
+        self.assertEqual(16, fentry.offset)
+        self.assertEqual(16, fentry.size)
+        self.assertEqual(0, fentry.flags)
+
+        fentry = next(fiter)
         self.assertEqual(b'RW_U_BOOT', fentry.name)
         self.assertEqual(16, fentry.offset)
         self.assertEqual(4, fentry.size)
         self.assertEqual(b'RW_U_BOOT', fentry.name)
         self.assertEqual(16, fentry.offset)
         self.assertEqual(4, fentry.size)
@@ -2067,8 +2079,8 @@ class TestFunctional(unittest.TestCase):
         self.assertEqual(expected, data[:32])
         fhdr, fentries = fmap_util.DecodeFmap(data[36:])
 
         self.assertEqual(expected, data[:32])
         fhdr, fentries = fmap_util.DecodeFmap(data[36:])
 
-        self.assertEqual(0x100, fhdr.image_size)
-        expect_size = fmap_util.FMAP_HEADER_LEN + fmap_util.FMAP_AREA_LEN * 3
+        self.assertEqual(0x180, fhdr.image_size)
+        expect_size = fmap_util.FMAP_HEADER_LEN + fmap_util.FMAP_AREA_LEN * 4
         fiter = iter(fentries)
 
         fentry = next(fiter)
         fiter = iter(fentries)
 
         fentry = next(fiter)
@@ -2077,6 +2089,11 @@ class TestFunctional(unittest.TestCase):
         self.assertEqual(4, fentry.size)
 
         fentry = next(fiter)
         self.assertEqual(4, fentry.size)
 
         fentry = next(fiter)
+        self.assertEqual(b'SECTION', fentry.name)
+        self.assertEqual(4, fentry.offset)
+        self.assertEqual(0x20 + expect_size, fentry.size)
+
+        fentry = next(fiter)
         self.assertEqual(b'INTEL_MRC', fentry.name)
         self.assertEqual(4, fentry.offset)
         self.assertEqual(3, fentry.size)
         self.assertEqual(b'INTEL_MRC', fentry.name)
         self.assertEqual(4, fentry.offset)
         self.assertEqual(3, fentry.size)
index 4cfce45..fd5f018 100644 (file)
@@ -7,7 +7,7 @@
 
        binman {
                end-at-4gb;
 
        binman {
                end-at-4gb;
-               size = <0x100>;
+               size = <0x180>;
                u-boot {
                };
                section {
                u-boot {
                };
                section {