summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/binman/binman.rst10
-rw-r--r--tools/binman/btool/mkimage.py5
-rw-r--r--tools/binman/entries.rst7
-rw-r--r--tools/binman/etype/fit.py57
-rw-r--r--tools/binman/ftest.py95
-rwxr-xr-xtools/binman/main.py6
-rw-r--r--tools/binman/test/340_fit_signature.dts98
-rw-r--r--tools/binman/test/340_rsa2048.key28
-rw-r--r--tools/binman/test/341_fit_signature.dts98
-rw-r--r--tools/binman/test/342_fit_signature.dts61
-rw-r--r--tools/buildman/builder.py6
-rw-r--r--tools/buildman/toolchain.py8
-rw-r--r--tools/docker/Dockerfile7
-rwxr-xr-xtools/expo.py33
-rw-r--r--tools/image-host.c2
-rw-r--r--tools/u_boot_pylib/test_util.py13
16 files changed, 506 insertions, 28 deletions
diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst
index f9a3a42183b..381e55686f9 100644
--- a/tools/binman/binman.rst
+++ b/tools/binman/binman.rst
@@ -2099,12 +2099,15 @@ Code coverage
-------------
Binman is a critical tool and is designed to be very testable. Entry
-implementations target 100% test coverage. Run 'binman test -T' to check this.
+implementations target 100% test coverage. Run ``binman test -T`` to check this.
To enable Python test coverage on Debian-type distributions (e.g. Ubuntu)::
$ sudo apt-get install python-coverage python3-coverage python-pytest
+You can also check the coverage provided by a single test, e.g.::
+
+ binman test -T testSimple
Exit status
-----------
@@ -2191,6 +2194,11 @@ Use '-P 1' to disable this. It is automatically disabled when code coverage is
being used (-T) since they are incompatible.
+Writing tests
+-------------
+
+See :doc:`../binman_tests`.
+
Debugging tests
---------------
diff --git a/tools/binman/btool/mkimage.py b/tools/binman/btool/mkimage.py
index 39a4c8c1432..78d3301bc10 100644
--- a/tools/binman/btool/mkimage.py
+++ b/tools/binman/btool/mkimage.py
@@ -22,7 +22,7 @@ class Bintoolmkimage(bintool.Bintool):
# pylint: disable=R0913
def run(self, reset_timestamp=False, output_fname=None, external=False,
- pad=None, align=None):
+ pad=None, align=None, priv_keys_dir=None):
"""Run mkimage
Args:
@@ -34,6 +34,7 @@ class Bintoolmkimage(bintool.Bintool):
other things to be easily added later, if required, such as
signatures
align: Bytes to use for alignment of the FIT and its external data
+ priv_keys_dir: Path to directory containing private keys
version: True to get the mkimage version
"""
args = []
@@ -45,6 +46,8 @@ class Bintoolmkimage(bintool.Bintool):
args += ['-B', f'{align:x}']
if reset_timestamp:
args.append('-t')
+ if priv_keys_dir:
+ args += ['-k', f'{priv_keys_dir}']
if output_fname:
args += ['-F', output_fname]
return self.run_cmd(*args)
diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
index 3006c5914d6..e918162fb48 100644
--- a/tools/binman/entries.rst
+++ b/tools/binman/entries.rst
@@ -864,6 +864,13 @@ The top-level 'fit' node supports the following special properties:
fit,fdt-list-dir = "arch/arm/dts
+ fit,sign
+ Enable signing FIT images via mkimage as described in
+ verified-boot.rst. If the property is found, the private keys path is
+ detected among binman include directories and passed to mkimage via
+ -k flag. All the keys required for signing FIT must be available at
+ time of signing and must be located in single include directory.
+
Substitutions
~~~~~~~~~~~~~
diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py
index 0abe1c78c43..b5afbda41b5 100644
--- a/tools/binman/etype/fit.py
+++ b/tools/binman/etype/fit.py
@@ -9,6 +9,7 @@ import glob
import os
import libfdt
+import os
from binman.entry import Entry, EntryArg
from binman.etype.section import Entry_section
@@ -101,6 +102,14 @@ class Entry_fit(Entry_section):
In this case the input directories are ignored and all devicetree
files must be in that directory.
+ fit,sign
+ Enable signing FIT images via mkimage as described in
+ verified-boot.rst. If the property is found, the private keys path
+ is detected among binman include directories and passed to mkimage
+ via -k flag. All the keys required for signing FIT must be
+ available at time of signing and must be located in single include
+ directory.
+
Substitutions
~~~~~~~~~~~~~
@@ -426,6 +435,7 @@ class Entry_fit(Entry_section):
self._remove_props = props.split()
self.mkimage = None
self.fdtgrep = None
+ self._fit_sign = None
def ReadNode(self):
super().ReadNode()
@@ -508,6 +518,45 @@ class Entry_fit(Entry_section):
# are removed from self._entries later.
self._priv_entries = dict(self._entries)
+ def _get_priv_keys_dir(self, data):
+ """Detect private keys path among binman include directories
+
+ Args:
+ data: FIT image in binary format
+
+ Returns:
+ str: Single path containing all private keys found or None
+
+ Raises:
+ ValueError: Filename 'rsa2048.key' not found in input path
+ ValueError: Multiple key paths found
+ """
+ def _find_keys_dir(node):
+ for subnode in node.subnodes:
+ if subnode.name.startswith('signature'):
+ if subnode.props.get('key-name-hint') is None:
+ continue
+ hint = subnode.props['key-name-hint'].value
+ name = tools.get_input_filename(f"{hint}.key")
+ path = os.path.dirname(name)
+ if path not in paths:
+ paths.append(path)
+ else:
+ _find_keys_dir(subnode)
+ return None
+
+ fdt = Fdt.FromData(data)
+ fdt.Scan()
+
+ paths = []
+
+ _find_keys_dir(fdt.GetRoot())
+
+ if len(paths) > 1:
+ self.Raise("multiple key paths found (%s)" % ",".join(paths))
+
+ return paths[0] if len(paths) else None
+
def BuildSectionData(self, required):
"""Build FIT entry contents
@@ -538,6 +587,8 @@ class Entry_fit(Entry_section):
align = self._fit_props.get('fit,align')
if align is not None:
args.update({'align': fdt_util.fdt32_to_cpu(align.value)})
+ if self._fit_props.get('fit,sign') is not None:
+ args.update({'priv_keys_dir': self._get_priv_keys_dir(data)})
if self.mkimage.run(reset_timestamp=True, output_fname=output_fname,
**args) is None:
if not self.GetAllowMissing():
@@ -637,8 +688,8 @@ class Entry_fit(Entry_section):
"""
val = fdt_util.GetStringList(node, 'fit,firmware')
if val is None:
- return None, self._loadables
- valid_entries = list(self._loadables)
+ return None, loadables
+ valid_entries = list(loadables)
for name, entry in self.GetEntries().items():
missing = []
entry.CheckMissing(missing)
@@ -653,7 +704,7 @@ class Entry_fit(Entry_section):
firmware = name
elif name not in result:
result.append(name)
- for name in self._loadables:
+ for name in loadables:
if name != firmware and name not in result:
result.append(name)
return firmware, result
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index e3f231e4bcc..156567ace77 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -7804,6 +7804,101 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
"""Test that binman can produce an iMX8 image"""
self._DoTestFile('339_nxp_imx8.dts')
+ def testFitSignSimple(self):
+ """Test that image with FIT and signature nodes can be signed"""
+ if not elf.ELF_TOOLS:
+ self.skipTest('Python elftools not available')
+ entry_args = {
+ 'of-list': 'test-fdt1',
+ 'default-dt': 'test-fdt1',
+ 'atf-bl31-path': 'bl31.elf',
+ }
+ data = tools.read_file(self.TestFile("340_rsa2048.key"))
+ self._MakeInputFile("keys/rsa2048.key", data)
+
+ test_subdir = os.path.join(self._indir, TEST_FDT_SUBDIR)
+ keys_subdir = os.path.join(self._indir, "keys")
+ data = self._DoReadFileDtb(
+ '340_fit_signature.dts',
+ entry_args=entry_args,
+ extra_indirs=[test_subdir, keys_subdir])[0]
+
+ dtb = fdt.Fdt.FromData(data)
+ dtb.Scan()
+
+ conf = dtb.GetNode('/configurations/conf-uboot-1')
+ self.assertIsNotNone(conf)
+ signature = conf.FindNode('signature')
+ self.assertIsNotNone(signature)
+ self.assertIsNotNone(signature.props.get('value'))
+
+ images = dtb.GetNode('/images')
+ self.assertIsNotNone(images)
+ for subnode in images.subnodes:
+ signature = subnode.FindNode('signature')
+ self.assertIsNotNone(signature)
+ self.assertIsNotNone(signature.props.get('value'))
+
+ def testFitSignKeyNotFound(self):
+ """Test that missing keys raise an error"""
+ if not elf.ELF_TOOLS:
+ self.skipTest('Python elftools not available')
+ entry_args = {
+ 'of-list': 'test-fdt1',
+ 'default-dt': 'test-fdt1',
+ 'atf-bl31-path': 'bl31.elf',
+ }
+ test_subdir = os.path.join(self._indir, TEST_FDT_SUBDIR)
+ with self.assertRaises(ValueError) as e:
+ self._DoReadFileDtb(
+ '340_fit_signature.dts',
+ entry_args=entry_args,
+ extra_indirs=[test_subdir])[0]
+ self.assertIn(
+ 'Filename \'rsa2048.key\' not found in input path',
+ str(e.exception))
+
+ def testFitSignMultipleKeyPaths(self):
+ """Test that keys found in multiple paths raise an error"""
+ if not elf.ELF_TOOLS:
+ self.skipTest('Python elftools not available')
+ entry_args = {
+ 'of-list': 'test-fdt1',
+ 'default-dt': 'test-fdt1',
+ 'atf-bl31-path': 'bl31.elf',
+ }
+ data = tools.read_file(self.TestFile("340_rsa2048.key"))
+ self._MakeInputFile("keys1/rsa2048.key", data)
+ data = tools.read_file(self.TestFile("340_rsa2048.key"))
+ self._MakeInputFile("keys2/conf-rsa2048.key", data)
+
+ test_subdir = os.path.join(self._indir, TEST_FDT_SUBDIR)
+ keys_subdir1 = os.path.join(self._indir, "keys1")
+ keys_subdir2 = os.path.join(self._indir, "keys2")
+ with self.assertRaises(ValueError) as e:
+ self._DoReadFileDtb(
+ '341_fit_signature.dts',
+ entry_args=entry_args,
+ extra_indirs=[test_subdir, keys_subdir1, keys_subdir2])[0]
+ self.assertIn(
+ 'Node \'/binman/fit\': multiple key paths found',
+ str(e.exception))
+
+ def testFitSignNoSingatureNodes(self):
+ """Test that fit,sign doens't raise error if no signature nodes found"""
+ if not elf.ELF_TOOLS:
+ self.skipTest('Python elftools not available')
+ entry_args = {
+ 'of-list': 'test-fdt1',
+ 'default-dt': 'test-fdt1',
+ 'atf-bl31-path': 'bl31.elf',
+ }
+ test_subdir = os.path.join(self._indir, TEST_FDT_SUBDIR)
+ self._DoReadFileDtb(
+ '342_fit_signature.dts',
+ entry_args=entry_args,
+ extra_indirs=[test_subdir])[0]
+
if __name__ == "__main__":
unittest.main()
diff --git a/tools/binman/main.py b/tools/binman/main.py
index dc817ddcd42..619840e7d55 100755
--- a/tools/binman/main.py
+++ b/tools/binman/main.py
@@ -85,7 +85,7 @@ def RunTests(debug, verbosity, processes, test_preserve_dirs, args, toolpath):
return (0 if result.wasSuccessful() else 1)
-def RunTestCoverage(toolpath, build_dir):
+def RunTestCoverage(toolpath, build_dir, args):
"""Run the tests and check that we get 100% coverage"""
glob_list = control.GetEntryModules(False)
all_set = set([os.path.splitext(os.path.basename(item))[0]
@@ -97,7 +97,7 @@ def RunTestCoverage(toolpath, build_dir):
test_util.run_test_coverage('tools/binman/binman', None,
['*test*', '*main.py', 'tools/patman/*', 'tools/dtoc/*',
'tools/u_boot_pylib/*'],
- build_dir, all_set, extra_args or None)
+ build_dir, all_set, extra_args or None, args=args)
def RunBinman(args):
"""Main entry point to binman once arguments are parsed
@@ -117,7 +117,7 @@ def RunBinman(args):
if args.cmd == 'test':
if args.test_coverage:
- RunTestCoverage(args.toolpath, args.build_dir)
+ RunTestCoverage(args.toolpath, args.build_dir, args.tests)
else:
ret_code = RunTests(args.debug, args.verbosity, args.processes,
args.test_preserve_dirs, args.tests,
diff --git a/tools/binman/test/340_fit_signature.dts b/tools/binman/test/340_fit_signature.dts
new file mode 100644
index 00000000000..9dce62e52de
--- /dev/null
+++ b/tools/binman/test/340_fit_signature.dts
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ fit {
+ description = "test desc";
+ #address-cells = <1>;
+ fit,fdt-list = "of-list";
+ fit,sign;
+
+ images {
+ u-boot {
+ description = "test u-boot";
+ type = "standalone";
+ arch = "arm64";
+ os = "u-boot";
+ compression = "none";
+ load = <0x00000000>;
+ entry = <0x00000000>;
+
+ u-boot-nodtb {
+ };
+
+ hash {
+ algo = "sha256";
+ };
+
+ signature {
+ algo = "sha256,rsa2048";
+ key-name-hint = "rsa2048";
+ };
+ };
+ @atf-SEQ {
+ fit,operation = "split-elf";
+ description = "test tf-a";
+ type = "firmware";
+ arch = "arm64";
+ os = "arm-trusted-firmware";
+ compression = "none";
+ fit,load;
+ fit,entry;
+ fit,data;
+
+ atf-bl31 {
+ };
+
+ hash {
+ algo = "sha256";
+ };
+
+ signature {
+ algo = "sha256,rsa2048";
+ key-name-hint = "rsa2048";
+ };
+ };
+ @fdt-SEQ {
+ description = "test fdt";
+ type = "flat_dt";
+ compression = "none";
+
+ hash {
+ algo = "sha256";
+ };
+
+ signature {
+ algo = "sha256,rsa2048";
+ key-name-hint = "rsa2048";
+ };
+ };
+ };
+
+ configurations {
+ default = "@conf-uboot-DEFAULT-SEQ";
+ @conf-uboot-SEQ {
+ description = "uboot config";
+ fdt = "fdt-SEQ";
+ fit,firmware = "u-boot";
+ fit,loadables;
+
+ hash {
+ algo = "sha256";
+ };
+
+ signature {
+ algo = "sha256,rsa2048";
+ key-name-hint = "rsa2048";
+ sign-images = "firmware", "loadables", "fdt";
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/340_rsa2048.key b/tools/binman/test/340_rsa2048.key
new file mode 100644
index 00000000000..e74b20cf392
--- /dev/null
+++ b/tools/binman/test/340_rsa2048.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDVUiT2JAF8Ajcx
+3XTB5qdGxuPMVFcXKJH+4L66oSt4YUBGi1bClo80U2azu08BTzk2Jzv6hez/mvzL
+hBvL3WnPwMl5vdOxb1kvUQyKLSw2bkM8VB0X1jGsKsKjzArg/aI8RknfiaSc5jua
+2lqwUFwv2RMF8jvIMN/1GnTLdECeMFVgVFSFkzIocISAHGPoGUOxTf8xK7o0x4RX
+NzB+95RtIqTQ5Az/KPVCOcQR5ETrUBXHF1I0rYjJjHHO4dUxxfDqFabt60EzQ/R2
+oZu58C4y0TrRI98g4hVPBYapildWjaNQm1Exa4ZaSDVl01OXsFW9Dm80PqfW4tTH
+Cm4nuCq5AgMBAAECggEBAIoG5b2SHJfFwzrzpQmVmeTU6i6a3+MvMBAwEZkmkb8J
+hhJfNFsiGjTsRgbDiuI5BbbBejCmmWvmN+3jZCzr7fwsLPEl36TufFF+atO5WOM7
+Qyv07QIwaOGSpXBgpSVhV6kSfdgy8p1G54hSAt4UkSGwnnt5ei8VWMP6Q1oltW3k
+f9DQ/ar4UEVa4jlJU3xqchcUTiKBKSH6pMC/Fqlq8x5JTLmk1Yb6C2UNcgJYez1u
+sHkdCA0FG3rFPrpFoQ1LUjMj1uEYNAxM3jOxE7Uvmk4yo9WpQDY7cRb2+Th9YY8a
+IKQ2s81Yg2TmkGzr8f5nrZz3WbAmQhQgsKbwlo6snjUCgYEA7kBOt0JlU7bJTfOr
+9s51g2VUfIH9lDS2Eh8MY+Bt6Y0Kdw/UK4HR8ZlN/nn0bHuHkc12K8lXEsQpgIEW
+DaqHytZJHqFs2egzKu/IvQYZ2WXEMj47LZQxEDHO9gtjE+5qCW9yJGqxW9BJKPVD
+F4spus4NqC+yD5OHM+6ESUtL/wMCgYEA5TZj6OHmECeh3efrwHqjDcjrqQbOTozU
+KPCNCY3Pv4Cg4xas/L93TE2CY6HJTr6mwEMUM+M4Ujjj15VCmSDQ/YYcGau1jo+f
+XdphOEENrPwoe9ATWIyBpT/wDrEz3L6JbE9dWMYY8vKYESt3qhVqDlbpmnYl8Jm+
+O3r5Cy2NlJMCgYEAyqzsCZuy5QcesnByvm8dqpxdxdkzJYu9wyakfKZj+gUgfO57
+OFOkjFk07yFB27MuPctCFredmfpDr+ygHRoPkG7AHw2Fss2EEaeP5bU18ilPQMqN
+vxVMs5EblVVUgJUVoVcsC2yz2f4S7oPOAk5BPoehOIzydauznWrvIAas7I8CgYBr
+CFHxLoNq6cbZQ3JACERZrIf2/vmZjoOHtoR1gKYRK7R1NmKDB7lihRMtCSBix/4/
+61Lkw+bJ5kzmn4lgzgUpTdWTWy5FquVlQxOA3EfRjlItNsXB5KKpksi7Y53vJ34u
+eIUDbkW6NPQzmFOhtaw3k/gzq5Yd2v0M82iWAqiJRwKBgQCl2+e2cjISK31QhKTC
+puhwQ0/YuC3zlwMXQgB3nPw8b9RlaDTMrRBCIUFIrrX11tHswGWpyVsxW2AvZ3Zm
+jsWpwGkUdpRdXJBhSaisV/PA+x3kYhpibzEI8FrzhU69zNROCb8CTkN4WcdBdq6J
+PUh/jRtKoE79qrlnIlNvFoz2gQ==
+-----END PRIVATE KEY-----
diff --git a/tools/binman/test/341_fit_signature.dts b/tools/binman/test/341_fit_signature.dts
new file mode 100644
index 00000000000..77bec8df1e5
--- /dev/null
+++ b/tools/binman/test/341_fit_signature.dts
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ fit {
+ description = "test desc";
+ #address-cells = <1>;
+ fit,fdt-list = "of-list";
+ fit,sign;
+
+ images {
+ u-boot {
+ description = "test u-boot";
+ type = "standalone";
+ arch = "arm64";
+ os = "u-boot";
+ compression = "none";
+ load = <0x00000000>;
+ entry = <0x00000000>;
+
+ u-boot-nodtb {
+ };
+
+ hash {
+ algo = "sha256";
+ };
+
+ signature {
+ algo = "sha256,rsa2048";
+ key-name-hint = "rsa2048";
+ };
+ };
+ @atf-SEQ {
+ fit,operation = "split-elf";
+ description = "test tf-a";
+ type = "firmware";
+ arch = "arm64";
+ os = "arm-trusted-firmware";
+ compression = "none";
+ fit,load;
+ fit,entry;
+ fit,data;
+
+ atf-bl31 {
+ };
+
+ hash {
+ algo = "sha256";
+ };
+
+ signature {
+ algo = "sha256,rsa2048";
+ key-name-hint = "rsa2048";
+ };
+ };
+ @fdt-SEQ {
+ description = "test fdt";
+ type = "flat_dt";
+ compression = "none";
+
+ hash {
+ algo = "sha256";
+ };
+
+ signature {
+ algo = "sha256,rsa2048";
+ key-name-hint = "rsa2048";
+ };
+ };
+ };
+
+ configurations {
+ default = "@conf-uboot-DEFAULT-SEQ";
+ @conf-uboot-SEQ {
+ description = "uboot config";
+ fdt = "fdt-SEQ";
+ fit,firmware = "u-boot";
+ fit,loadables;
+
+ hash {
+ algo = "sha256";
+ };
+
+ signature {
+ algo = "sha256,rsa2048";
+ key-name-hint = "conf-rsa2048";
+ sign-images = "firmware", "loadables", "fdt";
+ };
+ };
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/342_fit_signature.dts b/tools/binman/test/342_fit_signature.dts
new file mode 100644
index 00000000000..267105d0f68
--- /dev/null
+++ b/tools/binman/test/342_fit_signature.dts
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ fit {
+ description = "test desc";
+ #address-cells = <1>;
+ fit,fdt-list = "of-list";
+ fit,sign;
+
+ images {
+ u-boot {
+ description = "test u-boot";
+ type = "standalone";
+ arch = "arm64";
+ os = "u-boot";
+ compression = "none";
+ load = <0x00000000>;
+ entry = <0x00000000>;
+
+ u-boot-nodtb {
+ };
+ };
+ @atf-SEQ {
+ fit,operation = "split-elf";
+ description = "test tf-a";
+ type = "firmware";
+ arch = "arm64";
+ os = "arm-trusted-firmware";
+ compression = "none";
+ fit,load;
+ fit,entry;
+ fit,data;
+
+ atf-bl31 {
+ };
+ };
+ @fdt-SEQ {
+ description = "test fdt";
+ type = "flat_dt";
+ compression = "none";
+ };
+ };
+
+ configurations {
+ default = "@conf-uboot-DEFAULT-SEQ";
+ @conf-uboot-SEQ {
+ description = "uboot config";
+ fdt = "fdt-SEQ";
+ fit,firmware = "u-boot";
+ fit,loadables;
+ };
+ };
+ };
+ };
+};
diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py
index 4090d328b30..cbf1345281b 100644
--- a/tools/buildman/builder.py
+++ b/tools/buildman/builder.py
@@ -34,7 +34,7 @@ from u_boot_pylib.terminal import tprint
# Error in reading or end of file.
# <<
# which indicates that BREAK_ME has an empty default
-RE_NO_DEFAULT = re.compile(b'\((\w+)\) \[] \(NEW\)')
+RE_NO_DEFAULT = re.compile(br'\((\w+)\) \[] \(NEW\)')
# Symbol types which appear in the bloat feature (-B). Others are silently
# dropped when reading in the 'nm' output
@@ -374,9 +374,9 @@ class Builder:
self._re_function = re.compile('(.*): In function.*')
self._re_files = re.compile('In file included from.*')
- self._re_warning = re.compile('(.*):(\d*):(\d*): warning: .*')
+ self._re_warning = re.compile(r'(.*):(\d*):(\d*): warning: .*')
self._re_dtb_warning = re.compile('(.*): Warning .*')
- self._re_note = re.compile('(.*):(\d*):(\d*): note: this is the location of the previous.*')
+ self._re_note = re.compile(r'(.*):(\d*):(\d*): note: this is the location of the previous.*')
self._re_migration_warning = re.compile(r'^={21} WARNING ={22}\n.*\n=+\n',
re.MULTILINE | re.DOTALL)
diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py
index a7d7883b851..0c8a4fa16eb 100644
--- a/tools/buildman/toolchain.py
+++ b/tools/buildman/toolchain.py
@@ -440,12 +440,12 @@ class Toolchains:
This converts ${blah} within the string to the value of blah.
This function works recursively.
+ Resolved string
+
Args:
var_dict: Dictionary containing variables and their values
args: String containing make arguments
Returns:
- Resolved string
-
>>> bsettings.setup(None)
>>> tcs = Toolchains()
>>> tcs.Add('fred', False)
@@ -456,7 +456,7 @@ class Toolchains:
>>> tcs.ResolveReferences(var_dict, 'this=${oblique}_set${first}nd')
'this=OBLIQUE_setfi2ndrstnd'
"""
- re_var = re.compile('(\$\{[-_a-z0-9A-Z]{1,}\})')
+ re_var = re.compile(r'(\$\{[-_a-z0-9A-Z]{1,}\})')
while True:
m = re_var.search(args)
@@ -495,7 +495,7 @@ class Toolchains:
self._make_flags['target'] = brd.target
arg_str = self.ResolveReferences(self._make_flags,
self._make_flags.get(brd.target, ''))
- args = re.findall("(?:\".*?\"|\S)+", arg_str)
+ args = re.findall(r"(?:\".*?\"|\S)+", arg_str)
i = 0
while i < len(args):
args[i] = args[i].replace('"', '')
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
index c401170b1e1..967ac89fbde 100644
--- a/tools/docker/Dockerfile
+++ b/tools/docker/Dockerfile
@@ -244,12 +244,15 @@ RUN mkdir /tmp/trace && \
rm -rf /tmp/trace
# Build coreboot
-RUN wget -O - https://coreboot.org/releases/coreboot-4.22.01.tar.xz | tar -C /tmp -xJ && \
- cd /tmp/coreboot-4.22.01 && \
+RUN wget -O - https://coreboot.org/releases/coreboot-24.08.tar.xz | tar -C /tmp -xJ && \
+ cd /tmp/coreboot-24.08 && \
make crossgcc-i386 CPUS=$(nproc) && \
make -C payloads/coreinfo olddefconfig && \
make -C payloads/coreinfo && \
make olddefconfig && \
+ echo CONFIG_GENERIC_LINEAR_FRAMEBUFFER=y | tee -a .config && \
+ echo CONFIG_USE_OPTION_TABLE=y | tee -a .config && \
+ make olddefconfig && \
make -j $(nproc) && \
sudo mkdir /opt/coreboot && \
sudo cp build/coreboot.rom build/cbfstool /opt/coreboot/
diff --git a/tools/expo.py b/tools/expo.py
index ea80c70f04e..44995f28a38 100755
--- a/tools/expo.py
+++ b/tools/expo.py
@@ -20,17 +20,22 @@ from u_boot_pylib import tools
# Parse:
# SCENE1 = 7,
+# or SCENE1 = EXPOID_BASE_ID,
# or SCENE2,
-RE_ENUM = re.compile(r'(\S*)(\s*= (\d))?,')
+RE_ENUM = re.compile(r'(\S*)(\s*= ([0-9A-Z_]+))?,')
# Parse #define <name> "string"
RE_DEF = re.compile(r'#define (\S*)\s*"(.*)"')
-def calc_ids(fname):
+# Parse EXPOID_BASE_ID = 5,
+RE_BASE_ID = re.compile(r'\s*EXPOID_BASE_ID\s*= (\d+),')
+
+def calc_ids(fname, base_id):
"""Figure out the value of the enums in a C file
Args:
fname (str): Filename to parse
+ base_id (int): Base ID (value of EXPOID_BASE_ID)
Returns:
OrderedDict():
@@ -55,8 +60,12 @@ def calc_ids(fname):
if not line or line.startswith('/*'):
continue
m_enum = RE_ENUM.match(line)
- if m_enum.group(3):
- cur_id = int(m_enum.group(3))
+ enum_name = m_enum.group(3)
+ if enum_name:
+ if enum_name == 'EXPOID_BASE_ID':
+ cur_id = base_id
+ else:
+ cur_id = int(enum_name)
vals[m_enum.group(1)] = cur_id
cur_id += 1
else:
@@ -67,10 +76,24 @@ def calc_ids(fname):
return vals
+def find_base_id():
+ fname = 'include/expo.h'
+ base_id = None
+ with open(fname, 'r', encoding='utf-8') as inf:
+ for line in inf.readlines():
+ m_base_id = RE_BASE_ID.match(line)
+ if m_base_id:
+ base_id = int(m_base_id.group(1))
+ if base_id is None:
+ raise ValueError('EXPOID_BASE_ID not found in expo.h')
+ #print(f'EXPOID_BASE_ID={base_id}')
+ return base_id
+
def run_expo(args):
"""Run the expo program"""
+ base_id = find_base_id()
fname = args.enum_fname or args.layout
- ids = calc_ids(fname)
+ ids = calc_ids(fname, base_id)
if not ids:
print(f"Warning: No enum ID values found in file '{fname}'")
diff --git a/tools/image-host.c b/tools/image-host.c
index 49ce7436bb9..5e01b853c50 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -1333,7 +1333,7 @@ int fit_add_verification_data(const char *keydir, const char *keyfile,
if (ret) {
fprintf(stderr, "Can't add verification data for node '%s' (%s)\n",
fdt_get_name(fit, noffset, NULL),
- fdt_strerror(ret));
+ strerror(-ret));
return ret;
}
}
diff --git a/tools/u_boot_pylib/test_util.py b/tools/u_boot_pylib/test_util.py
index 857ce58c98c..dd671965263 100644
--- a/tools/u_boot_pylib/test_util.py
+++ b/tools/u_boot_pylib/test_util.py
@@ -23,8 +23,9 @@ except:
use_concurrent = False
-def run_test_coverage(prog, filter_fname, exclude_list, build_dir, required=None,
- extra_args=None, single_thread='-P1'):
+def run_test_coverage(prog, filter_fname, exclude_list, build_dir,
+ required=None, extra_args=None, single_thread='-P1',
+ args=None):
"""Run tests and check that we get 100% coverage
Args:
@@ -42,6 +43,7 @@ def run_test_coverage(prog, filter_fname, exclude_list, build_dir, required=None
single_thread (str): Argument string to make the tests run
single-threaded. This is necessary to get proper coverage results.
The default is '-P0'
+ args (list of str): List of tests to run, or None to run all
Raises:
ValueError if the code coverage is not 100%
@@ -66,9 +68,10 @@ def run_test_coverage(prog, filter_fname, exclude_list, build_dir, required=None
'coverage')
cmd = ('%s%s run '
- '--omit "%s" %s %s %s %s' % (prefix, covtool, ','.join(glob_list),
- prog, extra_args or '', test_cmd,
- single_thread or '-P1'))
+ '--omit "%s" %s %s %s %s %s' % (prefix, covtool, ','.join(glob_list),
+ prog, extra_args or '', test_cmd,
+ single_thread or '-P1',
+ ' '.join(args) if args else ''))
os.system(cmd)
stdout = command.output(covtool, 'report')
lines = stdout.splitlines()