diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/binman/binman.rst | 10 | ||||
-rw-r--r-- | tools/binman/btool/mkimage.py | 5 | ||||
-rw-r--r-- | tools/binman/entries.rst | 7 | ||||
-rw-r--r-- | tools/binman/etype/fit.py | 57 | ||||
-rw-r--r-- | tools/binman/ftest.py | 95 | ||||
-rwxr-xr-x | tools/binman/main.py | 6 | ||||
-rw-r--r-- | tools/binman/test/340_fit_signature.dts | 98 | ||||
-rw-r--r-- | tools/binman/test/340_rsa2048.key | 28 | ||||
-rw-r--r-- | tools/binman/test/341_fit_signature.dts | 98 | ||||
-rw-r--r-- | tools/binman/test/342_fit_signature.dts | 61 | ||||
-rw-r--r-- | tools/buildman/builder.py | 6 | ||||
-rw-r--r-- | tools/buildman/toolchain.py | 8 | ||||
-rw-r--r-- | tools/docker/Dockerfile | 7 | ||||
-rwxr-xr-x | tools/expo.py | 33 | ||||
-rw-r--r-- | tools/image-host.c | 2 | ||||
-rw-r--r-- | tools/u_boot_pylib/test_util.py | 13 |
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() |