1
0
mirror of https://xff.cz/git/u-boot/ synced 2025-09-03 09:42:22 +02:00

binman: Allow external binaries to be missing

Sometimes it is useful to build an image even though external binaries are
not present. This allows the build system to continue to function without
these files, albeit not producing valid images.

U-Boot does with with ATF (ARM Trusted Firmware) today.

Add a new flag to binman to request this behaviour.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
This commit is contained in:
Simon Glass
2020-07-09 18:39:38 -06:00
parent 04e6a6b9ec
commit 4f9f1056ec
8 changed files with 66 additions and 8 deletions

View File

@@ -48,6 +48,9 @@ Entry: blob-ext: Entry containing an externally built binary blob
Note: This should not be used by itself. It is normally used as a parent Note: This should not be used by itself. It is normally used as a parent
class by other entry types. class by other entry types.
If the file providing this blob is missing, binman can optionally ignore it
and produce a broken image with a warning.
See 'blob' for Properties / Entry arguments. See 'blob' for Properties / Entry arguments.

View File

@@ -53,6 +53,8 @@ controlled by a description in the board device tree.'''
help='Add a path to the list of directories to use for input files') help='Add a path to the list of directories to use for input files')
build_parser.add_argument('-m', '--map', action='store_true', build_parser.add_argument('-m', '--map', action='store_true',
default=False, help='Output a map file for each image') default=False, help='Output a map file for each image')
build_parser.add_argument('-M', '--allow-missing', action='store_true',
default=False, help='Allow external blobs to be missing')
build_parser.add_argument('-O', '--outdir', type=str, build_parser.add_argument('-O', '--outdir', type=str,
action='store', help='Path to directory to use for intermediate and ' action='store', help='Path to directory to use for intermediate and '
'output files') 'output files')

View File

@@ -387,7 +387,7 @@ def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt):
def ProcessImage(image, update_fdt, write_map, get_contents=True, def ProcessImage(image, update_fdt, write_map, get_contents=True,
allow_resize=True): allow_resize=True, allow_missing=False):
"""Perform all steps for this image, including checking and # writing it. """Perform all steps for this image, including checking and # writing it.
This means that errors found with a later image will be reported after This means that errors found with a later image will be reported after
@@ -402,8 +402,10 @@ def ProcessImage(image, update_fdt, write_map, get_contents=True,
the contents is already present the contents is already present
allow_resize: True to allow entries to change size (this does a re-pack allow_resize: True to allow entries to change size (this does a re-pack
of the entries), False to raise an exception of the entries), False to raise an exception
allow_missing: Allow blob_ext objects to be missing
""" """
if get_contents: if get_contents:
image.SetAllowMissing(allow_missing)
image.GetEntryContents() image.GetEntryContents()
image.GetEntryOffsets() image.GetEntryOffsets()
@@ -523,7 +525,8 @@ def Binman(args):
images = PrepareImagesAndDtbs(dtb_fname, args.image, images = PrepareImagesAndDtbs(dtb_fname, args.image,
args.update_fdt) args.update_fdt)
for image in images.values(): for image in images.values():
ProcessImage(image, args.update_fdt, args.map) ProcessImage(image, args.update_fdt, args.map,
allow_missing=args.allow_missing)
# Write the updated FDTs to our output files # Write the updated FDTs to our output files
for dtb_item in state.GetAllFdts(): for dtb_item in state.GetAllFdts():

View File

@@ -794,3 +794,12 @@ features to produce new behaviours.
elif self == entries[-1]: elif self == entries[-1]:
return 'end' return 'end'
return 'middle' return 'middle'
def SetAllowMissing(self, allow_missing):
"""Set whether a section allows missing external blobs
Args:
allow_missing: True if allowed, False if not allowed
"""
# This is meaningless for anything other than sections
pass

View File

@@ -18,6 +18,9 @@ class Entry_blob_ext(Entry_blob):
Note: This should not be used by itself. It is normally used as a parent Note: This should not be used by itself. It is normally used as a parent
class by other entry types. class by other entry types.
If the file providing this blob is missing, binman can optionally ignore it
and produce a broken image with a warning.
See 'blob' for Properties / Entry arguments. See 'blob' for Properties / Entry arguments.
""" """
def __init__(self, section, etype, node): def __init__(self, section, etype, node):
@@ -26,6 +29,10 @@ class Entry_blob_ext(Entry_blob):
def ObtainContents(self): def ObtainContents(self):
self._filename = self.GetDefaultFilename() self._filename = self.GetDefaultFilename()
self._pathname = tools.GetInputFilename(self._filename) self._pathname = tools.GetInputFilename(self._filename,
self.ReadBlobContents() self.section.GetAllowMissing())
return True # Allow the file to be missing
if not self._pathname:
self.SetContents(b'')
return True
return super().ObtainContents()

View File

@@ -34,6 +34,11 @@ class Entry_section(Entry):
name-prefix: Adds a prefix to the name of every entry in the section name-prefix: Adds a prefix to the name of every entry in the section
when writing out the map when writing out the map
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 Since a section is also an entry, it inherits all the properies of entries
too. too.
@@ -49,6 +54,7 @@ class Entry_section(Entry):
self._sort = False self._sort = False
self._skip_at_start = None self._skip_at_start = None
self._end_4gb = False self._end_4gb = False
self._allow_missing = False
def ReadNode(self): def ReadNode(self):
"""Read properties from the image node""" """Read properties from the image node"""
@@ -535,3 +541,21 @@ class Entry_section(Entry):
def WriteChildData(self, child): def WriteChildData(self, child):
return True return True
def SetAllowMissing(self, allow_missing):
"""Set whether a section allows missing external blobs
Args:
allow_missing: True if allowed, False if not allowed
"""
self._allow_missing = allow_missing
for entry in self._entries.values():
entry.SetAllowMissing(allow_missing)
def GetAllowMissing(self):
"""Get whether a section allows missing external blobs
Returns:
True if allowed, False if not allowed
"""
return self._allow_missing

View File

@@ -285,7 +285,7 @@ class TestFunctional(unittest.TestCase):
def _DoTestFile(self, fname, debug=False, map=False, update_dtb=False, def _DoTestFile(self, fname, debug=False, map=False, update_dtb=False,
entry_args=None, images=None, use_real_dtb=False, entry_args=None, images=None, use_real_dtb=False,
verbosity=None): verbosity=None, allow_missing=False):
"""Run binman with a given test file """Run binman with a given test file
Args: Args:
@@ -319,6 +319,8 @@ class TestFunctional(unittest.TestCase):
if entry_args: if entry_args:
for arg, value in entry_args.items(): for arg, value in entry_args.items():
args.append('-a%s=%s' % (arg, value)) args.append('-a%s=%s' % (arg, value))
if allow_missing:
args.append('-M')
if images: if images:
for image in images: for image in images:
args += ['-i', image] args += ['-i', image]
@@ -3376,6 +3378,10 @@ class TestFunctional(unittest.TestCase):
self.assertIn("Filename 'missing-file' not found in input path", self.assertIn("Filename 'missing-file' not found in input path",
str(e.exception)) str(e.exception))
def testExtblobMissingOk(self):
"""Test an image with an missing external blob that is allowed"""
self._DoTestFile('158_blob_ext_missing.dts', allow_missing=True)
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()

View File

@@ -114,14 +114,16 @@ def SetInputDirs(dirname):
indir = dirname indir = dirname
tout.Debug("Using input directories %s" % indir) tout.Debug("Using input directories %s" % indir)
def GetInputFilename(fname): def GetInputFilename(fname, allow_missing=False):
"""Return a filename for use as input. """Return a filename for use as input.
Args: Args:
fname: Filename to use for new file fname: Filename to use for new file
allow_missing: True if the filename can be missing
Returns: Returns:
The full path of the filename, within the input directory The full path of the filename, within the input directory, or
None on error
""" """
if not indir or fname[:1] == '/': if not indir or fname[:1] == '/':
return fname return fname
@@ -130,6 +132,8 @@ def GetInputFilename(fname):
if os.path.exists(pathname): if os.path.exists(pathname):
return pathname return pathname
if allow_missing:
return None
raise ValueError("Filename '%s' not found in input path (%s) (cwd='%s')" % raise ValueError("Filename '%s' not found in input path (%s) (cwd='%s')" %
(fname, ','.join(indir), os.getcwd())) (fname, ','.join(indir), os.getcwd()))