From 1736575b0cfe5dfe511a2904dd84289fc781728e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 3 Apr 2021 11:05:10 +1300 Subject: [PATCH] binman: Support adding sections to FMAPs 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 --- tools/binman/entries.rst | 13 +++++++++-- tools/binman/etype/fmap.py | 19 ++++++++++++++-- tools/binman/ftest.py | 25 ++++++++++++++++++---- tools/binman/test/095_fmap_x86_section.dts | 2 +- 4 files changed, 50 insertions(+), 9 deletions(-) diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst index a91211e93e..f1c3b7de7a 100644 --- a/tools/binman/entries.rst +++ b/tools/binman/entries.rst @@ -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 -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. +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. diff --git a/tools/binman/etype/fmap.py b/tools/binman/etype/fmap.py index fe81c6f64a..cac99b60eb 100644 --- a/tools/binman/etype/fmap.py +++ b/tools/binman/etype/fmap.py @@ -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 - 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) @@ -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': + # 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: diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index d0a1d99c0d..f36823f51b 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -1595,18 +1595,30 @@ class TestFunctional(unittest.TestCase): 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(3, fhdr.nareas) + self.assertEqual(5, fhdr.nareas) 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'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) @@ -2067,8 +2079,8 @@ class TestFunctional(unittest.TestCase): 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) @@ -2076,6 +2088,11 @@ class TestFunctional(unittest.TestCase): self.assertEqual(0, fentry.offset) 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) diff --git a/tools/binman/test/095_fmap_x86_section.dts b/tools/binman/test/095_fmap_x86_section.dts index 4cfce45670..fd5f018c92 100644 --- a/tools/binman/test/095_fmap_x86_section.dts +++ b/tools/binman/test/095_fmap_x86_section.dts @@ -7,7 +7,7 @@ binman { end-at-4gb; - size = <0x100>; + size = <0x180>; u-boot { }; section { -- 2.39.5