summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/binman/README.entries3
-rw-r--r--tools/binman/cmdline.py2
-rw-r--r--tools/binman/control.py7
-rw-r--r--tools/binman/entry.py9
-rw-r--r--tools/binman/etype/blob_ext.py13
-rw-r--r--tools/binman/etype/section.py24
-rw-r--r--tools/binman/ftest.py8
-rw-r--r--tools/patman/tools.py8
8 files changed, 66 insertions, 8 deletions
diff --git a/tools/binman/README.entries b/tools/binman/README.entries
index 46f6ab1899..f45f51428a 100644
--- a/tools/binman/README.entries
+++ b/tools/binman/README.entries
@@ -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
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.
diff --git a/tools/binman/cmdline.py b/tools/binman/cmdline.py
index 1e38593579..bb4d9d1288 100644
--- a/tools/binman/cmdline.py
+++ b/tools/binman/cmdline.py
@@ -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')
build_parser.add_argument('-m', '--map', action='store_true',
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,
action='store', help='Path to directory to use for intermediate and '
'output files')
diff --git a/tools/binman/control.py b/tools/binman/control.py
index dc1dd2a7dc..8c6eae83f1 100644
--- a/tools/binman/control.py
+++ b/tools/binman/control.py
@@ -387,7 +387,7 @@ def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt):
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.
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
allow_resize: True to allow entries to change size (this does a re-pack
of the entries), False to raise an exception
+ allow_missing: Allow blob_ext objects to be missing
"""
if get_contents:
+ image.SetAllowMissing(allow_missing)
image.GetEntryContents()
image.GetEntryOffsets()
@@ -523,7 +525,8 @@ def Binman(args):
images = PrepareImagesAndDtbs(dtb_fname, args.image,
args.update_fdt)
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
for dtb_item in state.GetAllFdts():
diff --git a/tools/binman/entry.py b/tools/binman/entry.py
index 90ffd27617..9388586e7c 100644
--- a/tools/binman/entry.py
+++ b/tools/binman/entry.py
@@ -794,3 +794,12 @@ features to produce new behaviours.
elif self == entries[-1]:
return 'end'
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
diff --git a/tools/binman/etype/blob_ext.py b/tools/binman/etype/blob_ext.py
index cc8d91bb59..51779c88c9 100644
--- a/tools/binman/etype/blob_ext.py
+++ b/tools/binman/etype/blob_ext.py
@@ -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
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.
"""
def __init__(self, section, etype, node):
@@ -26,6 +29,10 @@ class Entry_blob_ext(Entry_blob):
def ObtainContents(self):
self._filename = self.GetDefaultFilename()
- self._pathname = tools.GetInputFilename(self._filename)
- self.ReadBlobContents()
- return True
+ self._pathname = tools.GetInputFilename(self._filename,
+ self.section.GetAllowMissing())
+ # Allow the file to be missing
+ if not self._pathname:
+ self.SetContents(b'')
+ return True
+ return super().ObtainContents()
diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py
index f108121c3a..9b718f1fa7 100644
--- a/tools/binman/etype/section.py
+++ b/tools/binman/etype/section.py
@@ -34,6 +34,11 @@ class Entry_section(Entry):
name-prefix: Adds a prefix to the name of every entry in the section
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
too.
@@ -49,6 +54,7 @@ class Entry_section(Entry):
self._sort = False
self._skip_at_start = None
self._end_4gb = False
+ self._allow_missing = False
def ReadNode(self):
"""Read properties from the image node"""
@@ -535,3 +541,21 @@ class Entry_section(Entry):
def WriteChildData(self, child):
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
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index f8d5191672..7c8b3eb3a0 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -285,7 +285,7 @@ class TestFunctional(unittest.TestCase):
def _DoTestFile(self, fname, debug=False, map=False, update_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
Args:
@@ -319,6 +319,8 @@ class TestFunctional(unittest.TestCase):
if entry_args:
for arg, value in entry_args.items():
args.append('-a%s=%s' % (arg, value))
+ if allow_missing:
+ args.append('-M')
if images:
for image in images:
args += ['-i', image]
@@ -3376,6 +3378,10 @@ class TestFunctional(unittest.TestCase):
self.assertIn("Filename 'missing-file' not found in input path",
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__":
unittest.main()
diff --git a/tools/patman/tools.py b/tools/patman/tools.py
index f402b9aab8..d41115a22c 100644
--- a/tools/patman/tools.py
+++ b/tools/patman/tools.py
@@ -114,14 +114,16 @@ def SetInputDirs(dirname):
indir = dirname
tout.Debug("Using input directories %s" % indir)
-def GetInputFilename(fname):
+def GetInputFilename(fname, allow_missing=False):
"""Return a filename for use as input.
Args:
fname: Filename to use for new file
+ allow_missing: True if the filename can be missing
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] == '/':
return fname
@@ -130,6 +132,8 @@ def GetInputFilename(fname):
if os.path.exists(pathname):
return pathname
+ if allow_missing:
+ return None
raise ValueError("Filename '%s' not found in input path (%s) (cwd='%s')" %
(fname, ','.join(indir), os.getcwd()))