summaryrefslogtreecommitdiff
path: root/tools/binman
diff options
context:
space:
mode:
Diffstat (limited to 'tools/binman')
-rw-r--r--tools/binman/README.entries76
-rw-r--r--tools/binman/cmdline.py2
-rw-r--r--tools/binman/control.py19
-rw-r--r--tools/binman/entry.py21
-rw-r--r--tools/binman/etype/_testing.py9
-rw-r--r--tools/binman/etype/blob.py2
-rw-r--r--tools/binman/etype/blob_dtb.py6
-rw-r--r--tools/binman/etype/blob_ext.py39
-rw-r--r--tools/binman/etype/blob_named_by_arg.py2
-rw-r--r--tools/binman/etype/cbfs.py16
-rw-r--r--tools/binman/etype/cros_ec_rw.py4
-rw-r--r--tools/binman/etype/fdtmap.py2
-rw-r--r--tools/binman/etype/files.py2
-rw-r--r--tools/binman/etype/fill.py4
-rw-r--r--tools/binman/etype/fit.py164
-rw-r--r--tools/binman/etype/fmap.py2
-rw-r--r--tools/binman/etype/gbb.py2
-rw-r--r--tools/binman/etype/image_header.py4
-rw-r--r--tools/binman/etype/intel_cmc.py7
-rw-r--r--tools/binman/etype/intel_descriptor.py15
-rw-r--r--tools/binman/etype/intel_fit.py8
-rw-r--r--tools/binman/etype/intel_fit_ptr.py8
-rw-r--r--tools/binman/etype/intel_fsp.py7
-rw-r--r--tools/binman/etype/intel_fsp_m.py7
-rw-r--r--tools/binman/etype/intel_fsp_s.py7
-rw-r--r--tools/binman/etype/intel_fsp_t.py7
-rw-r--r--tools/binman/etype/intel_ifwi.py25
-rw-r--r--tools/binman/etype/intel_me.py9
-rw-r--r--tools/binman/etype/intel_mrc.py7
-rw-r--r--tools/binman/etype/intel_refcode.py7
-rw-r--r--tools/binman/etype/intel_vbt.py7
-rw-r--r--tools/binman/etype/intel_vga.py7
-rw-r--r--tools/binman/etype/mkimage.py62
-rw-r--r--tools/binman/etype/powerpc_mpc85xx_bootpg_resetvec.py5
-rw-r--r--tools/binman/etype/section.py58
-rw-r--r--tools/binman/etype/text.py2
-rw-r--r--tools/binman/etype/u_boot.py2
-rw-r--r--tools/binman/etype/u_boot_dtb.py2
-rw-r--r--tools/binman/etype/u_boot_dtb_with_ucode.py4
-rw-r--r--tools/binman/etype/u_boot_elf.py4
-rw-r--r--tools/binman/etype/u_boot_img.py2
-rw-r--r--tools/binman/etype/u_boot_nodtb.py2
-rw-r--r--tools/binman/etype/u_boot_spl.py2
-rw-r--r--tools/binman/etype/u_boot_spl_bss_pad.py2
-rw-r--r--tools/binman/etype/u_boot_spl_dtb.py2
-rw-r--r--tools/binman/etype/u_boot_spl_elf.py2
-rw-r--r--tools/binman/etype/u_boot_spl_nodtb.py2
-rw-r--r--tools/binman/etype/u_boot_spl_with_ucode_ptr.py2
-rw-r--r--tools/binman/etype/u_boot_tpl.py2
-rw-r--r--tools/binman/etype/u_boot_tpl_dtb.py2
-rw-r--r--tools/binman/etype/u_boot_tpl_dtb_with_ucode.py2
-rw-r--r--tools/binman/etype/u_boot_tpl_elf.py2
-rw-r--r--tools/binman/etype/u_boot_tpl_with_ucode_ptr.py2
-rw-r--r--tools/binman/etype/u_boot_ucode.py2
-rw-r--r--tools/binman/etype/u_boot_with_ucode_ptr.py2
-rw-r--r--tools/binman/etype/vblock.py2
-rw-r--r--tools/binman/etype/x86_reset16.py2
-rw-r--r--tools/binman/etype/x86_reset16_spl.py2
-rw-r--r--tools/binman/etype/x86_reset16_tpl.py2
-rw-r--r--tools/binman/etype/x86_start16.py2
-rw-r--r--tools/binman/etype/x86_start16_spl.py2
-rw-r--r--tools/binman/etype/x86_start16_tpl.py2
-rw-r--r--tools/binman/ftest.py140
-rw-r--r--tools/binman/image.py12
-rwxr-xr-xtools/binman/main.py18
-rw-r--r--tools/binman/test/156_mkimage.dts23
-rw-r--r--tools/binman/test/157_blob_ext.dts14
-rw-r--r--tools/binman/test/158_blob_ext_missing.dts16
-rw-r--r--tools/binman/test/159_blob_ext_missing_sect.dts23
-rw-r--r--tools/binman/test/160_pack_overlap_zero.dts18
-rw-r--r--tools/binman/test/161_fit.dts62
-rw-r--r--tools/binman/test/162_fit_external.dts64
72 files changed, 926 insertions, 151 deletions
diff --git a/tools/binman/README.entries b/tools/binman/README.entries
index 6a816bba6b..bf8edce02b 100644
--- a/tools/binman/README.entries
+++ b/tools/binman/README.entries
@@ -42,6 +42,19 @@ obtained from the list of available device-tree files, managed by the
+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.
+
+
+
Entry: blob-named-by-arg: A blob entry which gets its filename property from its subclass
-----------------------------------------------------------------------------------------
@@ -298,6 +311,46 @@ byte value of a region.
+Entry: fit: Entry containing a FIT
+----------------------------------
+
+This calls mkimage to create a FIT (U-Boot Flat Image Tree) based on the
+input provided.
+
+Nodes for the FIT should be written out in the binman configuration just as
+they would be in a file passed to mkimage.
+
+For example, this creates an image containing a FIT with U-Boot SPL:
+
+ binman {
+ fit {
+ description = "Test FIT";
+
+ images {
+ kernel@1 {
+ description = "SPL";
+ os = "u-boot";
+ type = "rkspi";
+ arch = "arm";
+ compression = "none";
+ load = <0>;
+ entry = <0>;
+
+ u-boot-spl {
+ };
+ };
+ };
+ };
+ };
+
+Properties:
+ fit,external-offset: Indicates that the contents of the FIT are external
+ and provides the external offset. This is passsed to mkimage via
+ the -E and -p flags.
+
+
+
+
Entry: fmap: An entry which contains an Fmap section
----------------------------------------------------
@@ -587,6 +640,29 @@ See README.x86 for information about Intel binary blobs.
+Entry: mkimage: Entry containing a binary produced by mkimage
+-------------------------------------------------------------
+
+Properties / Entry arguments:
+ - datafile: Filename for -d argument
+ - args: Other arguments to pass
+
+The data passed to mkimage is collected from subnodes of the mkimage node,
+e.g.:
+
+ mkimage {
+ args = "-n test -T imximage";
+
+ u-boot-spl {
+ };
+ };
+
+This calls mkimage to create an imximage with u-boot-spl.bin as the input
+file. The output from mkimage then becomes part of the image produced by
+binman.
+
+
+
Entry: powerpc-mpc85xx-bootpg-resetvec: PowerPC mpc85xx bootpg + resetvec code for U-Boot
-----------------------------------------------------------------------------------------
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..343b0a0c35 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,13 @@ 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
+
+ Returns:
+ True if one or more external blobs are missing, False if all are present
"""
if get_contents:
+ image.SetAllowMissing(allow_missing)
image.GetEntryContents()
image.GetEntryOffsets()
@@ -448,6 +453,12 @@ def ProcessImage(image, update_fdt, write_map, get_contents=True,
image.BuildImage()
if write_map:
image.WriteMap()
+ missing_list = []
+ image.CheckMissing(missing_list)
+ if missing_list:
+ tout.Warning("Image '%s' is missing external blobs and is non-functional: %s" %
+ (image.name, ' '.join([e.name for e in missing_list])))
+ return bool(missing_list)
def Binman(args):
@@ -522,13 +533,17 @@ def Binman(args):
images = PrepareImagesAndDtbs(dtb_fname, args.image,
args.update_fdt)
+ missing = False
for image in images.values():
- ProcessImage(image, args.update_fdt, args.map)
+ missing |= 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():
tools.WriteFile(dtb_item._fname, dtb_item.GetContents())
+ if missing:
+ tout.Warning("Some images are invalid")
finally:
tools.FinaliseOutputDir()
finally:
diff --git a/tools/binman/entry.py b/tools/binman/entry.py
index 90ffd27617..3434a3f804 100644
--- a/tools/binman/entry.py
+++ b/tools/binman/entry.py
@@ -84,6 +84,7 @@ class Entry(object):
self.image_pos = None
self._expand_size = False
self.compress = 'none'
+ self.missing = False
@staticmethod
def Lookup(node_path, etype):
@@ -794,3 +795,23 @@ 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
+
+ def CheckMissing(self, missing_list):
+ """Check if any entries in this section have missing external blobs
+
+ If there are missing blobs, the entries are added to the list
+
+ Args:
+ missing_list: List of Entry objects to be added to
+ """
+ if self.missing:
+ missing_list.append(self)
diff --git a/tools/binman/etype/_testing.py b/tools/binman/etype/_testing.py
index ed718eed14..0800c25899 100644
--- a/tools/binman/etype/_testing.py
+++ b/tools/binman/etype/_testing.py
@@ -41,10 +41,10 @@ class Entry__testing(Entry):
data type (generating an error)
"""
def __init__(self, section, etype, node):
- Entry.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def ReadNode(self):
- Entry.ReadNode(self)
+ super().ReadNode()
self.return_invalid_entry = fdt_util.GetBool(self._node,
'return-invalid-entry')
self.return_unknown_contents = fdt_util.GetBool(self._node,
@@ -57,6 +57,8 @@ class Entry__testing(Entry):
'return-contents-once')
self.bad_update_contents_twice = fdt_util.GetBool(self._node,
'bad-update-contents-twice')
+ self.return_contents_later = fdt_util.GetBool(self._node,
+ 'return-contents-later')
# Set to True when the entry is ready to process the FDT.
self.process_fdt_ready = False
@@ -83,6 +85,9 @@ class Entry__testing(Entry):
def ObtainContents(self):
if self.return_unknown_contents or not self.return_contents:
return False
+ if self.return_contents_later:
+ self.return_contents_later = False
+ return False
self.data = self.contents
self.contents_size = len(self.data)
if self.return_contents_once:
diff --git a/tools/binman/etype/blob.py b/tools/binman/etype/blob.py
index ede7a7a68c..e507203709 100644
--- a/tools/binman/etype/blob.py
+++ b/tools/binman/etype/blob.py
@@ -31,7 +31,7 @@ class Entry_blob(Entry):
data.
"""
def __init__(self, section, etype, node):
- Entry.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
self._filename = fdt_util.GetString(self._node, 'filename', self.etype)
self.compress = fdt_util.GetString(self._node, 'compress', 'none')
diff --git a/tools/binman/etype/blob_dtb.py b/tools/binman/etype/blob_dtb.py
index 6c06943763..724647a7bb 100644
--- a/tools/binman/etype/blob_dtb.py
+++ b/tools/binman/etype/blob_dtb.py
@@ -20,13 +20,13 @@ class Entry_blob_dtb(Entry_blob):
global state
from binman import state
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def ObtainContents(self):
"""Get the device-tree from the list held by the 'state' module"""
self._filename = self.GetDefaultFilename()
self._pathname, _ = state.GetFdtContents(self.GetFdtEtype())
- return Entry_blob.ReadBlobContents(self)
+ return super().ReadBlobContents()
def ProcessContents(self):
"""Re-read the DTB contents so that we get any calculated properties"""
@@ -57,7 +57,7 @@ class Entry_blob_dtb(Entry_blob):
return {self.GetFdtEtype(): [self, fname]}
def WriteData(self, data, decomp=True):
- ok = Entry_blob.WriteData(self, data, decomp)
+ ok = super().WriteData(data, decomp)
# Update the state module, since it has the authoritative record of the
# device trees used. If we don't do this, then state.GetFdtContents()
diff --git a/tools/binman/etype/blob_ext.py b/tools/binman/etype/blob_ext.py
new file mode 100644
index 0000000000..8d641001a9
--- /dev/null
+++ b/tools/binman/etype/blob_ext.py
@@ -0,0 +1,39 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2016 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# Entry-type module for external blobs, not built by U-Boot
+#
+
+import os
+
+from binman.etype.blob import Entry_blob
+from dtoc import fdt_util
+from patman import tools
+from patman import tout
+
+class Entry_blob_ext(Entry_blob):
+ """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.
+ """
+ def __init__(self, section, etype, node):
+ Entry_blob.__init__(self, section, etype, node)
+ self.external = True
+
+ def ObtainContents(self):
+ self._filename = self.GetDefaultFilename()
+ self._pathname = tools.GetInputFilename(self._filename,
+ self.section.GetAllowMissing())
+ # Allow the file to be missing
+ if not self._pathname:
+ self.SetContents(b'')
+ self.missing = True
+ return True
+ return super().ObtainContents()
diff --git a/tools/binman/etype/blob_named_by_arg.py b/tools/binman/etype/blob_named_by_arg.py
index 3b4593f071..e95dabe4d0 100644
--- a/tools/binman/etype/blob_named_by_arg.py
+++ b/tools/binman/etype/blob_named_by_arg.py
@@ -29,6 +29,6 @@ class Entry_blob_named_by_arg(Entry_blob):
See cros_ec_rw for an example of this.
"""
def __init__(self, section, etype, node, blob_fname):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
self._filename, = self.GetEntryArgsOrProps(
[EntryArg('%s-path' % blob_fname, str)])
diff --git a/tools/binman/etype/cbfs.py b/tools/binman/etype/cbfs.py
index e9aed8310c..650ab2c292 100644
--- a/tools/binman/etype/cbfs.py
+++ b/tools/binman/etype/cbfs.py
@@ -167,7 +167,7 @@ class Entry_cbfs(Entry):
global state
from binman import state
- Entry.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
self._cbfs_arg = fdt_util.GetString(node, 'cbfs-arch', 'x86')
self._cbfs_entries = OrderedDict()
self._ReadSubnodes()
@@ -204,7 +204,7 @@ class Entry_cbfs(Entry):
return True
def _ReadSubnodes(self):
- """Read the subnodes to find out what should go in this IFWI"""
+ """Read the subnodes to find out what should go in this CBFS"""
for node in self._node.subnodes:
entry = Entry.Create(self, node)
entry.ReadNode()
@@ -226,7 +226,7 @@ class Entry_cbfs(Entry):
Args:
image_pos: Position of this entry in the image
"""
- Entry.SetImagePos(self, image_pos)
+ super().SetImagePos(image_pos)
# Now update the entries with info from the CBFS entries
for entry in self._cbfs_entries.values():
@@ -238,7 +238,7 @@ class Entry_cbfs(Entry):
entry.uncomp_size = cfile.memlen
def AddMissingProperties(self):
- Entry.AddMissingProperties(self)
+ super().AddMissingProperties()
for entry in self._cbfs_entries.values():
entry.AddMissingProperties()
if entry._cbfs_compress:
@@ -250,7 +250,7 @@ class Entry_cbfs(Entry):
def SetCalculatedProperties(self):
"""Set the value of device-tree properties calculated by binman"""
- Entry.SetCalculatedProperties(self)
+ super().SetCalculatedProperties()
for entry in self._cbfs_entries.values():
state.SetInt(entry._node, 'offset', entry.offset)
state.SetInt(entry._node, 'size', entry.size)
@@ -260,7 +260,7 @@ class Entry_cbfs(Entry):
def ListEntries(self, entries, indent):
"""Override this method to list all files in the section"""
- Entry.ListEntries(self, entries, indent)
+ super().ListEntries(entries, indent)
for entry in self._cbfs_entries.values():
entry.ListEntries(entries, indent + 1)
@@ -268,12 +268,12 @@ class Entry_cbfs(Entry):
return self._cbfs_entries
def ReadData(self, decomp=True):
- data = Entry.ReadData(self, True)
+ data = super().ReadData(True)
return data
def ReadChildData(self, child, decomp=True):
if not self.reader:
- data = Entry.ReadData(self, True)
+ data = super().ReadData(True)
self.reader = cbfs_util.CbfsReader(data)
reader = self.reader
cfile = reader.files.get(child.name)
diff --git a/tools/binman/etype/cros_ec_rw.py b/tools/binman/etype/cros_ec_rw.py
index 0dbe14b342..741372e1af 100644
--- a/tools/binman/etype/cros_ec_rw.py
+++ b/tools/binman/etype/cros_ec_rw.py
@@ -18,5 +18,5 @@ class Entry_cros_ec_rw(Entry_blob_named_by_arg):
updating the EC on startup via software sync.
"""
def __init__(self, section, etype, node):
- Entry_blob_named_by_arg.__init__(self, section, etype, node,
- 'cros-ec-rw')
+ super().__init__(section, etype, node, 'cros-ec-rw')
+ self.external = True
diff --git a/tools/binman/etype/fdtmap.py b/tools/binman/etype/fdtmap.py
index aa8807990b..6ca88a100e 100644
--- a/tools/binman/etype/fdtmap.py
+++ b/tools/binman/etype/fdtmap.py
@@ -85,7 +85,7 @@ class Entry_fdtmap(Entry):
from binman import state
from dtoc.fdt import Fdt
- Entry.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def _GetFdtmap(self):
"""Build an FDT map from the entries in the current image
diff --git a/tools/binman/etype/files.py b/tools/binman/etype/files.py
index 10ab585f0e..9adb3afeb1 100644
--- a/tools/binman/etype/files.py
+++ b/tools/binman/etype/files.py
@@ -32,7 +32,7 @@ class Entry_files(Entry_section):
global state
from binman import state
- Entry_section.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
self._pattern = fdt_util.GetString(self._node, 'pattern')
if not self._pattern:
self.Raise("Missing 'pattern' property")
diff --git a/tools/binman/etype/fill.py b/tools/binman/etype/fill.py
index 860410ed6e..efb2d13e91 100644
--- a/tools/binman/etype/fill.py
+++ b/tools/binman/etype/fill.py
@@ -22,10 +22,10 @@ class Entry_fill(Entry):
byte value of a region.
"""
def __init__(self, section, etype, node):
- Entry.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def ReadNode(self):
- Entry.ReadNode(self)
+ super().ReadNode()
if self.size is None:
self.Raise("'fill' entry must have a size property")
self.fill_value = fdt_util.GetByte(self._node, 'fill-byte', 0)
diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py
new file mode 100644
index 0000000000..75712f4409
--- /dev/null
+++ b/tools/binman/etype/fit.py
@@ -0,0 +1,164 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2016 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# Entry-type module for producing a FIT
+#
+
+from collections import defaultdict, OrderedDict
+import libfdt
+
+from binman.entry import Entry
+from dtoc import fdt_util
+from dtoc.fdt import Fdt
+from patman import tools
+
+class Entry_fit(Entry):
+ """Entry containing a FIT
+
+ This calls mkimage to create a FIT (U-Boot Flat Image Tree) based on the
+ input provided.
+
+ Nodes for the FIT should be written out in the binman configuration just as
+ they would be in a file passed to mkimage.
+
+ For example, this creates an image containing a FIT with U-Boot SPL:
+
+ binman {
+ fit {
+ description = "Test FIT";
+
+ images {
+ kernel@1 {
+ description = "SPL";
+ os = "u-boot";
+ type = "rkspi";
+ arch = "arm";
+ compression = "none";
+ load = <0>;
+ entry = <0>;
+
+ u-boot-spl {
+ };
+ };
+ };
+ };
+ };
+
+ Properties:
+ fit,external-offset: Indicates that the contents of the FIT are external
+ and provides the external offset. This is passsed to mkimage via
+ the -E and -p flags.
+
+ """
+ def __init__(self, section, etype, node):
+ """
+ Members:
+ _fit: FIT file being built
+ _fit_content: dict:
+ key: relative path to entry Node (from the base of the FIT)
+ value: List of Entry objects comprising the contents of this
+ node
+ """
+ super().__init__(section, etype, node)
+ self._fit = None
+ self._fit_content = defaultdict(list)
+ self._fit_props = {}
+
+ def ReadNode(self):
+ self._ReadSubnodes()
+ super().ReadNode()
+
+ def _ReadSubnodes(self):
+ def _AddNode(base_node, depth, node):
+ """Add a node to the FIT
+
+ Args:
+ base_node: Base Node of the FIT (with 'description' property)
+ depth: Current node depth (0 is the base node)
+ node: Current node to process
+
+ There are two cases to deal with:
+ - hash and signature nodes which become part of the FIT
+ - binman entries which are used to define the 'data' for each
+ image
+ """
+ for pname, prop in node.props.items():
+ if pname.startswith('fit,'):
+ self._fit_props[pname] = prop
+ else:
+ fsw.property(pname, prop.bytes)
+
+ rel_path = node.path[len(base_node.path):]
+ has_images = depth == 2 and rel_path.startswith('/images/')
+ for subnode in node.subnodes:
+ if has_images and not (subnode.name.startswith('hash') or
+ subnode.name.startswith('signature')):
+ # This is a content node. We collect all of these together
+ # and put them in the 'data' property. They do not appear
+ # in the FIT.
+ entry = Entry.Create(self.section, subnode)
+ entry.ReadNode()
+ self._fit_content[rel_path].append(entry)
+ else:
+ with fsw.add_node(subnode.name):
+ _AddNode(base_node, depth + 1, subnode)
+
+ # Build a new tree with all nodes and properties starting from the
+ # entry node
+ fsw = libfdt.FdtSw()
+ fsw.finish_reservemap()
+ with fsw.add_node(''):
+ _AddNode(self._node, 0, self._node)
+ fdt = fsw.as_fdt()
+
+ # Pack this new FDT and scan it so we can add the data later
+ fdt.pack()
+ self._fdt = Fdt.FromData(fdt.as_bytearray())
+ self._fdt.Scan()
+
+ def ObtainContents(self):
+ """Obtain the contents of the FIT
+
+ This adds the 'data' properties to the input ITB (Image-tree Binary)
+ then runs mkimage to process it.
+ """
+ data = self._BuildInput(self._fdt)
+ if data == False:
+ return False
+ uniq = self.GetUniqueName()
+ input_fname = tools.GetOutputFilename('%s.itb' % uniq)
+ output_fname = tools.GetOutputFilename('%s.fit' % uniq)
+ tools.WriteFile(input_fname, data)
+ tools.WriteFile(output_fname, data)
+
+ args = []
+ ext_offset = self._fit_props.get('fit,external-offset')
+ if ext_offset is not None:
+ args += ['-E', '-p', '%x' % fdt_util.fdt32_to_cpu(ext_offset.value)]
+ tools.Run('mkimage', '-t', '-F', output_fname, *args)
+
+ self.SetContents(tools.ReadFile(output_fname))
+ return True
+
+ def _BuildInput(self, fdt):
+ """Finish the FIT by adding the 'data' properties to it
+
+ Arguments:
+ fdt: FIT to update
+
+ Returns:
+ New fdt contents (bytes)
+ """
+ for path, entries in self._fit_content.items():
+ node = fdt.GetNode(path)
+ data = b''
+ for entry in entries:
+ if not entry.ObtainContents():
+ return False
+ data += entry.GetData()
+ node.AddData('data', data)
+
+ fdt.Sync(auto_resize=True)
+ data = fdt.GetContents()
+ return data
diff --git a/tools/binman/etype/fmap.py b/tools/binman/etype/fmap.py
index a43fac38de..3e9b815d11 100644
--- a/tools/binman/etype/fmap.py
+++ b/tools/binman/etype/fmap.py
@@ -32,7 +32,7 @@ class Entry_fmap(Entry):
the sub-entries are ignored.
"""
def __init__(self, section, etype, node):
- Entry.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def _GetFmap(self):
"""Build an FMAP from the entries in the current image
diff --git a/tools/binman/etype/gbb.py b/tools/binman/etype/gbb.py
index dd10599717..41554eba8f 100644
--- a/tools/binman/etype/gbb.py
+++ b/tools/binman/etype/gbb.py
@@ -54,7 +54,7 @@ class Entry_gbb(Entry):
README.chromium for how to obtain the required keys and tools.
"""
def __init__(self, section, etype, node):
- Entry.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
self.hardware_id, self.keydir, self.bmpblk = self.GetEntryArgsOrProps(
[EntryArg('hardware-id', str),
EntryArg('keydir', str),
diff --git a/tools/binman/etype/image_header.py b/tools/binman/etype/image_header.py
index 176bdeb29b..2401188495 100644
--- a/tools/binman/etype/image_header.py
+++ b/tools/binman/etype/image_header.py
@@ -57,7 +57,7 @@ class Entry_image_header(Entry):
first/last in the entry list.
"""
def __init__(self, section, etype, node):
- Entry.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
self.location = fdt_util.GetString(self._node, 'location')
def _GetHeader(self):
@@ -101,7 +101,7 @@ class Entry_image_header(Entry):
else:
offset = image_size - IMAGE_HEADER_LEN
offset += self.section.GetStartOffset()
- return Entry.Pack(self, offset)
+ return super().Pack(offset)
def ProcessContents(self):
"""Write an updated version of the FDT map to this entry
diff --git a/tools/binman/etype/intel_cmc.py b/tools/binman/etype/intel_cmc.py
index 5e6edbe4df..644fa421d3 100644
--- a/tools/binman/etype/intel_cmc.py
+++ b/tools/binman/etype/intel_cmc.py
@@ -5,10 +5,9 @@
# Entry-type module for Intel Chip Microcode binary blob
#
-from binman.entry import Entry
-from binman.etype.blob import Entry_blob
+from binman.etype.blob_ext import Entry_blob_ext
-class Entry_intel_cmc(Entry_blob):
+class Entry_intel_cmc(Entry_blob_ext):
"""Entry containing an Intel Chipset Micro Code (CMC) file
Properties / Entry arguments:
@@ -20,4 +19,4 @@ class Entry_intel_cmc(Entry_blob):
See README.x86 for information about x86 binary blobs.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
diff --git a/tools/binman/etype/intel_descriptor.py b/tools/binman/etype/intel_descriptor.py
index d4d7a26901..7fe88a9ec1 100644
--- a/tools/binman/etype/intel_descriptor.py
+++ b/tools/binman/etype/intel_descriptor.py
@@ -8,7 +8,7 @@
import struct
from binman.entry import Entry
-from binman.etype.blob import Entry_blob
+from binman.etype.blob_ext import Entry_blob_ext
FD_SIGNATURE = struct.pack('<L', 0x0ff0a55a)
MAX_REGIONS = 5
@@ -25,7 +25,7 @@ class Region:
self.limit = ((val & 0x0fff0000) >> 4) | 0xfff
self.size = self.limit - self.base + 1
-class Entry_intel_descriptor(Entry_blob):
+class Entry_intel_descriptor(Entry_blob_ext):
"""Intel flash descriptor block (4KB)
Properties / Entry arguments:
@@ -45,16 +45,22 @@ class Entry_intel_descriptor(Entry_blob):
See README.x86 for information about x86 binary blobs.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
self._regions = []
def Pack(self, offset):
"""Put this entry at the start of the image"""
if self.offset is None:
offset = self.section.GetStartOffset()
- return Entry_blob.Pack(self, offset)
+ return super().Pack(offset)
def GetOffsets(self):
+ info = {}
+ if self.missing:
+ # Return zero offsets so that these entries get placed somewhere
+ if self.HasSibling('intel-me'):
+ info['intel-me'] = [0, None]
+ return info
offset = self.data.find(FD_SIGNATURE)
if offset == -1:
self.Raise('Cannot find Intel Flash Descriptor (FD) signature')
@@ -66,7 +72,6 @@ class Entry_intel_descriptor(Entry_blob):
# Set the offset for ME (Management Engine) and IFWI (Integrated
# Firmware Image), for now, since the others are not used.
- info = {}
if self.HasSibling('intel-me'):
info['intel-me'] = [self._regions[REGION_ME].base,
self._regions[REGION_ME].size]
diff --git a/tools/binman/etype/intel_fit.py b/tools/binman/etype/intel_fit.py
index ea482a6125..f1a10c55a6 100644
--- a/tools/binman/etype/intel_fit.py
+++ b/tools/binman/etype/intel_fit.py
@@ -7,9 +7,9 @@
import struct
-from binman.etype.blob import Entry_blob
+from binman.etype.blob_ext import Entry_blob_ext
-class Entry_intel_fit(Entry_blob):
+class Entry_intel_fit(Entry_blob_ext):
"""Intel Firmware Image Table (FIT)
This entry contains a dummy FIT as required by recent Intel CPUs. The FIT
@@ -19,11 +19,11 @@ class Entry_intel_fit(Entry_blob):
At present binman only supports a basic FIT with no microcode.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def ReadNode(self):
"""Force 16-byte alignment as required by FIT pointer"""
- Entry_blob.ReadNode(self)
+ super().ReadNode()
self.align = 16
def ObtainContents(self):
diff --git a/tools/binman/etype/intel_fit_ptr.py b/tools/binman/etype/intel_fit_ptr.py
index df118a68f2..01f082281c 100644
--- a/tools/binman/etype/intel_fit_ptr.py
+++ b/tools/binman/etype/intel_fit_ptr.py
@@ -7,16 +7,16 @@
import struct
-from binman.etype.blob import Entry_blob
+from binman.etype.blob_ext import Entry_blob_ext
-class Entry_intel_fit_ptr(Entry_blob):
+class Entry_intel_fit_ptr(Entry_blob_ext):
"""Intel Firmware Image Table (FIT) pointer
This entry contains a pointer to the FIT. It is required to be at address
0xffffffc0 in the image.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
if self.HasSibling('intel-fit') is False:
self.Raise("'intel-fit-ptr' section must have an 'intel-fit' sibling")
@@ -38,4 +38,4 @@ class Entry_intel_fit_ptr(Entry_blob):
def Pack(self, offset):
"""Special pack method to set the offset to the right place"""
- return Entry_blob.Pack(self, 0xffffffc0)
+ return super().Pack(0xffffffc0)
diff --git a/tools/binman/etype/intel_fsp.py b/tools/binman/etype/intel_fsp.py
index 7db3d96b43..2ac012bce1 100644
--- a/tools/binman/etype/intel_fsp.py
+++ b/tools/binman/etype/intel_fsp.py
@@ -5,10 +5,9 @@
# Entry-type module for Intel Firmware Support Package binary blob
#
-from binman.entry import Entry
-from binman.etype.blob import Entry_blob
+from binman.etype.blob_ext import Entry_blob_ext
-class Entry_intel_fsp(Entry_blob):
+class Entry_intel_fsp(Entry_blob_ext):
"""Entry containing an Intel Firmware Support Package (FSP) file
Properties / Entry arguments:
@@ -24,4 +23,4 @@ class Entry_intel_fsp(Entry_blob):
See README.x86 for information about x86 binary blobs.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
diff --git a/tools/binman/etype/intel_fsp_m.py b/tools/binman/etype/intel_fsp_m.py
index 51b4e7e1ac..434b0f1856 100644
--- a/tools/binman/etype/intel_fsp_m.py
+++ b/tools/binman/etype/intel_fsp_m.py
@@ -5,10 +5,9 @@
# Entry-type module for Intel Firmware Support Package binary blob (M section)
#
-from binman.entry import Entry
-from binman.etype.blob import Entry_blob
+from binman.etype.blob_ext import Entry_blob_ext
-class Entry_intel_fsp_m(Entry_blob):
+class Entry_intel_fsp_m(Entry_blob_ext):
"""Entry containing Intel Firmware Support Package (FSP) memory init
Properties / Entry arguments:
@@ -24,4 +23,4 @@ class Entry_intel_fsp_m(Entry_blob):
See README.x86 for information about x86 binary blobs.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
diff --git a/tools/binman/etype/intel_fsp_s.py b/tools/binman/etype/intel_fsp_s.py
index b3683e476a..564e1228bb 100644
--- a/tools/binman/etype/intel_fsp_s.py
+++ b/tools/binman/etype/intel_fsp_s.py
@@ -5,10 +5,9 @@
# Entry-type module for Intel Firmware Support Package binary blob (S section)
#
-from binman.entry import Entry
-from binman.etype.blob import Entry_blob
+from binman.etype.blob_ext import Entry_blob_ext
-class Entry_intel_fsp_s(Entry_blob):
+class Entry_intel_fsp_s(Entry_blob_ext):
"""Entry containing Intel Firmware Support Package (FSP) silicon init
Properties / Entry arguments:
@@ -24,4 +23,4 @@ class Entry_intel_fsp_s(Entry_blob):
See README.x86 for information about x86 binary blobs.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
diff --git a/tools/binman/etype/intel_fsp_t.py b/tools/binman/etype/intel_fsp_t.py
index 0f196f0f1c..df0c5fbee0 100644
--- a/tools/binman/etype/intel_fsp_t.py
+++ b/tools/binman/etype/intel_fsp_t.py
@@ -5,10 +5,9 @@
# Entry-type module for Intel Firmware Support Package binary blob (T section)
#
-from binman.entry import Entry
-from binman.etype.blob import Entry_blob
+from binman.etype.blob_ext import Entry_blob_ext
-class Entry_intel_fsp_t(Entry_blob):
+class Entry_intel_fsp_t(Entry_blob_ext):
"""Entry containing Intel Firmware Support Package (FSP) temp ram init
Properties / Entry arguments:
@@ -23,4 +22,4 @@ class Entry_intel_fsp_t(Entry_blob):
See README.x86 for information about x86 binary blobs.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
diff --git a/tools/binman/etype/intel_ifwi.py b/tools/binman/etype/intel_ifwi.py
index 6a96f6be55..76b3357c25 100644
--- a/tools/binman/etype/intel_ifwi.py
+++ b/tools/binman/etype/intel_ifwi.py
@@ -8,11 +8,11 @@
from collections import OrderedDict
from binman.entry import Entry
-from binman.etype.blob import Entry_blob
+from binman.etype.blob_ext import Entry_blob_ext
from dtoc import fdt_util
from patman import tools
-class Entry_intel_ifwi(Entry_blob):
+class Entry_intel_ifwi(Entry_blob_ext):
"""Entry containing an Intel Integrated Firmware Image (IFWI) file
Properties / Entry arguments:
@@ -45,13 +45,13 @@ class Entry_intel_ifwi(Entry_blob):
See README.x86 for information about x86 binary blobs.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
self._convert_fit = fdt_util.GetBool(self._node, 'convert-fit')
self._ifwi_entries = OrderedDict()
def ReadNode(self):
self._ReadSubnodes()
- Entry_blob.ReadNode(self)
+ super().ReadNode()
def _BuildIfwi(self):
"""Build the contents of the IFWI and write it to the 'data' property"""
@@ -84,7 +84,7 @@ class Entry_intel_ifwi(Entry_blob):
return True
def ObtainContents(self):
- """Get the contects for the IFWI
+ """Get the contents for the IFWI
Unfortunately we cannot create anything from scratch here, as Intel has
tools which create precursor binaries with lots of data and settings,
@@ -97,13 +97,21 @@ class Entry_intel_ifwi(Entry_blob):
After that we delete the OBBP sub-partition and add each of the files
that we want in the IFWI file, one for each sub-entry of the IWFI node.
"""
- self._pathname = tools.GetInputFilename(self._filename)
+ self._pathname = tools.GetInputFilename(self._filename,
+ self.section.GetAllowMissing())
+ # Allow the file to be missing
+ if not self._pathname:
+ self.SetContents(b'')
+ self.missing = True
+ return True
for entry in self._ifwi_entries.values():
if not entry.ObtainContents():
return False
return self._BuildIfwi()
def ProcessContents(self):
+ if self.missing:
+ return True
orig_data = self.data
self._BuildIfwi()
same = orig_data == self.data
@@ -121,5 +129,6 @@ class Entry_intel_ifwi(Entry_blob):
def WriteSymbols(self, section):
"""Write symbol values into binary files for access at run time"""
- for entry in self._ifwi_entries.values():
- entry.WriteSymbols(self)
+ if not self.missing:
+ for entry in self._ifwi_entries.values():
+ entry.WriteSymbols(self)
diff --git a/tools/binman/etype/intel_me.py b/tools/binman/etype/intel_me.py
index 41c9c6b920..a6fe5427f3 100644
--- a/tools/binman/etype/intel_me.py
+++ b/tools/binman/etype/intel_me.py
@@ -5,10 +5,9 @@
# Entry-type module for Intel Management Engine binary blob
#
-from binman.entry import Entry
-from binman.etype.blob import Entry_blob
+from binman.etype.blob_ext import Entry_blob_ext
-class Entry_intel_me(Entry_blob):
+class Entry_intel_me(Entry_blob_ext):
"""Entry containing an Intel Management Engine (ME) file
Properties / Entry arguments:
@@ -16,7 +15,7 @@ class Entry_intel_me(Entry_blob):
This file contains code used by the SoC that is required to make it work.
The Management Engine is like a background task that runs things that are
- not clearly documented, but may include keyboard, deplay and network
+ not clearly documented, but may include keyboard, display and network
access. For platform that use ME it is not possible to disable it. U-Boot
does not directly execute code in the ME binary.
@@ -27,4 +26,4 @@ class Entry_intel_me(Entry_blob):
See README.x86 for information about x86 binary blobs.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
diff --git a/tools/binman/etype/intel_mrc.py b/tools/binman/etype/intel_mrc.py
index 854a4dda61..ccbb046519 100644
--- a/tools/binman/etype/intel_mrc.py
+++ b/tools/binman/etype/intel_mrc.py
@@ -5,10 +5,9 @@
# Entry-type module for Intel Memory Reference Code binary blob
#
-from binman.entry import Entry
-from binman.etype.blob import Entry_blob
+from binman.etype.blob_ext import Entry_blob_ext
-class Entry_intel_mrc(Entry_blob):
+class Entry_intel_mrc(Entry_blob_ext):
"""Entry containing an Intel Memory Reference Code (MRC) file
Properties / Entry arguments:
@@ -21,7 +20,7 @@ class Entry_intel_mrc(Entry_blob):
See README.x86 for information about x86 binary blobs.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def GetDefaultFilename(self):
return 'mrc.bin'
diff --git a/tools/binman/etype/intel_refcode.py b/tools/binman/etype/intel_refcode.py
index a1059f787e..5ead08b2be 100644
--- a/tools/binman/etype/intel_refcode.py
+++ b/tools/binman/etype/intel_refcode.py
@@ -5,10 +5,9 @@
# Entry-type module for Intel Memory Reference Code binary blob
#
-from binman.entry import Entry
-from binman.etype.blob import Entry_blob
+from binman.etype.blob_ext import Entry_blob_ext
-class Entry_intel_refcode(Entry_blob):
+class Entry_intel_refcode(Entry_blob_ext):
"""Entry containing an Intel Reference Code file
Properties / Entry arguments:
@@ -21,7 +20,7 @@ class Entry_intel_refcode(Entry_blob):
See README.x86 for information about x86 binary blobs.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def GetDefaultFilename(self):
return 'refcode.bin'
diff --git a/tools/binman/etype/intel_vbt.py b/tools/binman/etype/intel_vbt.py
index 4d465ad017..2a98c12368 100644
--- a/tools/binman/etype/intel_vbt.py
+++ b/tools/binman/etype/intel_vbt.py
@@ -4,10 +4,9 @@
# Entry-type module for Intel Video BIOS Table binary blob
#
-from binman.entry import Entry
-from binman.etype.blob import Entry_blob
+from binman.etype.blob_ext import Entry_blob_ext
-class Entry_intel_vbt(Entry_blob):
+class Entry_intel_vbt(Entry_blob_ext):
"""Entry containing an Intel Video BIOS Table (VBT) file
Properties / Entry arguments:
@@ -19,4 +18,4 @@ class Entry_intel_vbt(Entry_blob):
See README.x86 for information about Intel binary blobs.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
diff --git a/tools/binman/etype/intel_vga.py b/tools/binman/etype/intel_vga.py
index 04cd72f3dc..a103f1ce0e 100644
--- a/tools/binman/etype/intel_vga.py
+++ b/tools/binman/etype/intel_vga.py
@@ -5,10 +5,9 @@
# Entry-type module for x86 VGA ROM binary blob
#
-from binman.entry import Entry
-from binman.etype.blob import Entry_blob
+from binman.etype.blob_ext import Entry_blob_ext
-class Entry_intel_vga(Entry_blob):
+class Entry_intel_vga(Entry_blob_ext):
"""Entry containing an Intel Video Graphics Adaptor (VGA) file
Properties / Entry arguments:
@@ -22,4 +21,4 @@ class Entry_intel_vga(Entry_blob):
See README.x86 for information about Intel binary blobs.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
diff --git a/tools/binman/etype/mkimage.py b/tools/binman/etype/mkimage.py
new file mode 100644
index 0000000000..8fddc88118
--- /dev/null
+++ b/tools/binman/etype/mkimage.py
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2016 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# Entry-type module for producing an image using mkimage
+#
+
+from collections import OrderedDict
+
+from binman.entry import Entry
+from dtoc import fdt_util
+from patman import tools
+
+class Entry_mkimage(Entry):
+ """Entry containing a binary produced by mkimage
+
+ Properties / Entry arguments:
+ - datafile: Filename for -d argument
+ - args: Other arguments to pass
+
+ The data passed to mkimage is collected from subnodes of the mkimage node,
+ e.g.:
+
+ mkimage {
+ args = "-n test -T imximage";
+
+ u-boot-spl {
+ };
+ };
+
+ This calls mkimage to create an imximage with u-boot-spl.bin as the input
+ file. The output from mkimage then becomes part of the image produced by
+ binman.
+ """
+ def __init__(self, section, etype, node):
+ super().__init__(section, etype, node)
+ self._args = fdt_util.GetString(self._node, 'args').split(' ')
+ self._mkimage_entries = OrderedDict()
+ self._ReadSubnodes()
+
+ def ObtainContents(self):
+ data = b''
+ for entry in self._mkimage_entries.values():
+ # First get the input data and put it in a file. If not available,
+ # try later.
+ if not entry.ObtainContents():
+ return False
+ data += entry.GetData()
+ uniq = self.GetUniqueName()
+ input_fname = tools.GetOutputFilename('mkimage.%s' % uniq)
+ tools.WriteFile(input_fname, data)
+ output_fname = tools.GetOutputFilename('mkimage-out.%s' % uniq)
+ tools.Run('mkimage', '-d', input_fname, *self._args, output_fname)
+ self.SetContents(tools.ReadFile(output_fname))
+ return True
+
+ def _ReadSubnodes(self):
+ """Read the subnodes to find out what should go in this image"""
+ for node in self._node.subnodes:
+ entry = Entry.Create(self, node)
+ entry.ReadNode()
+ self._mkimage_entries[entry.name] = entry
diff --git a/tools/binman/etype/powerpc_mpc85xx_bootpg_resetvec.py b/tools/binman/etype/powerpc_mpc85xx_bootpg_resetvec.py
index cefd425a5d..3a92fa399f 100644
--- a/tools/binman/etype/powerpc_mpc85xx_bootpg_resetvec.py
+++ b/tools/binman/etype/powerpc_mpc85xx_bootpg_resetvec.py
@@ -4,7 +4,6 @@
# Entry-type module for the PowerPC mpc85xx bootpg and resetvec code for U-Boot
#
-from binman.entry import Entry
from binman.etype.blob import Entry_blob
class Entry_powerpc_mpc85xx_bootpg_resetvec(Entry_blob):
@@ -13,13 +12,13 @@ class Entry_powerpc_mpc85xx_bootpg_resetvec(Entry_blob):
Properties / Entry arguments:
- filename: Filename of u-boot-br.bin (default 'u-boot-br.bin')
- This enrty is valid for PowerPC mpc85xx cpus. This entry holds
+ This entry is valid for PowerPC mpc85xx cpus. This entry holds
'bootpg + resetvec' code for PowerPC mpc85xx CPUs which needs to be
placed at offset 'RESET_VECTOR_ADDRESS - 0xffc'.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def GetDefaultFilename(self):
return 'u-boot-br.bin'
diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py
index 91b8e0c110..73c5553c81 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.
@@ -43,16 +48,18 @@ class Entry_section(Entry):
"""
def __init__(self, section, etype, node, test=False):
if not test:
- Entry.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
self._entries = OrderedDict()
self._pad_byte = 0
self._sort = False
self._skip_at_start = None
self._end_4gb = False
+ self._allow_missing = False
+ self.missing = False
def ReadNode(self):
"""Read properties from the image node"""
- Entry.ReadNode(self)
+ super().ReadNode()
self._pad_byte = fdt_util.GetInt(self._node, 'pad-byte', 0)
self._sort = fdt_util.GetBool(self._node, 'sort-by-offset')
self._end_4gb = fdt_util.GetBool(self._node, 'end-at-4gb')
@@ -126,13 +133,13 @@ class Entry_section(Entry):
a section containing a list of files. Process these entries so that
this information is added to the device tree.
"""
- Entry.ExpandEntries(self)
+ super().ExpandEntries()
for entry in self._entries.values():
entry.ExpandEntries()
def AddMissingProperties(self):
"""Add new properties to the device tree as needed for this entry"""
- Entry.AddMissingProperties(self)
+ super().AddMissingProperties()
for entry in self._entries.values():
entry.AddMissingProperties()
@@ -168,14 +175,14 @@ class Entry_section(Entry):
def ResetForPack(self):
"""Reset offset/size fields so that packing can be done again"""
- Entry.ResetForPack(self)
+ super().ResetForPack()
for entry in self._entries.values():
entry.ResetForPack()
def Pack(self, offset):
"""Pack all entries into the section"""
self._PackEntries()
- return Entry.Pack(self, offset)
+ return super().Pack(offset)
def _PackEntries(self):
"""Pack all entries into the image"""
@@ -219,7 +226,7 @@ class Entry_section(Entry):
"at %#x (%d)" %
(entry.offset, entry.offset, self._skip_at_start,
self._skip_at_start))
- if entry.offset < offset:
+ if entry.offset < offset and entry.size:
entry.Raise("Offset %#x (%d) overlaps with previous entry '%s' "
"ending at %#x (%d)" %
(entry.offset, entry.offset, prev_name, offset, offset))
@@ -232,12 +239,12 @@ class Entry_section(Entry):
entry.WriteSymbols(self)
def SetCalculatedProperties(self):
- Entry.SetCalculatedProperties(self)
+ super().SetCalculatedProperties()
for entry in self._entries.values():
entry.SetCalculatedProperties()
def SetImagePos(self, image_pos):
- Entry.SetImagePos(self, image_pos)
+ super().SetImagePos(image_pos)
for entry in self._entries.values():
entry.SetImagePos(image_pos + self.offset)
@@ -435,8 +442,8 @@ class Entry_section(Entry):
if not entry:
self._Raise("Unable to set offset/size for unknown entry '%s'" %
name)
- entry.SetOffsetSize(self._skip_at_start + offset if offset else None,
- size)
+ entry.SetOffsetSize(self._skip_at_start + offset if offset is not None
+ else None, size)
def GetEntryOffsets(self):
"""Handle entries that want to set the offset/size of other entries
@@ -535,3 +542,32 @@ 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
+
+ def CheckMissing(self, missing_list):
+ """Check if any entries in this section have missing external blobs
+
+ If there are missing blobs, the entries are added to the list
+
+ Args:
+ missing_list: List of Entry objects to be added to
+ """
+ for entry in self._entries.values():
+ entry.CheckMissing(missing_list)
diff --git a/tools/binman/etype/text.py b/tools/binman/etype/text.py
index 3577135adb..a69c2a4ec4 100644
--- a/tools/binman/etype/text.py
+++ b/tools/binman/etype/text.py
@@ -57,7 +57,7 @@ class Entry_text(Entry):
by setting the size of the entry to something larger than the text.
"""
def __init__(self, section, etype, node):
- Entry.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
value = fdt_util.GetString(self._node, 'text')
if value:
value = tools.ToBytes(value)
diff --git a/tools/binman/etype/u_boot.py b/tools/binman/etype/u_boot.py
index ab1019b00c..4767197e13 100644
--- a/tools/binman/etype/u_boot.py
+++ b/tools/binman/etype/u_boot.py
@@ -26,7 +26,7 @@ class Entry_u_boot(Entry_blob):
in the binman README for more information.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def GetDefaultFilename(self):
return 'u-boot.bin'
diff --git a/tools/binman/etype/u_boot_dtb.py b/tools/binman/etype/u_boot_dtb.py
index e98350088f..65e71291d2 100644
--- a/tools/binman/etype/u_boot_dtb.py
+++ b/tools/binman/etype/u_boot_dtb.py
@@ -22,7 +22,7 @@ class Entry_u_boot_dtb(Entry_blob_dtb):
binman to know which entries contain a device tree.
"""
def __init__(self, section, etype, node):
- Entry_blob_dtb.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def GetDefaultFilename(self):
return 'u-boot.dtb'
diff --git a/tools/binman/etype/u_boot_dtb_with_ucode.py b/tools/binman/etype/u_boot_dtb_with_ucode.py
index aec145533e..66a9db55ca 100644
--- a/tools/binman/etype/u_boot_dtb_with_ucode.py
+++ b/tools/binman/etype/u_boot_dtb_with_ucode.py
@@ -28,7 +28,7 @@ class Entry_u_boot_dtb_with_ucode(Entry_blob_dtb):
global state
from binman import state
- Entry_blob_dtb.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
self.ucode_data = b''
self.collate = False
self.ucode_offset = None
@@ -78,7 +78,7 @@ class Entry_u_boot_dtb_with_ucode(Entry_blob_dtb):
def ObtainContents(self):
# Call the base class just in case it does something important.
- Entry_blob_dtb.ObtainContents(self)
+ super().ObtainContents()
if self.ucode and not self.collate:
for node in self.ucode.subnodes:
data_prop = node.props.get('data')
diff --git a/tools/binman/etype/u_boot_elf.py b/tools/binman/etype/u_boot_elf.py
index 5f906e520c..6614a75faf 100644
--- a/tools/binman/etype/u_boot_elf.py
+++ b/tools/binman/etype/u_boot_elf.py
@@ -21,7 +21,7 @@ class Entry_u_boot_elf(Entry_blob):
relocated to any address for execution.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
self._strip = fdt_util.GetBool(self._node, 'strip')
def ReadBlobContents(self):
@@ -31,7 +31,7 @@ class Entry_u_boot_elf(Entry_blob):
tools.WriteFile(out_fname, tools.ReadFile(self._pathname))
tools.Run('strip', out_fname)
self._pathname = out_fname
- Entry_blob.ReadBlobContents(self)
+ super().ReadBlobContents()
return True
def GetDefaultFilename(self):
diff --git a/tools/binman/etype/u_boot_img.py b/tools/binman/etype/u_boot_img.py
index 50cc71d3ce..8a739d8edb 100644
--- a/tools/binman/etype/u_boot_img.py
+++ b/tools/binman/etype/u_boot_img.py
@@ -21,7 +21,7 @@ class Entry_u_boot_img(Entry_blob):
applications.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def GetDefaultFilename(self):
return 'u-boot.img'
diff --git a/tools/binman/etype/u_boot_nodtb.py b/tools/binman/etype/u_boot_nodtb.py
index e8c0e1a1d6..e84df490f6 100644
--- a/tools/binman/etype/u_boot_nodtb.py
+++ b/tools/binman/etype/u_boot_nodtb.py
@@ -21,7 +21,7 @@ class Entry_u_boot_nodtb(Entry_blob):
U-Boot and the device tree).
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def GetDefaultFilename(self):
return 'u-boot-nodtb.bin'
diff --git a/tools/binman/etype/u_boot_spl.py b/tools/binman/etype/u_boot_spl.py
index a6fddbe8f1..d66e46140b 100644
--- a/tools/binman/etype/u_boot_spl.py
+++ b/tools/binman/etype/u_boot_spl.py
@@ -32,7 +32,7 @@ class Entry_u_boot_spl(Entry_blob):
binman uses that to look up symbols to write into the SPL binary.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
self.elf_fname = 'spl/u-boot-spl'
def GetDefaultFilename(self):
diff --git a/tools/binman/etype/u_boot_spl_bss_pad.py b/tools/binman/etype/u_boot_spl_bss_pad.py
index a6a177a128..596b2bed97 100644
--- a/tools/binman/etype/u_boot_spl_bss_pad.py
+++ b/tools/binman/etype/u_boot_spl_bss_pad.py
@@ -31,7 +31,7 @@ class Entry_u_boot_spl_bss_pad(Entry_blob):
binman uses that to look up the BSS address.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def ObtainContents(self):
fname = tools.GetInputFilename('spl/u-boot-spl')
diff --git a/tools/binman/etype/u_boot_spl_dtb.py b/tools/binman/etype/u_boot_spl_dtb.py
index a0761eeacd..eefc4a44aa 100644
--- a/tools/binman/etype/u_boot_spl_dtb.py
+++ b/tools/binman/etype/u_boot_spl_dtb.py
@@ -19,7 +19,7 @@ class Entry_u_boot_spl_dtb(Entry_blob_dtb):
to activate.
"""
def __init__(self, section, etype, node):
- Entry_blob_dtb.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def GetDefaultFilename(self):
return 'spl/u-boot-spl.dtb'
diff --git a/tools/binman/etype/u_boot_spl_elf.py b/tools/binman/etype/u_boot_spl_elf.py
index f99f74abab..7f1236bcbb 100644
--- a/tools/binman/etype/u_boot_spl_elf.py
+++ b/tools/binman/etype/u_boot_spl_elf.py
@@ -18,7 +18,7 @@ class Entry_u_boot_spl_elf(Entry_blob):
be relocated to any address for execution.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def GetDefaultFilename(self):
return 'spl/u-boot-spl'
diff --git a/tools/binman/etype/u_boot_spl_nodtb.py b/tools/binman/etype/u_boot_spl_nodtb.py
index 072b915ff3..6f4529396d 100644
--- a/tools/binman/etype/u_boot_spl_nodtb.py
+++ b/tools/binman/etype/u_boot_spl_nodtb.py
@@ -22,7 +22,7 @@ class Entry_u_boot_spl_nodtb(Entry_blob):
both SPL and the device tree).
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def GetDefaultFilename(self):
return 'spl/u-boot-spl-nodtb.bin'
diff --git a/tools/binman/etype/u_boot_spl_with_ucode_ptr.py b/tools/binman/etype/u_boot_spl_with_ucode_ptr.py
index b1543a5ef3..72739a5eb6 100644
--- a/tools/binman/etype/u_boot_spl_with_ucode_ptr.py
+++ b/tools/binman/etype/u_boot_spl_with_ucode_ptr.py
@@ -18,7 +18,7 @@ class Entry_u_boot_spl_with_ucode_ptr(Entry_u_boot_with_ucode_ptr):
process.
"""
def __init__(self, section, etype, node):
- Entry_u_boot_with_ucode_ptr.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
self.elf_fname = 'spl/u-boot-spl'
def GetDefaultFilename(self):
diff --git a/tools/binman/etype/u_boot_tpl.py b/tools/binman/etype/u_boot_tpl.py
index 6562457c9a..02287ab327 100644
--- a/tools/binman/etype/u_boot_tpl.py
+++ b/tools/binman/etype/u_boot_tpl.py
@@ -32,7 +32,7 @@ class Entry_u_boot_tpl(Entry_blob):
binman uses that to look up symbols to write into the TPL binary.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
self.elf_fname = 'tpl/u-boot-tpl'
def GetDefaultFilename(self):
diff --git a/tools/binman/etype/u_boot_tpl_dtb.py b/tools/binman/etype/u_boot_tpl_dtb.py
index 890155f271..2ff1d7ced1 100644
--- a/tools/binman/etype/u_boot_tpl_dtb.py
+++ b/tools/binman/etype/u_boot_tpl_dtb.py
@@ -19,7 +19,7 @@ class Entry_u_boot_tpl_dtb(Entry_blob_dtb):
to activate.
"""
def __init__(self, section, etype, node):
- Entry_blob_dtb.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def GetDefaultFilename(self):
return 'tpl/u-boot-tpl.dtb'
diff --git a/tools/binman/etype/u_boot_tpl_dtb_with_ucode.py b/tools/binman/etype/u_boot_tpl_dtb_with_ucode.py
index ca1bf85ace..066f18dfef 100644
--- a/tools/binman/etype/u_boot_tpl_dtb_with_ucode.py
+++ b/tools/binman/etype/u_boot_tpl_dtb_with_ucode.py
@@ -16,7 +16,7 @@ class Entry_u_boot_tpl_dtb_with_ucode(Entry_u_boot_dtb_with_ucode):
process.
"""
def __init__(self, section, etype, node):
- Entry_u_boot_dtb_with_ucode.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def GetDefaultFilename(self):
return 'tpl/u-boot-tpl.dtb'
diff --git a/tools/binman/etype/u_boot_tpl_elf.py b/tools/binman/etype/u_boot_tpl_elf.py
index 7fa8e96364..3f24d3aa7b 100644
--- a/tools/binman/etype/u_boot_tpl_elf.py
+++ b/tools/binman/etype/u_boot_tpl_elf.py
@@ -18,7 +18,7 @@ class Entry_u_boot_tpl_elf(Entry_blob):
be relocated to any address for execution.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def GetDefaultFilename(self):
return 'tpl/u-boot-tpl'
diff --git a/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py b/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py
index 7f7fab7105..c7f3f9dedb 100644
--- a/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py
+++ b/tools/binman/etype/u_boot_tpl_with_ucode_ptr.py
@@ -20,7 +20,7 @@ class Entry_u_boot_tpl_with_ucode_ptr(Entry_u_boot_with_ucode_ptr):
process.
"""
def __init__(self, section, etype, node):
- Entry_u_boot_with_ucode_ptr.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
self.elf_fname = 'tpl/u-boot-tpl'
def GetDefaultFilename(self):
diff --git a/tools/binman/etype/u_boot_ucode.py b/tools/binman/etype/u_boot_ucode.py
index d9e1a605ef..4462293618 100644
--- a/tools/binman/etype/u_boot_ucode.py
+++ b/tools/binman/etype/u_boot_ucode.py
@@ -58,7 +58,7 @@ class Entry_u_boot_ucode(Entry_blob):
contents of this entry.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def ObtainContents(self):
# If the section does not need microcode, there is nothing to do
diff --git a/tools/binman/etype/u_boot_with_ucode_ptr.py b/tools/binman/etype/u_boot_with_ucode_ptr.py
index 06047b654d..92d2fc6853 100644
--- a/tools/binman/etype/u_boot_with_ucode_ptr.py
+++ b/tools/binman/etype/u_boot_with_ucode_ptr.py
@@ -29,7 +29,7 @@ class Entry_u_boot_with_ucode_ptr(Entry_blob):
complicated. Otherwise it is the same as the u_boot entry.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
self.elf_fname = 'u-boot'
self.target_offset = None
diff --git a/tools/binman/etype/vblock.py b/tools/binman/etype/vblock.py
index 5753de7ec7..f734fbaec4 100644
--- a/tools/binman/etype/vblock.py
+++ b/tools/binman/etype/vblock.py
@@ -36,7 +36,7 @@ class Entry_vblock(Entry):
and kernel are genuine.
"""
def __init__(self, section, etype, node):
- Entry.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
self.content = fdt_util.GetPhandleList(self._node, 'content')
if not self.content:
self.Raise("Vblock must have a 'content' property")
diff --git a/tools/binman/etype/x86_reset16.py b/tools/binman/etype/x86_reset16.py
index ad864e5442..5d49f16e21 100644
--- a/tools/binman/etype/x86_reset16.py
+++ b/tools/binman/etype/x86_reset16.py
@@ -23,7 +23,7 @@ class Entry_x86_reset16(Entry_blob):
For 64-bit U-Boot, the 'x86_reset16_spl' entry type is used instead.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def GetDefaultFilename(self):
return 'u-boot-x86-reset16.bin'
diff --git a/tools/binman/etype/x86_reset16_spl.py b/tools/binman/etype/x86_reset16_spl.py
index 9a663f0ae2..775b90699b 100644
--- a/tools/binman/etype/x86_reset16_spl.py
+++ b/tools/binman/etype/x86_reset16_spl.py
@@ -23,7 +23,7 @@ class Entry_x86_reset16_spl(Entry_blob):
For 32-bit U-Boot, the 'x86_reset_spl' entry type is used instead.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def GetDefaultFilename(self):
return 'spl/u-boot-x86-reset16-spl.bin'
diff --git a/tools/binman/etype/x86_reset16_tpl.py b/tools/binman/etype/x86_reset16_tpl.py
index 864508f367..52d3f4869a 100644
--- a/tools/binman/etype/x86_reset16_tpl.py
+++ b/tools/binman/etype/x86_reset16_tpl.py
@@ -23,7 +23,7 @@ class Entry_x86_reset16_tpl(Entry_blob):
For 32-bit U-Boot, the 'x86_reset_tpl' entry type is used instead.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def GetDefaultFilename(self):
return 'tpl/u-boot-x86-reset16-tpl.bin'
diff --git a/tools/binman/etype/x86_start16.py b/tools/binman/etype/x86_start16.py
index d8345f6722..18fdd95d37 100644
--- a/tools/binman/etype/x86_start16.py
+++ b/tools/binman/etype/x86_start16.py
@@ -25,7 +25,7 @@ class Entry_x86_start16(Entry_blob):
For 64-bit U-Boot, the 'x86_start16_spl' entry type is used instead.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def GetDefaultFilename(self):
return 'u-boot-x86-start16.bin'
diff --git a/tools/binman/etype/x86_start16_spl.py b/tools/binman/etype/x86_start16_spl.py
index ad520d3c6d..ac8e90f2e0 100644
--- a/tools/binman/etype/x86_start16_spl.py
+++ b/tools/binman/etype/x86_start16_spl.py
@@ -25,7 +25,7 @@ class Entry_x86_start16_spl(Entry_blob):
For 32-bit U-Boot, the 'x86-start16' entry type is used instead.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def GetDefaultFilename(self):
return 'spl/u-boot-x86-start16-spl.bin'
diff --git a/tools/binman/etype/x86_start16_tpl.py b/tools/binman/etype/x86_start16_tpl.py
index ccc8727d1d..72d4608bb7 100644
--- a/tools/binman/etype/x86_start16_tpl.py
+++ b/tools/binman/etype/x86_start16_tpl.py
@@ -26,7 +26,7 @@ class Entry_x86_start16_tpl(Entry_blob):
may be used instead.
"""
def __init__(self, section, etype, node):
- Entry_blob.__init__(self, section, etype, node)
+ super().__init__(section, etype, node)
def GetDefaultFilename(self):
return 'tpl/u-boot-x86-start16-tpl.bin'
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 5e24920088..ea72eff8c5 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -6,10 +6,12 @@
#
# python -m unittest func_test.TestFunctional.testHelp
+import collections
import gzip
import hashlib
from optparse import OptionParser
import os
+import re
import shutil
import struct
import sys
@@ -160,8 +162,7 @@ class TestFunctional(unittest.TestCase):
tools.ReadFile(cls.ElfTestFile('u_boot_ucode_ptr')))
# Intel flash descriptor file
- with open(cls.TestFile('descriptor.bin'), 'rb') as fd:
- TestFunctional._MakeInputFile('descriptor.bin', fd.read())
+ cls._SetupDescriptor()
shutil.copytree(cls.TestFile('files'),
os.path.join(cls._indir, 'files'))
@@ -285,7 +286,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 +320,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]
@@ -506,6 +509,11 @@ class TestFunctional(unittest.TestCase):
tools.ReadFile(cls.ElfTestFile(src_fname)))
@classmethod
+ def _SetupDescriptor(cls):
+ with open(cls.TestFile('descriptor.bin'), 'rb') as fd:
+ TestFunctional._MakeInputFile('descriptor.bin', fd.read())
+
+ @classmethod
def TestFile(cls, fname):
return os.path.join(cls._binman_dir, 'test', fname)
@@ -931,11 +939,14 @@ class TestFunctional(unittest.TestCase):
def testPackX86RomMeNoDesc(self):
"""Test that an invalid Intel descriptor entry is detected"""
- TestFunctional._MakeInputFile('descriptor.bin', b'')
- with self.assertRaises(ValueError) as e:
- self._DoTestFile('031_x86_rom_me.dts')
- self.assertIn("Node '/binman/intel-descriptor': Cannot find Intel Flash Descriptor (FD) signature",
- str(e.exception))
+ try:
+ TestFunctional._MakeInputFile('descriptor.bin', b'')
+ with self.assertRaises(ValueError) as e:
+ self._DoTestFile('031_x86_rom_me.dts')
+ self.assertIn("Node '/binman/intel-descriptor': Cannot find Intel Flash Descriptor (FD) signature",
+ str(e.exception))
+ finally:
+ self._SetupDescriptor()
def testPackX86RomBadDesc(self):
"""Test that the Intel requires a descriptor entry"""
@@ -3230,7 +3241,7 @@ class TestFunctional(unittest.TestCase):
with test_util.capture_sys_output() as (stdout, stderr):
control.ReplaceEntries(updated_fname, None, outdir, [])
self.assertIn("Skipping entry '/u-boot' from missing file",
- stdout.getvalue())
+ stderr.getvalue())
def testReplaceCmdMap(self):
"""Test replacing a file fron an image on the command line"""
@@ -3357,6 +3368,117 @@ class TestFunctional(unittest.TestCase):
data = self._DoReadFile('154_intel_fsp_t.dts')
self.assertEqual(FSP_T_DATA, data[:len(FSP_T_DATA)])
+ def testMkimage(self):
+ """Test using mkimage to build an image"""
+ data = self._DoReadFile('156_mkimage.dts')
+
+ # Just check that the data appears in the file somewhere
+ self.assertIn(U_BOOT_SPL_DATA, data)
+
+ def testExtblob(self):
+ """Test an image with an external blob"""
+ data = self._DoReadFile('157_blob_ext.dts')
+ self.assertEqual(REFCODE_DATA, data)
+
+ def testExtblobMissing(self):
+ """Test an image with a missing external blob"""
+ with self.assertRaises(ValueError) as e:
+ self._DoReadFile('158_blob_ext_missing.dts')
+ 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"""
+ with test_util.capture_sys_output() as (stdout, stderr):
+ self._DoTestFile('158_blob_ext_missing.dts', allow_missing=True)
+ err = stderr.getvalue()
+ self.assertRegex(err, "Image 'main-section'.*missing.*: blob-ext")
+
+ def testExtblobMissingOkSect(self):
+ """Test an image with an missing external blob that is allowed"""
+ with test_util.capture_sys_output() as (stdout, stderr):
+ self._DoTestFile('159_blob_ext_missing_sect.dts',
+ allow_missing=True)
+ err = stderr.getvalue()
+ self.assertRegex(err, "Image 'main-section'.*missing.*: "
+ "blob-ext blob-ext2")
+
+ def testPackX86RomMeMissingDesc(self):
+ """Test that an missing Intel descriptor entry is allowed"""
+ pathname = os.path.join(self._indir, 'descriptor.bin')
+ os.remove(pathname)
+ with test_util.capture_sys_output() as (stdout, stderr):
+ self._DoTestFile('031_x86_rom_me.dts', allow_missing=True)
+ err = stderr.getvalue()
+ self.assertRegex(err,
+ "Image 'main-section'.*missing.*: intel-descriptor")
+
+ def testPackX86RomMissingIfwi(self):
+ """Test that an x86 ROM with Integrated Firmware Image can be created"""
+ self._SetupIfwi('fitimage.bin')
+ pathname = os.path.join(self._indir, 'fitimage.bin')
+ os.remove(pathname)
+ with test_util.capture_sys_output() as (stdout, stderr):
+ self._DoTestFile('111_x86_rom_ifwi.dts', allow_missing=True)
+ err = stderr.getvalue()
+ self.assertRegex(err, "Image 'main-section'.*missing.*: intel-ifwi")
+
+ def testPackOverlap(self):
+ """Test that zero-size overlapping regions are ignored"""
+ self._DoTestFile('160_pack_overlap_zero.dts')
+
+ def testSimpleFit(self):
+ """Test an image with a FIT inside"""
+ data = self._DoReadFile('161_fit.dts')
+ self.assertEqual(U_BOOT_DATA, data[:len(U_BOOT_DATA)])
+ self.assertEqual(U_BOOT_NODTB_DATA, data[-len(U_BOOT_NODTB_DATA):])
+ fit_data = data[len(U_BOOT_DATA):-len(U_BOOT_NODTB_DATA)]
+
+ # The data should be inside the FIT
+ dtb = fdt.Fdt.FromData(fit_data)
+ dtb.Scan()
+ fnode = dtb.GetNode('/images/kernel')
+ self.assertIn('data', fnode.props)
+
+ fname = os.path.join(self._indir, 'fit_data.fit')
+ tools.WriteFile(fname, fit_data)
+ out = tools.Run('dumpimage', '-l', fname)
+
+ # Check a few features to make sure the plumbing works. We don't need
+ # to test the operation of mkimage or dumpimage here. First convert the
+ # output into a dict where the keys are the fields printed by dumpimage
+ # and the values are a list of values for each field
+ lines = out.splitlines()
+
+ # Converts "Compression: gzip compressed" into two groups:
+ # 'Compression' and 'gzip compressed'
+ re_line = re.compile(r'^ *([^:]*)(?:: *(.*))?$')
+ vals = collections.defaultdict(list)
+ for line in lines:
+ mat = re_line.match(line)
+ vals[mat.group(1)].append(mat.group(2))
+
+ self.assertEquals('FIT description: test-desc', lines[0])
+ self.assertIn('Created:', lines[1])
+ self.assertIn('Image 0 (kernel)', vals)
+ self.assertIn('Hash value', vals)
+ data_sizes = vals.get('Data Size')
+ self.assertIsNotNone(data_sizes)
+ self.assertEqual(2, len(data_sizes))
+ # Format is "4 Bytes = 0.00 KiB = 0.00 MiB" so take the first word
+ self.assertEqual(len(U_BOOT_DATA), int(data_sizes[0].split()[0]))
+ self.assertEqual(len(U_BOOT_SPL_DTB_DATA), int(data_sizes[1].split()[0]))
+
+ def testFitExternal(self):
+ """Test an image with an FIT"""
+ data = self._DoReadFile('162_fit_external.dts')
+ fit_data = data[len(U_BOOT_DATA):-2] # _testing is 2 bytes
+
+ # The data should be outside the FIT
+ dtb = fdt.Fdt.FromData(fit_data)
+ dtb.Scan()
+ fnode = dtb.GetNode('/images/kernel')
+ self.assertNotIn('data', fnode.props)
if __name__ == "__main__":
unittest.main()
diff --git a/tools/binman/image.py b/tools/binman/image.py
index 523b274c31..a8772c3763 100644
--- a/tools/binman/image.py
+++ b/tools/binman/image.py
@@ -45,7 +45,7 @@ class Image(section.Entry_section):
we create a section manually.
"""
def __init__(self, name, node, copy_to_orig=True, test=False):
- section.Entry_section.__init__(self, None, 'section', node, test=test)
+ super().__init__(None, 'section', node, test=test)
self.copy_to_orig = copy_to_orig
self.name = 'main-section'
self.image_name = name
@@ -57,7 +57,7 @@ class Image(section.Entry_section):
self.ReadNode()
def ReadNode(self):
- section.Entry_section.ReadNode(self)
+ super().ReadNode()
filename = fdt_util.GetString(self._node, 'filename')
if filename:
self._filename = filename
@@ -116,11 +116,11 @@ class Image(section.Entry_section):
def PackEntries(self):
"""Pack all entries into the image"""
- section.Entry_section.Pack(self, 0)
+ super().Pack(0)
def SetImagePos(self):
# This first section in the image so it starts at 0
- section.Entry_section.SetImagePos(self, 0)
+ super().SetImagePos(0)
def ProcessEntryContents(self):
"""Call the ProcessContents() method for each entry
@@ -139,7 +139,7 @@ class Image(section.Entry_section):
def WriteSymbols(self):
"""Write symbol values into binary files for access at run time"""
- section.Entry_section.WriteSymbols(self, self)
+ super().WriteSymbols(self)
def BuildImage(self):
"""Write the image to a file"""
@@ -161,7 +161,7 @@ class Image(section.Entry_section):
with open(fname, 'w') as fd:
print('%8s %8s %8s %s' % ('ImagePos', 'Offset', 'Size', 'Name'),
file=fd)
- section.Entry_section.WriteMap(self, fd, 0)
+ super().WriteMap(fd, 0)
return fname
def BuildEntryList(self):
diff --git a/tools/binman/main.py b/tools/binman/main.py
index efa7fa8386..e543a7d06a 100755
--- a/tools/binman/main.py
+++ b/tools/binman/main.py
@@ -26,6 +26,7 @@ from patman import test_util
# Bring in the libfdt module
sys.path.insert(2, 'scripts/dtc/pylibfdt')
+sys.path.insert(2, os.path.join(our_path, '../../scripts/dtc/pylibfdt'))
sys.path.insert(2, os.path.join(our_path,
'../../build-sandbox_spl/scripts/dtc/pylibfdt'))
@@ -88,14 +89,18 @@ def GetEntryModules(include_testing=True):
for item in glob_list
if include_testing or '_testing' not in item])
-def RunTestCoverage():
+def RunTestCoverage(toolpath):
"""Run the tests and check that we get 100% coverage"""
glob_list = GetEntryModules(False)
all_set = set([os.path.splitext(os.path.basename(item))[0]
for item in glob_list if '_testing' not in item])
+ extra_args = ''
+ if toolpath:
+ for path in toolpath:
+ extra_args += ' --toolpath %s' % path
test_util.RunTestCoverage('tools/binman/binman', None,
['*test*', '*main.py', 'tools/patman/*', 'tools/dtoc/*'],
- args.build_dir, all_set)
+ args.build_dir, all_set, extra_args or None)
def RunBinman(args):
"""Main entry point to binman once arguments are parsed
@@ -108,9 +113,14 @@ def RunBinman(args):
if not args.debug:
sys.tracebacklimit = 0
+ # Provide a default toolpath in the hope of finding a mkimage built from
+ # current source
+ if not args.toolpath:
+ args.toolpath = ['./tools', 'build-sandbox/tools']
+
if args.cmd == 'test':
if args.test_coverage:
- RunTestCoverage()
+ RunTestCoverage(args.toolpath)
else:
ret_code = RunTests(args.debug, args.verbosity, args.processes,
args.test_preserve_dirs, args.tests,
@@ -123,7 +133,7 @@ def RunBinman(args):
try:
ret_code = control.Binman(args)
except Exception as e:
- print('binman: %s' % e)
+ print('binman: %s' % e, file=sys.stderr)
if args.debug:
print()
traceback.print_exc()
diff --git a/tools/binman/test/156_mkimage.dts b/tools/binman/test/156_mkimage.dts
new file mode 100644
index 0000000000..933b13143a
--- /dev/null
+++ b/tools/binman/test/156_mkimage.dts
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ size = <0x80>;
+
+ mkimage {
+ args = "-n test -T script";
+
+ u-boot-spl {
+ };
+
+ _testing {
+ return-contents-later;
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/157_blob_ext.dts b/tools/binman/test/157_blob_ext.dts
new file mode 100644
index 0000000000..8afdd5339e
--- /dev/null
+++ b/tools/binman/test/157_blob_ext.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ blob-ext {
+ filename = "refcode.bin";
+ };
+ };
+};
diff --git a/tools/binman/test/158_blob_ext_missing.dts b/tools/binman/test/158_blob_ext_missing.dts
new file mode 100644
index 0000000000..d315e5592e
--- /dev/null
+++ b/tools/binman/test/158_blob_ext_missing.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ size = <0x80>;
+
+ blob-ext {
+ filename = "missing-file";
+ };
+ };
+};
diff --git a/tools/binman/test/159_blob_ext_missing_sect.dts b/tools/binman/test/159_blob_ext_missing_sect.dts
new file mode 100644
index 0000000000..5f14c54138
--- /dev/null
+++ b/tools/binman/test/159_blob_ext_missing_sect.dts
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ size = <0x80>;
+
+ section {
+ blob-ext {
+ filename = "missing-file";
+ };
+ };
+
+ blob-ext2 {
+ type = "blob-ext";
+ filename = "missing-file2";
+ };
+ };
+};
diff --git a/tools/binman/test/160_pack_overlap_zero.dts b/tools/binman/test/160_pack_overlap_zero.dts
new file mode 100644
index 0000000000..731aa1cbe6
--- /dev/null
+++ b/tools/binman/test/160_pack_overlap_zero.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ u-boot {
+ };
+
+ fill {
+ size = <0>;
+ offset = <3>;
+ };
+ };
+};
diff --git a/tools/binman/test/161_fit.dts b/tools/binman/test/161_fit.dts
new file mode 100644
index 0000000000..c52d760b73
--- /dev/null
+++ b/tools/binman/test/161_fit.dts
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ u-boot {
+ };
+ fit {
+ description = "test-desc";
+ #address-cells = <1>;
+
+ images {
+ kernel {
+ description = "Vanilla Linux kernel";
+ type = "kernel";
+ arch = "ppc";
+ os = "linux";
+ compression = "gzip";
+ load = <00000000>;
+ entry = <00000000>;
+ hash-1 {
+ algo = "crc32";
+ };
+ hash-2 {
+ algo = "sha1";
+ };
+ u-boot {
+ };
+ };
+ fdt-1 {
+ description = "Flattened Device Tree blob";
+ type = "flat_dt";
+ arch = "ppc";
+ compression = "none";
+ hash-1 {
+ algo = "crc32";
+ };
+ hash-2 {
+ algo = "sha1";
+ };
+ u-boot-spl-dtb {
+ };
+ };
+ };
+
+ configurations {
+ default = "conf-1";
+ conf-1 {
+ description = "Boot Linux kernel with FDT blob";
+ kernel = "kernel";
+ fdt = "fdt-1";
+ };
+ };
+ };
+ u-boot-nodtb {
+ };
+ };
+};
diff --git a/tools/binman/test/162_fit_external.dts b/tools/binman/test/162_fit_external.dts
new file mode 100644
index 0000000000..19518e05a5
--- /dev/null
+++ b/tools/binman/test/162_fit_external.dts
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ u-boot {
+ };
+ fit {
+ fit,external-offset = <0>;
+ description = "test-desc";
+ #address-cells = <1>;
+
+ images {
+ kernel {
+ description = "Vanilla Linux kernel";
+ type = "kernel";
+ arch = "ppc";
+ os = "linux";
+ compression = "gzip";
+ load = <00000000>;
+ entry = <00000000>;
+ hash-1 {
+ algo = "crc32";
+ };
+ hash-2 {
+ algo = "sha1";
+ };
+ u-boot {
+ };
+ };
+ fdt-1 {
+ description = "Flattened Device Tree blob";
+ type = "flat_dt";
+ arch = "ppc";
+ compression = "none";
+ hash-1 {
+ algo = "crc32";
+ };
+ hash-2 {
+ algo = "sha1";
+ };
+ _testing {
+ return-contents-later;
+ };
+ };
+ };
+
+ configurations {
+ default = "conf-1";
+ conf-1 {
+ description = "Boot Linux kernel with FDT blob";
+ kernel = "kernel";
+ fdt = "fdt-1";
+ };
+ };
+ };
+ u-boot-nodtb {
+ };
+ };
+};