binman: Support marking FMAP areas as preserved

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@chromium.org>
This commit is contained in:
Simon Glass
2023-02-12 17:11:15 -07:00
parent 139c464c2a
commit 9dbb02b9d1
7 changed files with 38 additions and 3 deletions

View File

@@ -838,6 +838,14 @@ offset-from-elf:
is the symbol to lookup (relative to elf-base-sym) and <offset> is an offset is the symbol to lookup (relative to elf-base-sym) and <offset> is an offset
to add to that value. 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 Examples of the above options can be found in the tests. See the
tools/binman/test directory. tools/binman/test directory.

View File

@@ -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 from the FMAP by using the offset information. This convention does not
seem to be documented, but is used in Chromium OS. 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. CBFS entries appear as a single entry, i.e. the sub-entries are ignored.

View File

@@ -100,6 +100,10 @@ class Entry(object):
appear in the map appear in the map
optional (bool): True if this entry contains an optional external blob optional (bool): True if this entry contains an optional external blob
overlap (bool): True if this entry overlaps with others 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 fake_dir = None
@@ -148,6 +152,7 @@ class Entry(object):
self.overlap = False self.overlap = False
self.elf_base_sym = None self.elf_base_sym = None
self.offset_from_elf = None self.offset_from_elf = None
self.preserve = False
@staticmethod @staticmethod
def FindEntryClass(etype, expanded): def FindEntryClass(etype, expanded):
@@ -310,6 +315,8 @@ class Entry(object):
self.offset_from_elf = fdt_util.GetPhandleNameOffset(self._node, self.offset_from_elf = fdt_util.GetPhandleNameOffset(self._node,
'offset-from-elf') 'offset-from-elf')
self.preserve = fdt_util.GetBool(self._node, 'preserve')
def GetDefaultFilename(self): def GetDefaultFilename(self):
return None return None

View File

@@ -33,6 +33,11 @@ class Entry_fmap(Entry):
from the FMAP by using the offset information. This convention does not from the FMAP by using the offset information. This convention does not
seem to be documented, but is used in Chromium OS. 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. CBFS entries appear as a single entry, i.e. the sub-entries are ignored.
""" """
def __init__(self, section, etype, node): def __init__(self, section, etype, node):
@@ -48,6 +53,12 @@ class Entry_fmap(Entry):
entries = entry.GetEntries() entries = entry.GetEntries()
tout.debug("fmap: Add entry '%s' type '%s' (%s subentries)" % tout.debug("fmap: Add entry '%s' type '%s' (%s subentries)" %
(entry.GetPath(), entry.etype, to_hex_size(entries))) (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': if entries and entry.etype != 'cbfs':
# Create an area for the section, which encompasses all entries # Create an area for the section, which encompasses all entries
# within it # within it
@@ -59,7 +70,7 @@ class Entry_fmap(Entry):
# Drop @ symbols in name # Drop @ symbols in name
name = entry.name.replace('@', '') name = entry.name.replace('@', '')
areas.append( 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(): for subentry in entries.values():
_AddEntries(areas, subentry) _AddEntries(areas, subentry)
else: else:
@@ -67,7 +78,7 @@ class Entry_fmap(Entry):
if pos is not None: if pos is not None:
pos -= entry.section.GetRootSkipAtStart() pos -= entry.section.GetRootSkipAtStart()
areas.append(fmap_util.FmapArea(pos or 0, entry.size or 0, areas.append(fmap_util.FmapArea(pos or 0, entry.size or 0,
entry.name, 0)) entry.name, flags))
entries = self.GetImage().GetEntries() entries = self.GetImage().GetEntries()
areas = [] areas = []

View File

@@ -45,6 +45,9 @@ FMAP_AREA_NAMES = (
'flags', '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 # 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 # appears once at the start) and an area (which is repeated until the end of
# the list of areas) # the list of areas)

View File

@@ -1702,7 +1702,7 @@ class TestFunctional(unittest.TestCase):
self.assertEqual(b'SECTION0', fentry.name) self.assertEqual(b'SECTION0', fentry.name)
self.assertEqual(0, fentry.offset) self.assertEqual(0, fentry.offset)
self.assertEqual(16, fentry.size) self.assertEqual(16, fentry.size)
self.assertEqual(0, fentry.flags) self.assertEqual(fmap_util.FMAP_AREA_PRESERVE, fentry.flags)
fentry = next(fiter) fentry = next(fiter)
self.assertEqual(b'RO_U_BOOT', fentry.name) self.assertEqual(b'RO_U_BOOT', fentry.name)

View File

@@ -11,6 +11,7 @@
name-prefix = "ro-"; name-prefix = "ro-";
size = <0x10>; size = <0x10>;
pad-byte = <0x21>; pad-byte = <0x21>;
preserve;
u-boot { u-boot {
}; };