mirror of
https://github.com/smaeul/u-boot.git
synced 2025-10-17 14:18:14 +01:00
binman: add support for creating dummy files for external blobs
While converting to binman for an imx8mq board, it has been found that building in the u-boot CI fails. This is because an imx8mq requires an external binary (signed_hdmi_imx8m.bin). If this file cannot be found mkimage fails. To be able to build this board in the u-boot CI a binman option (--fake-ext-blobs) is introduced that can be switched on via the u-boot makefile option BINMAN_FAKE_EXT_BLOBS. With that the needed dummy files are created. Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
a14af7216a
commit
a89c8f2111
1
Makefile
1
Makefile
@ -1315,6 +1315,7 @@ cmd_binman = $(srctree)/tools/binman/binman $(if $(BINMAN_DEBUG),-D) \
|
|||||||
-a tpl-bss-pad=$(if $(CONFIG_TPL_SEPARATE_BSS),,1) \
|
-a tpl-bss-pad=$(if $(CONFIG_TPL_SEPARATE_BSS),,1) \
|
||||||
-a spl-dtb=$(CONFIG_SPL_OF_REAL) \
|
-a spl-dtb=$(CONFIG_SPL_OF_REAL) \
|
||||||
-a tpl-dtb=$(CONFIG_TPL_OF_REAL) \
|
-a tpl-dtb=$(CONFIG_TPL_OF_REAL) \
|
||||||
|
$(if $(BINMAN_FAKE_EXT_BLOBS),--fake-ext-blobs) \
|
||||||
$(BINMAN_$(@F))
|
$(BINMAN_$(@F))
|
||||||
|
|
||||||
OBJCOPYFLAGS_u-boot.ldr.hex := -I binary -O ihex
|
OBJCOPYFLAGS_u-boot.ldr.hex := -I binary -O ihex
|
||||||
|
@ -52,6 +52,8 @@ controlled by a description in the board device tree.'''
|
|||||||
help='Configuration file (.dtb) to use')
|
help='Configuration file (.dtb) to use')
|
||||||
build_parser.add_argument('--fake-dtb', action='store_true',
|
build_parser.add_argument('--fake-dtb', action='store_true',
|
||||||
help='Use fake device tree contents (for testing only)')
|
help='Use fake device tree contents (for testing only)')
|
||||||
|
build_parser.add_argument('--fake-ext-blobs', action='store_true',
|
||||||
|
help='Create fake ext blobs with dummy content (for testing only)')
|
||||||
build_parser.add_argument('-i', '--image', type=str, action='append',
|
build_parser.add_argument('-i', '--image', type=str, action='append',
|
||||||
help='Image filename to build (if not specified, build all)')
|
help='Image filename to build (if not specified, build all)')
|
||||||
build_parser.add_argument('-I', '--indir', action='append',
|
build_parser.add_argument('-I', '--indir', action='append',
|
||||||
|
@ -479,7 +479,8 @@ def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, use_expanded):
|
|||||||
|
|
||||||
|
|
||||||
def ProcessImage(image, update_fdt, write_map, get_contents=True,
|
def ProcessImage(image, update_fdt, write_map, get_contents=True,
|
||||||
allow_resize=True, allow_missing=False):
|
allow_resize=True, allow_missing=False,
|
||||||
|
allow_fake_blobs=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
|
||||||
@ -495,12 +496,15 @@ def ProcessImage(image, update_fdt, write_map, get_contents=True,
|
|||||||
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
|
allow_missing: Allow blob_ext objects to be missing
|
||||||
|
allow_fake_blobs: Allow blob_ext objects to be faked with dummy files
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True if one or more external blobs are missing, False if all are present
|
True if one or more external blobs are missing or faked,
|
||||||
|
False if all are present
|
||||||
"""
|
"""
|
||||||
if get_contents:
|
if get_contents:
|
||||||
image.SetAllowMissing(allow_missing)
|
image.SetAllowMissing(allow_missing)
|
||||||
|
image.SetAllowFakeBlob(allow_fake_blobs)
|
||||||
image.GetEntryContents()
|
image.GetEntryContents()
|
||||||
image.GetEntryOffsets()
|
image.GetEntryOffsets()
|
||||||
|
|
||||||
@ -549,7 +553,13 @@ def ProcessImage(image, update_fdt, write_map, get_contents=True,
|
|||||||
tout.Warning("Image '%s' is missing external blobs and is non-functional: %s" %
|
tout.Warning("Image '%s' is missing external blobs and is non-functional: %s" %
|
||||||
(image.name, ' '.join([e.name for e in missing_list])))
|
(image.name, ' '.join([e.name for e in missing_list])))
|
||||||
_ShowHelpForMissingBlobs(missing_list)
|
_ShowHelpForMissingBlobs(missing_list)
|
||||||
return bool(missing_list)
|
faked_list = []
|
||||||
|
image.CheckFakedBlobs(faked_list)
|
||||||
|
if faked_list:
|
||||||
|
tout.Warning("Image '%s:%s' has faked external blobs and is non-functional: %s" %
|
||||||
|
(image.name, image.image_name,
|
||||||
|
' '.join([e.GetDefaultFilename() for e in faked_list])))
|
||||||
|
return bool(missing_list) or bool(faked_list)
|
||||||
|
|
||||||
|
|
||||||
def Binman(args):
|
def Binman(args):
|
||||||
@ -636,13 +646,15 @@ def Binman(args):
|
|||||||
|
|
||||||
images = PrepareImagesAndDtbs(dtb_fname, args.image,
|
images = PrepareImagesAndDtbs(dtb_fname, args.image,
|
||||||
args.update_fdt, use_expanded)
|
args.update_fdt, use_expanded)
|
||||||
|
|
||||||
if args.test_section_timeout:
|
if args.test_section_timeout:
|
||||||
# Set the first image to timeout, used in testThreadTimeout()
|
# Set the first image to timeout, used in testThreadTimeout()
|
||||||
images[list(images.keys())[0]].test_section_timeout = True
|
images[list(images.keys())[0]].test_section_timeout = True
|
||||||
missing = False
|
invalid = False
|
||||||
for image in images.values():
|
for image in images.values():
|
||||||
missing |= ProcessImage(image, args.update_fdt, args.map,
|
invalid |= ProcessImage(image, args.update_fdt, args.map,
|
||||||
allow_missing=args.allow_missing)
|
allow_missing=args.allow_missing,
|
||||||
|
allow_fake_blobs=args.fake_ext_blobs)
|
||||||
|
|
||||||
# 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():
|
||||||
@ -652,7 +664,7 @@ def Binman(args):
|
|||||||
data = state.GetFdtForEtype('u-boot-dtb').GetContents()
|
data = state.GetFdtForEtype('u-boot-dtb').GetContents()
|
||||||
elf.UpdateFile(*elf_params, data)
|
elf.UpdateFile(*elf_params, data)
|
||||||
|
|
||||||
if missing:
|
if invalid:
|
||||||
tout.Warning("\nSome images are invalid")
|
tout.Warning("\nSome images are invalid")
|
||||||
|
|
||||||
# Use this to debug the time take to pack the image
|
# Use this to debug the time take to pack the image
|
||||||
|
@ -70,6 +70,8 @@ class Entry(object):
|
|||||||
missing: True if this entry is missing its contents
|
missing: True if this entry is missing its contents
|
||||||
allow_missing: Allow children of this entry to be missing (used by
|
allow_missing: Allow children of this entry to be missing (used by
|
||||||
subclasses such as Entry_section)
|
subclasses such as Entry_section)
|
||||||
|
allow_fake: Allow creating a dummy fake file if the blob file is not
|
||||||
|
available. This is mainly used for testing.
|
||||||
external: True if this entry contains an external binary blob
|
external: True if this entry contains an external binary blob
|
||||||
"""
|
"""
|
||||||
def __init__(self, section, etype, node, name_prefix=''):
|
def __init__(self, section, etype, node, name_prefix=''):
|
||||||
@ -98,8 +100,10 @@ class Entry(object):
|
|||||||
self._expand_size = False
|
self._expand_size = False
|
||||||
self.compress = 'none'
|
self.compress = 'none'
|
||||||
self.missing = False
|
self.missing = False
|
||||||
|
self.faked = False
|
||||||
self.external = False
|
self.external = False
|
||||||
self.allow_missing = False
|
self.allow_missing = False
|
||||||
|
self.allow_fake = False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def Lookup(node_path, etype, expanded):
|
def Lookup(node_path, etype, expanded):
|
||||||
@ -898,6 +902,14 @@ features to produce new behaviours.
|
|||||||
# This is meaningless for anything other than sections
|
# This is meaningless for anything other than sections
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def SetAllowFakeBlob(self, allow_fake):
|
||||||
|
"""Set whether a section allows to create a fake blob
|
||||||
|
|
||||||
|
Args:
|
||||||
|
allow_fake: True if allowed, False if not allowed
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
def CheckMissing(self, missing_list):
|
def CheckMissing(self, missing_list):
|
||||||
"""Check if any entries in this section have missing external blobs
|
"""Check if any entries in this section have missing external blobs
|
||||||
|
|
||||||
@ -909,6 +921,17 @@ features to produce new behaviours.
|
|||||||
if self.missing:
|
if self.missing:
|
||||||
missing_list.append(self)
|
missing_list.append(self)
|
||||||
|
|
||||||
|
def CheckFakedBlobs(self, faked_blobs_list):
|
||||||
|
"""Check if any entries in this section have faked external blobs
|
||||||
|
|
||||||
|
If there are faked blobs, the entries are added to the list
|
||||||
|
|
||||||
|
Args:
|
||||||
|
fake_blobs_list: List of Entry objects to be added to
|
||||||
|
"""
|
||||||
|
# This is meaningless for anything other than blobs
|
||||||
|
pass
|
||||||
|
|
||||||
def GetAllowMissing(self):
|
def GetAllowMissing(self):
|
||||||
"""Get whether a section allows missing external blobs
|
"""Get whether a section allows missing external blobs
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
# Entry-type module for blobs, which are binary objects read from files
|
# Entry-type module for blobs, which are binary objects read from files
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import pathlib
|
||||||
|
|
||||||
from binman.entry import Entry
|
from binman.entry import Entry
|
||||||
from binman import state
|
from binman import state
|
||||||
from dtoc import fdt_util
|
from dtoc import fdt_util
|
||||||
@ -36,6 +38,11 @@ class Entry_blob(Entry):
|
|||||||
self._filename = fdt_util.GetString(self._node, 'filename', self.etype)
|
self._filename = fdt_util.GetString(self._node, 'filename', self.etype)
|
||||||
|
|
||||||
def ObtainContents(self):
|
def ObtainContents(self):
|
||||||
|
if self.allow_fake and not pathlib.Path(self._filename).is_file():
|
||||||
|
with open(self._filename, "wb") as out:
|
||||||
|
out.truncate(1024)
|
||||||
|
self.faked = True
|
||||||
|
|
||||||
self._filename = self.GetDefaultFilename()
|
self._filename = self.GetDefaultFilename()
|
||||||
self._pathname = tools.GetInputFilename(self._filename,
|
self._pathname = tools.GetInputFilename(self._filename,
|
||||||
self.external and self.section.GetAllowMissing())
|
self.external and self.section.GetAllowMissing())
|
||||||
@ -75,3 +82,14 @@ class Entry_blob(Entry):
|
|||||||
def ProcessContents(self):
|
def ProcessContents(self):
|
||||||
# The blob may have changed due to WriteSymbols()
|
# The blob may have changed due to WriteSymbols()
|
||||||
return self.ProcessContentsUpdate(self.data)
|
return self.ProcessContentsUpdate(self.data)
|
||||||
|
|
||||||
|
def CheckFakedBlobs(self, faked_blobs_list):
|
||||||
|
"""Check if any entries in this section have faked external blobs
|
||||||
|
|
||||||
|
If there are faked blobs, the entries are added to the list
|
||||||
|
|
||||||
|
Args:
|
||||||
|
fake_blobs_list: List of Entry objects to be added to
|
||||||
|
"""
|
||||||
|
if self.faked:
|
||||||
|
faked_blobs_list.append(self)
|
||||||
|
@ -26,3 +26,11 @@ class Entry_blob_ext(Entry_blob):
|
|||||||
def __init__(self, section, etype, node):
|
def __init__(self, section, etype, node):
|
||||||
Entry_blob.__init__(self, section, etype, node)
|
Entry_blob.__init__(self, section, etype, node)
|
||||||
self.external = True
|
self.external = True
|
||||||
|
|
||||||
|
def SetAllowFakeBlob(self, allow_fake):
|
||||||
|
"""Set whether the entry allows to create a fake blob
|
||||||
|
|
||||||
|
Args:
|
||||||
|
allow_fake_blob: True if allowed, False if not allowed
|
||||||
|
"""
|
||||||
|
self.allow_fake = allow_fake
|
||||||
|
@ -61,3 +61,23 @@ class Entry_mkimage(Entry):
|
|||||||
entry = Entry.Create(self, node)
|
entry = Entry.Create(self, node)
|
||||||
entry.ReadNode()
|
entry.ReadNode()
|
||||||
self._mkimage_entries[entry.name] = entry
|
self._mkimage_entries[entry.name] = entry
|
||||||
|
|
||||||
|
def SetAllowFakeBlob(self, allow_fake):
|
||||||
|
"""Set whether the sub nodes allows to create a fake blob
|
||||||
|
|
||||||
|
Args:
|
||||||
|
allow_fake: True if allowed, False if not allowed
|
||||||
|
"""
|
||||||
|
for entry in self._mkimage_entries.values():
|
||||||
|
entry.SetAllowFakeBlob(allow_fake)
|
||||||
|
|
||||||
|
def CheckFakedBlobs(self, faked_blobs_list):
|
||||||
|
"""Check if any entries in this section have faked external blobs
|
||||||
|
|
||||||
|
If there are faked blobs, the entries are added to the list
|
||||||
|
|
||||||
|
Args:
|
||||||
|
faked_blobs_list: List of Entry objects to be added to
|
||||||
|
"""
|
||||||
|
for entry in self._mkimage_entries.values():
|
||||||
|
entry.CheckFakedBlobs(faked_blobs_list)
|
||||||
|
@ -689,6 +689,15 @@ class Entry_section(Entry):
|
|||||||
for entry in self._entries.values():
|
for entry in self._entries.values():
|
||||||
entry.SetAllowMissing(allow_missing)
|
entry.SetAllowMissing(allow_missing)
|
||||||
|
|
||||||
|
def SetAllowFakeBlob(self, allow_fake):
|
||||||
|
"""Set whether a section allows to create a fake blob
|
||||||
|
|
||||||
|
Args:
|
||||||
|
allow_fake_blob: True if allowed, False if not allowed
|
||||||
|
"""
|
||||||
|
for entry in self._entries.values():
|
||||||
|
entry.SetAllowFakeBlob(allow_fake)
|
||||||
|
|
||||||
def CheckMissing(self, missing_list):
|
def CheckMissing(self, missing_list):
|
||||||
"""Check if any entries in this section have missing external blobs
|
"""Check if any entries in this section have missing external blobs
|
||||||
|
|
||||||
@ -700,6 +709,17 @@ class Entry_section(Entry):
|
|||||||
for entry in self._entries.values():
|
for entry in self._entries.values():
|
||||||
entry.CheckMissing(missing_list)
|
entry.CheckMissing(missing_list)
|
||||||
|
|
||||||
|
def CheckFakedBlobs(self, faked_blobs_list):
|
||||||
|
"""Check if any entries in this section have faked external blobs
|
||||||
|
|
||||||
|
If there are faked blobs, the entries are added to the list
|
||||||
|
|
||||||
|
Args:
|
||||||
|
fake_blobs_list: List of Entry objects to be added to
|
||||||
|
"""
|
||||||
|
for entry in self._entries.values():
|
||||||
|
entry.CheckFakedBlobs(faked_blobs_list)
|
||||||
|
|
||||||
def _CollectEntries(self, entries, entries_by_name, add_entry):
|
def _CollectEntries(self, entries, entries_by_name, add_entry):
|
||||||
"""Collect all the entries in an section
|
"""Collect all the entries in an section
|
||||||
|
|
||||||
|
@ -308,7 +308,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,
|
||||||
use_expanded=False, verbosity=None, allow_missing=False,
|
use_expanded=False, verbosity=None, allow_missing=False,
|
||||||
extra_indirs=None, threads=None,
|
allow_fake_blobs=False, extra_indirs=None, threads=None,
|
||||||
test_section_timeout=False, update_fdt_in_elf=None):
|
test_section_timeout=False, update_fdt_in_elf=None):
|
||||||
"""Run binman with a given test file
|
"""Run binman with a given test file
|
||||||
|
|
||||||
@ -331,6 +331,7 @@ class TestFunctional(unittest.TestCase):
|
|||||||
verbosity: Verbosity level to use (0-3, None=don't set it)
|
verbosity: Verbosity level to use (0-3, None=don't set it)
|
||||||
allow_missing: Set the '--allow-missing' flag so that missing
|
allow_missing: Set the '--allow-missing' flag so that missing
|
||||||
external binaries just produce a warning instead of an error
|
external binaries just produce a warning instead of an error
|
||||||
|
allow_fake_blobs: Set the '--fake-ext-blobs' flag
|
||||||
extra_indirs: Extra input directories to add using -I
|
extra_indirs: Extra input directories to add using -I
|
||||||
threads: Number of threads to use (None for default, 0 for
|
threads: Number of threads to use (None for default, 0 for
|
||||||
single-threaded)
|
single-threaded)
|
||||||
@ -369,6 +370,8 @@ class TestFunctional(unittest.TestCase):
|
|||||||
args.append('-a%s=%s' % (arg, value))
|
args.append('-a%s=%s' % (arg, value))
|
||||||
if allow_missing:
|
if allow_missing:
|
||||||
args.append('-M')
|
args.append('-M')
|
||||||
|
if allow_fake_blobs:
|
||||||
|
args.append('--fake-ext-blobs')
|
||||||
if update_fdt_in_elf:
|
if update_fdt_in_elf:
|
||||||
args += ['--update-fdt-in-elf', update_fdt_in_elf]
|
args += ['--update-fdt-in-elf', update_fdt_in_elf]
|
||||||
if images:
|
if images:
|
||||||
@ -4661,6 +4664,16 @@ class TestFunctional(unittest.TestCase):
|
|||||||
str(e.exception),
|
str(e.exception),
|
||||||
"Not enough space in '.*u_boot_binman_embed_sm' for data length.*")
|
"Not enough space in '.*u_boot_binman_embed_sm' for data length.*")
|
||||||
|
|
||||||
|
def testFakeBlob(self):
|
||||||
|
"""Test handling of faking an external blob"""
|
||||||
|
with test_util.capture_sys_output() as (stdout, stderr):
|
||||||
|
self._DoTestFile('203_fake_blob.dts', allow_missing=True,
|
||||||
|
allow_fake_blobs=True)
|
||||||
|
err = stderr.getvalue()
|
||||||
|
self.assertRegex(err,
|
||||||
|
"Image '.*' has faked external blobs and is non-functional: .*")
|
||||||
|
os.remove('binman_faking_test_blob')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
14
tools/binman/test/203_fake_blob.dts
Normal file
14
tools/binman/test/203_fake_blob.dts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
/dts-v1/;
|
||||||
|
|
||||||
|
/ {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
|
||||||
|
binman {
|
||||||
|
blob-ext {
|
||||||
|
filename = "binman_faking_test_blob";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user