[PATCH] binman: Support marking FMAP areas as preserved

Simon Glass sjg at chromium.org
Mon Feb 13 01:11:15 CET 2023


Add an entry flag called 'preserve' to indicate that an entry should be
preserved by firmware updates. Propagate this to FMAP too.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

 tools/binman/binman.rst        |  8 ++++++++
 tools/binman/entries.rst       |  5 +++++
 tools/binman/entry.py          |  7 +++++++
 tools/binman/etype/fmap.py     | 15 +++++++++++++--
 tools/binman/fmap_util.py      |  3 +++
 tools/binman/ftest.py          |  2 +-
 tools/binman/test/067_fmap.dts |  1 +
 7 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst
index 03a99a19bc6..6cf4f196fb3 100644
--- a/tools/binman/binman.rst
+++ b/tools/binman/binman.rst
@@ -838,6 +838,14 @@ offset-from-elf:
     is the symbol to lookup (relative to elf-base-sym) and <offset> is an offset
     to add to that value.
 
+preserve:
+    Indicates that this entry should be preserved by any firmware updates. This
+    flag should be checked by the updater when it is deciding which entries to
+    update. This flag is normally attached to sections but can be attached to
+    a single entry in a section if the updater supports it. Not that binman
+    itself has no control over the updater's behaviour, so this is just a
+    signal. It is not enforced by binman.
+
 Examples of the above options can be found in the tests. See the
 tools/binman/test directory.
 
diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
index 7a04a613992..19659247cf0 100644
--- a/tools/binman/entries.rst
+++ b/tools/binman/entries.rst
@@ -887,6 +887,11 @@ 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.
 
+To mark an area as preserved, use the normal 'preserved' flag in the entry.
+This will result in the corresponding FMAP area having the
+FMAP_AREA_PRESERVE flag. This flag does not automatically propagate down to
+child entries.
+
 CBFS entries appear as a single entry, i.e. the sub-entries are ignored.
 
 
diff --git a/tools/binman/entry.py b/tools/binman/entry.py
index 5eacc5fa6c4..fd617e4f15f 100644
--- a/tools/binman/entry.py
+++ b/tools/binman/entry.py
@@ -100,6 +100,10 @@ class Entry(object):
             appear in the map
         optional (bool): True if this entry contains an optional external blob
         overlap (bool): True if this entry overlaps with others
+        preserve (bool): True if this entry should be preserved when updating
+            firmware. This means that it will not be changed by the update.
+            This is just a signal: enforcement of this is up to the updater.
+            This flag does not automatically propagate down to child entries.
     """
     fake_dir = None
 
@@ -148,6 +152,7 @@ class Entry(object):
         self.overlap = False
         self.elf_base_sym = None
         self.offset_from_elf = None
+        self.preserve = False
 
     @staticmethod
     def FindEntryClass(etype, expanded):
@@ -310,6 +315,8 @@ class Entry(object):
         self.offset_from_elf = fdt_util.GetPhandleNameOffset(self._node,
                                                              'offset-from-elf')
 
+        self.preserve = fdt_util.GetBool(self._node, 'preserve')
+
     def GetDefaultFilename(self):
         return None
 
diff --git a/tools/binman/etype/fmap.py b/tools/binman/etype/fmap.py
index 0c576202a48..b35450fec97 100644
--- a/tools/binman/etype/fmap.py
+++ b/tools/binman/etype/fmap.py
@@ -33,6 +33,11 @@ class Entry_fmap(Entry):
     from the FMAP by using the offset information. This convention does not
     seem to be documented, but is used in Chromium OS.
 
+    To mark an area as preserved, use the normal 'preserved' flag in the entry.
+    This will result in the corresponding FMAP area having the
+    FMAP_AREA_PRESERVE flag. This flag does not automatically propagate down to
+    child entries.
+
     CBFS entries appear as a single entry, i.e. the sub-entries are ignored.
     """
     def __init__(self, section, etype, node):
@@ -48,6 +53,12 @@ class Entry_fmap(Entry):
             entries = entry.GetEntries()
             tout.debug("fmap: Add entry '%s' type '%s' (%s subentries)" %
                        (entry.GetPath(), entry.etype, to_hex_size(entries)))
+
+            # Collect any flag (separate lines to ensure code coverage)
+            flags = 0
+            if entry.preserve:
+                flags = fmap_util.FMAP_AREA_PRESERVE
+
             if entries and entry.etype != 'cbfs':
                 # Create an area for the section, which encompasses all entries
                 # within it
@@ -59,7 +70,7 @@ class Entry_fmap(Entry):
                 # Drop @ symbols in name
                 name = entry.name.replace('@', '')
                 areas.append(
-                    fmap_util.FmapArea(pos, entry.size or 0, name, 0))
+                    fmap_util.FmapArea(pos, entry.size or 0, name, flags))
                 for subentry in entries.values():
                     _AddEntries(areas, subentry)
             else:
@@ -67,7 +78,7 @@ class Entry_fmap(Entry):
                 if pos is not None:
                     pos -= entry.section.GetRootSkipAtStart()
                 areas.append(fmap_util.FmapArea(pos or 0, entry.size or 0,
-                                                entry.name, 0))
+                                                entry.name, flags))
 
         entries = self.GetImage().GetEntries()
         areas = []
diff --git a/tools/binman/fmap_util.py b/tools/binman/fmap_util.py
index 1ce63d1a832..82e0f74d50f 100644
--- a/tools/binman/fmap_util.py
+++ b/tools/binman/fmap_util.py
@@ -45,6 +45,9 @@ FMAP_AREA_NAMES = (
     'flags',
 )
 
+# Flags supported by areas (bits 2:0 are unused so not included here)
+FMAP_AREA_PRESERVE = 1 << 3  # Preserved by any firmware updates
+
 # These are the two data structures supported by flashrom, a header (which
 # appears once at the start) and an area (which is repeated until the end of
 # the list of areas)
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 6b203dfb644..8df2fb39a8b 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -1702,7 +1702,7 @@ class TestFunctional(unittest.TestCase):
         self.assertEqual(b'SECTION0', fentry.name)
         self.assertEqual(0, fentry.offset)
         self.assertEqual(16, fentry.size)
-        self.assertEqual(0, fentry.flags)
+        self.assertEqual(fmap_util.FMAP_AREA_PRESERVE, fentry.flags)
 
         fentry = next(fiter)
         self.assertEqual(b'RO_U_BOOT', fentry.name)
diff --git a/tools/binman/test/067_fmap.dts b/tools/binman/test/067_fmap.dts
index 9c0e293ac83..24fa6351ec3 100644
--- a/tools/binman/test/067_fmap.dts
+++ b/tools/binman/test/067_fmap.dts
@@ -11,6 +11,7 @@
 			name-prefix = "ro-";
 			size = <0x10>;
 			pad-byte = <0x21>;
+			preserve;
 
 			u-boot {
 			};
-- 
2.39.1.581.gbfd45094c4-goog



More information about the U-Boot mailing list