
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 --- v2: - pass allow_fake_blobs to ProcessImage() - set AllowAllowFakeBlob() to images/entries - create fake blob in Entry_blot.ObtainContents() when file is missing and creation is allowed
still missing: - unittest - option to set BINMAN_FAKE_EXT_BLOBS in Makefile via environment variable. With that we could simply set this env variable in the CI (gitlab-ci.yml) with adding support to buildman.
Makefile | 1 + tools/binman/cmdline.py | 2 ++ tools/binman/control.py | 9 +++++++-- tools/binman/entry.py | 11 +++++++++++ tools/binman/etype/blob.py | 7 +++++++ tools/binman/etype/blob_ext.py | 8 ++++++++ tools/binman/etype/mkimage.py | 9 +++++++++ tools/binman/etype/section.py | 9 +++++++++ 8 files changed, 54 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile index f911f70344..1a833a1637 100644 --- a/Makefile +++ b/Makefile @@ -1307,6 +1307,7 @@ cmd_binman = $(srctree)/tools/binman/binman $(if $(BINMAN_DEBUG),-D) \ -a tpl-bss-pad=$(if $(CONFIG_TPL_SEPARATE_BSS),,1) \ -a spl-dtb=$(CONFIG_SPL_OF_REAL) \ -a tpl-dtb=$(CONFIG_SPL_OF_REAL) \ + $(if $(BINMAN_FAKE_EXT_BLOBS),--fake-ext-blobs) \ $(BINMAN_$(@F))
OBJCOPYFLAGS_u-boot.ldr.hex := -I binary -O ihex diff --git a/tools/binman/cmdline.py b/tools/binman/cmdline.py index d6156df408..2b29981cb4 100644 --- a/tools/binman/cmdline.py +++ b/tools/binman/cmdline.py @@ -52,6 +52,8 @@ controlled by a description in the board device tree.''' help='Configuration file (.dtb) to use') build_parser.add_argument('--fake-dtb', action='store_true', 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', help='Image filename to build (if not specified, build all)') build_parser.add_argument('-I', '--indir', action='append', diff --git a/tools/binman/control.py b/tools/binman/control.py index 0dbcbc28e9..fa034bddef 100644 --- a/tools/binman/control.py +++ b/tools/binman/control.py @@ -479,7 +479,8 @@ def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, use_expanded):
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.
This means that errors found with a later image will be reported after @@ -495,12 +496,14 @@ def ProcessImage(image, update_fdt, write_map, get_contents=True, 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 + allow_fake_blobs: Allow blob_ext objects to be faked with dummy files
Returns: True if one or more external blobs are missing, False if all are present """ if get_contents: image.SetAllowMissing(allow_missing) + image.SetAllowFakeBlob(allow_fake_blobs) image.GetEntryContents() image.GetEntryOffsets()
@@ -629,13 +632,15 @@ def Binman(args):
images = PrepareImagesAndDtbs(dtb_fname, args.image, args.update_fdt, use_expanded) + if args.test_section_timeout: # Set the first image to timeout, used in testThreadTimeout() images[list(images.keys())[0]].test_section_timeout = True missing = False for image in images.values(): missing |= 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 for dtb_item in state.GetAllFdts(): diff --git a/tools/binman/entry.py b/tools/binman/entry.py index 70222718ea..9aa4359be1 100644 --- a/tools/binman/entry.py +++ b/tools/binman/entry.py @@ -70,6 +70,8 @@ class Entry(object): missing: True if this entry is missing its contents allow_missing: Allow children of this entry to be missing (used by 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 """ def __init__(self, section, etype, node, name_prefix=''): @@ -100,6 +102,7 @@ class Entry(object): self.missing = False self.external = False self.allow_missing = False + self.allow_fake = False
@staticmethod def Lookup(node_path, etype, expanded): @@ -898,6 +901,14 @@ features to produce new behaviours. # This is meaningless for anything other than sections 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): """Check if any entries in this section have missing external blobs
diff --git a/tools/binman/etype/blob.py b/tools/binman/etype/blob.py index fae86ca3ec..0c7469409f 100644 --- a/tools/binman/etype/blob.py +++ b/tools/binman/etype/blob.py @@ -5,6 +5,8 @@ # Entry-type module for blobs, which are binary objects read from files #
+import pathlib + from binman.entry import Entry from binman import state from dtoc import fdt_util @@ -36,6 +38,11 @@ class Entry_blob(Entry): self._filename = fdt_util.GetString(self._node, 'filename', self.etype)
def ObtainContents(self): + if self.allow_fake and not pathlib.Path(self._filename).is_file(): + tout.Warning("Missing blob '%s', fake it" % self._filename) + with open(self._filename, "wb") as out: + out.truncate(1024) + self._filename = self.GetDefaultFilename() self._pathname = tools.GetInputFilename(self._filename, self.external and self.section.GetAllowMissing()) diff --git a/tools/binman/etype/blob_ext.py b/tools/binman/etype/blob_ext.py index d6b0ca17c3..fba6271de2 100644 --- a/tools/binman/etype/blob_ext.py +++ b/tools/binman/etype/blob_ext.py @@ -26,3 +26,11 @@ class Entry_blob_ext(Entry_blob): def __init__(self, section, etype, node): Entry_blob.__init__(self, section, etype, node) 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 diff --git a/tools/binman/etype/mkimage.py b/tools/binman/etype/mkimage.py index e49977522e..a797d9314e 100644 --- a/tools/binman/etype/mkimage.py +++ b/tools/binman/etype/mkimage.py @@ -61,3 +61,12 @@ class Entry_mkimage(Entry): entry = Entry.Create(self, node) entry.ReadNode() 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) diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py index e2949fc916..52cbbe0f73 100644 --- a/tools/binman/etype/section.py +++ b/tools/binman/etype/section.py @@ -689,6 +689,15 @@ class Entry_section(Entry): for entry in self._entries.values(): 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): """Check if any entries in this section have missing external blobs