binman: Keep a separate list of entries for fit

The current implementation sets up the FIT entries but then deletes the
'generator' ones so they don't appear in the final image.

This is a bit clumsy. We cannot build the image more than once, since the
generator entries are lost during the first build. Binman requires that
calling BuildSectionData() multiple times returns a valid result each
time.

Keep a separate, private list which includes the generator nodes and use
that where needed, to correct this problem. Ensure that the missing list
includes removed generator entries too.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
This commit is contained in:
Simon Glass
2022-03-05 20:19:11 -07:00
parent 01f467e2d3
commit 2337eca283

View File

@@ -163,12 +163,17 @@ class Entry_fit(Entry_section):
key: relative path to entry Node (from the base of the FIT)
value: Entry_section object comprising the contents of this
node
_priv_entries: Internal copy of _entries which includes 'generator'
entries which are used to create the FIT, but should not be
processed as real entries. This is set up once we have the
entries
"""
super().__init__(section, etype, node)
self._fit = None
self._fit_props = {}
self._fdts = None
self.mkimage = None
self._priv_entries = {}
def ReadNode(self):
super().ReadNode()
@@ -236,6 +241,10 @@ class Entry_fit(Entry_section):
_add_entries(self._node, 0, self._node)
# Keep a copy of all entries, including generator entries, since these
# removed from self._entries later.
self._priv_entries = dict(self._entries)
def BuildSectionData(self, required):
"""Build FIT entry contents
@@ -415,11 +424,12 @@ class Entry_fit(Entry_section):
has_images = depth == 2 and in_images
if has_images:
entry = self._entries[rel_path]
entry = self._priv_entries[rel_path]
data = entry.GetData()
fsw.property('data', bytes(data))
for subnode in node.subnodes:
subnode_path = f'{rel_path}/{subnode.name}'
if has_images and not (subnode.name.startswith('hash') or
subnode.name.startswith('signature')):
# This subnode is a content node not meant to appear in
@@ -427,11 +437,11 @@ class Entry_fit(Entry_section):
# fsw.add_node() or _add_node() for it.
pass
elif self.GetImage().generate and subnode.name.startswith('@'):
subnode_path = f'{rel_path}/{subnode.name}'
entry = self._entries.get(subnode_path)
_gen_node(base_node, subnode, depth, in_images)
if entry:
del self._entries[subnode_path]
# This is a generator (template) entry, so remove it from
# the list of entries used by PackEntries(), etc. Otherwise
# it will appear in the binman output
to_remove.append(subnode_path)
else:
with fsw.add_node(subnode.name):
_add_node(base_node, depth + 1, subnode)
@@ -440,10 +450,16 @@ class Entry_fit(Entry_section):
# entry node
fsw = libfdt.FdtSw()
fsw.finish_reservemap()
to_remove = []
with fsw.add_node(''):
_add_node(self._node, 0, self._node)
fdt = fsw.as_fdt()
# Remove generator entries from the main list
for path in to_remove:
if path in self._entries:
del self._entries[path]
# Pack this new FDT and scan it so we can add the data later
fdt.pack()
data = fdt.as_bytearray()
@@ -503,3 +519,10 @@ class Entry_fit(Entry_section):
def AddBintools(self, btools):
super().AddBintools(btools)
self.mkimage = self.AddBintool(btools, 'mkimage')
def CheckMissing(self, missing_list):
# We must use our private entry list for this since generator notes
# which are removed from self._entries will otherwise not show up as
# missing
for entry in self._priv_entries.values():
entry.CheckMissing(missing_list)