[PATCH RFC v2 5/8] binman: rework dropping absent entries from packaged image
Yannic Moog
y.moog at phytec.de
Tue May 27 15:24:13 CEST 2025
When blobs are absent and are marked as optional, they can be safely
dropped from the binman tree. Use the drop_absent function for that.
Rename drop_absent to drop_absent_optional as we do not want to drop any
entries that are absent; they should be reported by binman as errors
when they are missing.
We also reorder the processing of the image the following:
- We call the CheckForProblems function before the image is built.
- We drop entries after we checked for problems with the image.
This is okay because CheckForProblems does not look at the file we have
written but rather queries the data structure (image) built with binman.
This also allows us to get all error and warning messages that we want
to report while avoiding putting missing optional entries in the final
image.
Signed-off-by: Yannic Moog <y.moog at phytec.de>
---
tools/binman/control.py | 8 ++++----
tools/binman/entry.py | 6 +++++-
tools/binman/etype/cbfs.py | 3 ++-
tools/binman/etype/mkimage.py | 2 +-
tools/binman/etype/section.py | 18 +++++++++++++-----
tools/binman/image.py | 4 +++-
6 files changed, 28 insertions(+), 13 deletions(-)
diff --git a/tools/binman/control.py b/tools/binman/control.py
index 81f61e3e152a9eab558cfc9667131a38082b61a1..c2a4d3eae9d4e8f4a3c5be1abfb1469ba1c0ed93 100644
--- a/tools/binman/control.py
+++ b/tools/binman/control.py
@@ -18,6 +18,7 @@ import re
import sys
+import image
from binman import bintool
from binman import cbfs_util
from binman import elf
@@ -669,7 +670,7 @@ def CheckForProblems(image):
for bintool in missing_bintool_list])))
return any([missing_list, faked_list, missing_bintool_list])
-def ProcessImage(image, update_fdt, write_map, get_contents=True,
+def ProcessImage(image: image.Image, update_fdt, write_map, get_contents=True,
allow_resize=True, allow_missing=False,
allow_fake_blobs=False):
"""Perform all steps for this image, including checking and # writing it.
@@ -697,7 +698,6 @@ def ProcessImage(image, update_fdt, write_map, get_contents=True,
image.SetAllowMissing(allow_missing)
image.SetAllowFakeBlob(allow_fake_blobs)
image.GetEntryContents()
- image.drop_absent()
image.GetEntryOffsets()
# We need to pack the entries to figure out where everything
@@ -736,12 +736,12 @@ def ProcessImage(image, update_fdt, write_map, get_contents=True,
image.Raise('Entries changed size after packing (tried %s passes)' %
passes)
+ has_problems = CheckForProblems(image)
+
image.BuildImage()
if write_map:
image.WriteMap()
- has_problems = CheckForProblems(image)
-
image.WriteAlternates()
return has_problems
diff --git a/tools/binman/entry.py b/tools/binman/entry.py
index 6390917e5083e40a4e3294e5d36ec300d2057fe9..ce7ef28e94b17e349544776070c457d5882661b1 100644
--- a/tools/binman/entry.py
+++ b/tools/binman/entry.py
@@ -760,7 +760,7 @@ class Entry(object):
self.image_pos)
# pylint: disable=assignment-from-none
- def GetEntries(self):
+ def GetEntries(self) -> None:
"""Return a list of entries contained by this entry
Returns:
@@ -1351,6 +1351,10 @@ features to produce new behaviours.
os.mkdir(cls.fake_dir)
tout.notice(f"Fake-blob dir is '{cls.fake_dir}'")
+ def drop_absent_optional(self) -> None:
+ """Entries don't have any entries, do nothing"""
+ pass
+
def ensure_props(self):
"""Raise an exception if properties are missing
diff --git a/tools/binman/etype/cbfs.py b/tools/binman/etype/cbfs.py
index 886e34ef8221ad50e9f881e8abad16015c9790b5..bb97b227ef78356b08b5cc31b04d98c6fa0633ef 100644
--- a/tools/binman/etype/cbfs.py
+++ b/tools/binman/etype/cbfs.py
@@ -276,7 +276,8 @@ class Entry_cbfs(Entry):
for entry in self.GetEntries().values():
entry.ListEntries(entries, indent + 1)
- def GetEntries(self):
+ def GetEntries(self) -> dict[str, Entry]:
+ """Returns the entries (tree children) of this section"""
return self._entries
def ReadData(self, decomp=True, alt_format=None):
diff --git a/tools/binman/etype/mkimage.py b/tools/binman/etype/mkimage.py
index 19ee30a13ca75a5d05a17d4c26424e84934b6ea2..c9362c6bbf740da946abe2fadefe35ebfc89fced 100644
--- a/tools/binman/etype/mkimage.py
+++ b/tools/binman/etype/mkimage.py
@@ -205,7 +205,7 @@ class Entry_mkimage(Entry_section):
self.record_missing_bintool(self.mkimage)
return data
- def GetEntries(self):
+ def GetEntries(self) -> dict[str, Entry]:
# Make a copy so we don't change the original
entries = OrderedDict(self._entries)
if self._imagename:
diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py
index 44b1b85e93496d0ca114907f42a98da1f0af09b9..8e5c20e3017c9b320ebfdfd3bf82489ed6161c98 100644
--- a/tools/binman/etype/section.py
+++ b/tools/binman/etype/section.py
@@ -450,7 +450,7 @@ class Entry_section(Entry):
def _PackEntries(self):
"""Pack all entries into the section"""
offset = self._skip_at_start
- for entry in self._entries.values():
+ for entry in self.GetEntries().values():
offset = entry.Pack(offset)
return offset
@@ -533,7 +533,7 @@ class Entry_section(Entry):
for entry in self.GetEntries().values():
entry.WriteMap(fd, indent + 1)
- def GetEntries(self):
+ def GetEntries(self) -> dict[str, Entry]:
return self._entries
def GetContentsByPhandle(self, phandle, source_entry, required):
@@ -768,9 +768,17 @@ class Entry_section(Entry):
todo)
return True
- def drop_absent(self):
- """Drop entries which are absent"""
- self._entries = {n: e for n, e in self._entries.items() if not e.absent}
+ def drop_absent_optional(self) -> None:
+ """Drop entries which are absent.
+ Call for all nodes in the tree. Leaf nodes will do nothing per
+ definition. Sections however have _entries and should drop all children
+ which are absent.
+ """
+ self._entries = {n: e for n, e in self._entries.items() if not (e.absent and e.optional)}
+ # Drop nodes first before traversing children to avoid superfluous calls
+ # to children of absent nodes.
+ for e in self.GetEntries().values():
+ e.drop_absent_optional()
def _SetEntryOffsetSize(self, name, offset, size):
"""Set the offset and size of an entry
diff --git a/tools/binman/image.py b/tools/binman/image.py
index 24ce0af7c72b5256a9a71963a6d94c080ed8bdd4..86543ad8db36b38afc1957fde7e20152067b79aa 100644
--- a/tools/binman/image.py
+++ b/tools/binman/image.py
@@ -15,7 +15,7 @@ import sys
from binman.entry import Entry
from binman.etype import fdtmap
from binman.etype import image_header
-from binman.etype import section
+from etype import section
from dtoc import fdt
from dtoc import fdt_util
from u_boot_pylib import tools
@@ -183,6 +183,8 @@ class Image(section.Entry_section):
fname = tools.get_output_filename(self._filename)
tout.info("Writing image to '%s'" % fname)
with open(fname, 'wb') as fd:
+ # For final image, don't write absent blobs to file
+ self.drop_absent_optional()
data = self.GetPaddedData()
fd.write(data)
tout.info("Wrote %#x bytes" % len(data))
--
2.43.0
More information about the U-Boot
mailing list