diff options
Diffstat (limited to 'tools')
27 files changed, 420 insertions, 80 deletions
diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst index 366491089ad..3a860421a69 100644 --- a/tools/binman/binman.rst +++ b/tools/binman/binman.rst @@ -2161,6 +2161,11 @@ BINMAN_INDIRS Sets the search path for input files used by binman by adding one or more `-I` arguments. See :ref:`External blobs`. +KEYDIR + Sets the key directory passed to FIT entries by adding a + `-a keydir=$(KEYDIR)` argument. FIT entries use this directory for + mkimage's `-k` argument when `fit,sign` or `fit,encrypt` is enabled. + BINMAN_TOOLPATHS Sets the search path for external tool used by binman by adding one or more `--toolpath` arguments. See :ref:`External tools`. diff --git a/tools/binman/btool/bootgen.py b/tools/binman/btool/bootgen.py index 1bc9f0aa96f..f740381b704 100644 --- a/tools/binman/btool/bootgen.py +++ b/tools/binman/btool/bootgen.py @@ -7,7 +7,7 @@ bootgen allows creating bootable SPL for Zynq(MP) Documentation is available via: -https://www.xilinx.com/support/documents/sw_manuals/xilinx2022_1/ug1283-bootgen-user-guide.pdf +https://docs.amd.com/r/en-US/ug1283-bootgen-user-guide/ Source code is available at: https://github.com/Xilinx/bootgen diff --git a/tools/binman/btool/mkeficapsule.py b/tools/binman/btool/mkeficapsule.py index 7638c941a8e..3d3ceb009c1 100644 --- a/tools/binman/btool/mkeficapsule.py +++ b/tools/binman/btool/mkeficapsule.py @@ -126,7 +126,7 @@ class Bintoolmkeficapsule(bintool.Bintool): cmd = ['tools-only_defconfig', 'tools'] result = self.build_from_git( - 'https://source.denx.de/u-boot/u-boot.git', + 'https://git.u-boot-project.org/u-boot/u-boot.git', cmd, 'tools/mkeficapsule') return result diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py index f28b1e6b4cb..32caa03a7e1 100644 --- a/tools/binman/etype/fit.py +++ b/tools/binman/etype/fit.py @@ -105,18 +105,20 @@ class Entry_fit(Entry_section): fit,sign Enable signing FIT images via mkimage as described in verified-boot.rst. - If the property is found and fit,engine is not set, 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. + If the property is found and fit,engine is not set, the `keydir` + entry argument is passed to mkimage via the -k flag. If no key + directory is provided, the private keys path is detected among + binman include directories. All the keys required for signing FIT + must be available at time of signing and must be located in a + single directory. fit,encrypt Enable data encryption in FIT images via mkimage. If the property - is found, the keys path is detected among binman include - directories and passed to mkimage via -k flag. All the keys - required for encrypting the FIT must be available at the time of - encrypting and must be located in a single include directory. + is found, the `keydir` entry argument is passed to mkimage via the + -k flag. If no key directory is provided, the keys path is detected + among binman include directories. All the keys required for + encrypting the FIT must be available at the time of encrypting and + must be located in a single directory. Incompatible with fit,engine. @@ -485,6 +487,7 @@ class Entry_fit(Entry_section): includes 'generator' entries which are used to create the FIT, but should not be processed as real entries. This is set up once we have the entries + _keydir (str): Key directory from the keydir EntryArg, if provided _loadables (list of str): List of generated split-elf nodes, each a node name _remove_props (list of str): Value of of-spl-remove-props EntryArg, @@ -502,8 +505,9 @@ class Entry_fit(Entry_section): self._priv_entries = {} self._loadables = [] self._remove_props = [] - props = self.GetEntryArgsOrProps( - [EntryArg('of-spl-remove-props', str)], required=False)[0] + props, self._keydir = self.GetEntryArgsOrProps( + [EntryArg('of-spl-remove-props', str), + EntryArg('keydir', str)], required=False) if props: self._remove_props = props.split() self.mkimage = None @@ -701,7 +705,7 @@ class Entry_fit(Entry_section): args.update({'engine': engine}) # If no engine, keys must exist locally, find them if engine is None: - keydir = self._get_keys_dir(data) + keydir = self._keydir or self._get_keys_dir(data) elif self._fit_props.get('fit,encrypt') is not None: self.Raise('fit,engine currently does not support encryption') diff --git a/tools/binman/etype/gbb.py b/tools/binman/etype/gbb.py index cca18af6e2f..70067a54504 100644 --- a/tools/binman/etype/gbb.py +++ b/tools/binman/etype/gbb.py @@ -48,7 +48,7 @@ class Entry_gbb(Entry): the root and recovery keys that are used to verify the boot process. Some more details are here: - https://www.chromium.org/chromium-os/firmware-porting-guide/2-concepts + https://www.chromium.org/chromium-os/developer-library/guides/firmware/firmware-porting-guide/2-concepts/ but note that the page dates from 2013 so is quite out of date. See README.chromium for how to obtain the required keys and tools. diff --git a/tools/binman/etype/nxp_imx8mcst.py b/tools/binman/etype/nxp_imx8mcst.py index dd9f226b751..29a7451678d 100644 --- a/tools/binman/etype/nxp_imx8mcst.py +++ b/tools/binman/etype/nxp_imx8mcst.py @@ -20,8 +20,9 @@ from binman import elf from dtoc import fdt_util from u_boot_pylib import tools -MAGIC_NXP_IMX_IVT = 0x412000d1 -MAGIC_FITIMAGE = 0xedfe0dd0 +MAGIC_NXP_IMX_IVT = 0x412000d1 +MAGIC_NXP_IMX_FCFB = 0x42464346 +MAGIC_FITIMAGE = 0xedfe0dd0 KEY_NAME = 'sha256_4096_65537_v3_usr_crt' @@ -65,6 +66,13 @@ class Entry_nxp_imx8mcst(Entry_mkimage): Properties / Entry arguments: - nxp,loader-address - loader address (SPL text base) + - nxp,srk-table - full path to SRK_1_2_3_4_table.bin + - nxp,csf-crt - full path to the CSF Key CSF1_1_sha256_4096_65537_v3_usr_crt.pem + - nxp,img-crt - full path to the IMG Key IMG1_1_sha256_4096_65537_v3_usr_crt.pem + - nxp,fast-auth - enable fast authentication method + - nxp,srk-crt - full path to the SRK Key SRK1_sha256_4096_65537_v3_ca_crt.pem + - nxp,unlock - unlock CAAM in SPL + - nxp,cst-backend - CST tool backend, default is 'ssl', or selectable 'pkcs11' """ def __init__(self, section, etype, node): @@ -90,6 +98,10 @@ class Entry_nxp_imx8mcst(Entry_mkimage): 'SRK_KEY', fdt_util.GetString(self._node, 'nxp,srk-crt', f'SRK1_{KEY_NAME}.pem')) + self.backend = os.getenv( + 'CST_BACKEND', fdt_util.GetString(self._node, 'nxp,cst-backend', + 'ssl')) + self.unlock = fdt_util.GetBool(self._node, 'nxp,unlock') self.ReadEntries() @@ -101,6 +113,9 @@ class Entry_nxp_imx8mcst(Entry_mkimage): # - If it is mkimage'd imx8mimage, then extract to be signed data size # from imx8mimage header, and calculate CSF blob offset right past # the SPL from this information. + # - If it is mkimage'd imx8mimage wrapped in FCFB, then extract to be + # signed data size from imx8mimage header past the FCFB header, and + # calculate CSF blob offset right past the SPL from this information. # - If it is fitImage, then pad the image to 4k, add generated IVT and # sign the whole payload, then append CSF blob at the end right past # the IVT. @@ -114,6 +129,17 @@ class Entry_nxp_imx8mcst(Entry_mkimage): signsize = struct.unpack('<I', data[24:28])[0] - signbase # Remove mkimage generated padding from the end of data data = data[:signsize] + elif signtype == MAGIC_NXP_IMX_FCFB: # SPL/imx8mimage with FCFB + # Sign the payload including FCFB and imx8mimage headers + # (extra 0x1000 and 0x40 bytes before the payload) + signbase -= 0x1040 + # Pull the end address from IVT offset 24 Bytes and subtract + # the start address to get amount of data to sign. The IVT + # itself is at offset 4096 Bytes, so the total end address + # offset in the image is 4120 Bytes. + signsize = struct.unpack('<I', data[4120:4124])[0] - signbase + # Remove mkimage generated padding from the end of data + data = data[:signsize] elif signtype == MAGIC_FITIMAGE: # fitImage # Align fitImage to 4k signsize = tools.align(len(data), 0x1000) @@ -161,8 +187,14 @@ class Entry_nxp_imx8mcst(Entry_mkimage): with open(cfg_fname, 'w') as cfgf: config.write(cfgf) + # SSL is the default backend, PKCS11 backend is optional + if self.backend == "pkcs11": + cst_backend = "pkcs11" + else: + cst_backend = "ssl" + output_fname = tools.get_output_filename(f'nxp.csf-output-blob.{uniq}') - args = ['-i', cfg_fname, '-o', output_fname] + args = ['-i', cfg_fname, '-o', output_fname, '-b', cst_backend] if self.cst.run_cmd(*args) is not None: outdata = tools.read_file(output_fname) # fixme: 0x2000 should be CONFIG_CSF_SIZE diff --git a/tools/binman/etype/nxp_imx8mimage.py b/tools/binman/etype/nxp_imx8mimage.py index 25c43438a87..38d31b1bc09 100644 --- a/tools/binman/etype/nxp_imx8mimage.py +++ b/tools/binman/etype/nxp_imx8mimage.py @@ -7,7 +7,7 @@ # configuration file and input data. # -import os +import struct from collections import OrderedDict @@ -25,8 +25,26 @@ class Entry_nxp_imx8mimage(Entry_mkimage): - nxp,boot-from - device to boot from (e.g. 'sd') - nxp,loader-address - loader address (SPL text base) - nxp,rom-version - BootROM version ('2' for i.MX8M Nano and Plus) - - nxp,fspi-header-filename - FSPI header file name (CONFIG_FSPI_CONF_FILE). - Used only if 'nxp,boot-from == "fspi"' . + + Properties / Entry arguments for FSPI boot mode (nxp,boot-from = "fspi"): + - nxp,fspi-columnaddresswidth - FSPI column address width + (3 - HyperFlash, 12/13 - Serial NAND, 0 - Otherwise (default)) + - nxp,fspi-controllermisc-diffclk - FSPI differential clock enable (default off) + - nxp,fspi-controllermisc-wordaddr - FSPI word addressable enable (default off) + - nxp,fspi-controllermisc-safecfg - FSPI safe configuration frequency (default off) + - nxp,fspi-controllermisc-padovr - FSPI pad setting override (default off) + - nxp,fspi-controllermisc-ddrmode - FSPI DDR mode (default off) + - nxp,fspi-lutcustomseq - FSPI use LUT sequence parameters (default off) + - nxp,fspi-devicetype - FSPI device type + (1 - SPI NOR (default), 2 - Serial NAND) + - nxp,fspi-flasha1size - FSPI device size (default 0x10000000) + - nxp,fspi-flashpadtype - FSPI flash pad type + (1 - Single pad (default), 2 - Dual pads, 4 - Quad pads, 8 - Octal pads) + - nxp,fspi-readsampleclksrc - FSPI clock source + (0 - Internal loopback (default), 1 - loopback from DQS pad, 3 - Flash provided DQS). + - nxp,fspi-serialclkfreq - FSPI clock frequency + (1 - 30 MHz, 2 - 50 MHz (default), 3 - 60 MHz, 4 - 75 MHz, 5 - 80 MHz, + 6 - 100 MHz, 7 - 133 MHz, 8 - 166 MHz). """ def __init__(self, section, etype, node): @@ -37,9 +55,30 @@ class Entry_nxp_imx8mimage(Entry_mkimage): def ReadNode(self): super().ReadNode() self.boot_from = fdt_util.GetString(self._node, 'nxp,boot-from') - self.fspi_header = fdt_util.GetString(self._node, 'nxp,fspi-header-filename', 'fspi_header.bin') + self.fspi_columnadresswidth = fdt_util.GetInt(self._node, 'nxp,fspi-columnaddresswidth', 0) + self.fspi_controllermisc_diffclk = fdt_util.GetBool(self._node, 'nxp,fspi-controllermisc-diffclk') + self.fspi_controllermisc_wordaddr = fdt_util.GetBool(self._node, 'nxp,fspi-controllermisc-wordaddr') + self.fspi_controllermisc_safecfg = fdt_util.GetBool(self._node, 'nxp,fspi-controllermisc-safecfg') + self.fspi_controllermisc_padovr = fdt_util.GetBool(self._node, 'nxp,fspi-controllermisc-padovr') + self.fspi_controllermisc_ddrmode = fdt_util.GetBool(self._node, 'nxp,fspi-controllermisc-ddrmode') + self.fspi_devicetype = fdt_util.GetInt(self._node, 'nxp,fspi-devicetype', 1) + self.fspi_flasha1size = fdt_util.GetInt(self._node, 'nxp,fspi-flasha1size', 0x10000000) + self.fspi_flashpadtype = fdt_util.GetInt(self._node, 'nxp,fspi-flashpadtype', 1) + self.fspi_lutcustomseq = fdt_util.GetBool(self._node, 'nxp,fspi-lutcustomseq') + self.fspi_readsampleclksrc = fdt_util.GetInt(self._node, 'nxp,fspi-readsampleclksrc', 0) + self.fspi_serialclkfreq = fdt_util.GetInt(self._node, 'nxp,fspi-serialclkfreq', 2) self.loader_address = fdt_util.GetInt(self._node, 'nxp,loader-address') self.rom_version = fdt_util.GetInt(self._node, 'nxp,rom-version') + if not self.fspi_columnadresswidth in [ 0, 3, 12, 13 ]: + self.Raise('nxp,fspi-columnaddresswidth can be 0, 3, 12, 13 only.') + if not self.fspi_devicetype in [ 1, 2 ]: + self.Raise('nxp,fspi-devicetype can be 1, 2 only.') + if not self.fspi_flashpadtype in [ 1, 2, 4, 8 ]: + self.Raise('nxp,fspi-flashpadtype can be 1, 2, 4, 8 only.') + if not self.fspi_readsampleclksrc in [ 0, 1, 3 ]: + self.Raise('nxp,fspi-readsampleclksrc can be 0, 1, 3 only.') + if not self.fspi_serialclkfreq in [ 1, 2, 3, 4, 5, 6, 7, 8 ]: + self.Raise('nxp,fspi-serialclkfreq can be 1..8 only.') self.ReadEntries() def BuildSectionData(self, required): @@ -59,9 +98,51 @@ class Entry_nxp_imx8mimage(Entry_mkimage): if self.mkimage.run_cmd(*args) is not None: outdata = tools.read_file(output_fname) if self.boot_from == 'fspi': - spidata = tools.read_file(os.path.join(tools.get_output_dir(), self.fspi_header)) - if len(spidata) != 448: - raise ValueError("FSPI header is not 448 Bytes long") + # 0x00 ... Tag + spidata = struct.pack('<I', 0x42464346) + # 0x04 ... Version + spidata += struct.pack('<I', 0x56010000) + # 0x08 ... Reserved + spidata += struct.pack('<I', 0) + # 0x0c ... readSampleClkSrc (LSByte at 0x0c), dataHoldTime, + # dataSetupTime, columnAdressWidth (MSByte at 0x0f) + spidata += struct.pack('<I', 0x00030300 | + (self.fspi_columnadresswidth << 24) | + self.fspi_readsampleclksrc) + + # 0x10..0x3f ... Padding + spidata += tools.get_bytes(0, 0x30) + + # 0x40 ... controllerMiscOption + spidata += struct.pack('<I', + ((1 << 0) if self.fspi_controllermisc_diffclk else 0) | + ((1 << 3) if self.fspi_controllermisc_wordaddr else 0) | + ((1 << 4) if self.fspi_controllermisc_safecfg else 0) | + ((1 << 5) if self.fspi_controllermisc_padovr else 0) | + ((1 << 6) if self.fspi_controllermisc_ddrmode else 0)) + + # 0x44 ... deviceType (LSByte at 0x44), sflashPadType, + # serialClkFreq, lutCustomSeqEnable (MSByte at 0x47) + spidata += struct.pack('<I', + ((1 << 24) if self.fspi_lutcustomseq else 0) | + (self.fspi_serialclkfreq << 16) | + (self.fspi_flashpadtype << 8) | + self.fspi_devicetype) + + # 0x48..0x4f ... Padding + spidata += tools.get_bytes(0, 0x8) + + # 0x50 ... flashA1Size + spidata += struct.pack('<I', self.fspi_flasha1size) + + # 0x54..0x7f ... Padding + spidata += tools.get_bytes(0, 0x2c) + + # 0x80 ... lookupTable + spidata += struct.pack('<I', 0x0818040b) + spidata += struct.pack('<I', 0x24043008) + + # 0x88..0xfff ... Padding (end of FSPI block is 0x1bf, align to 4k) spidata += tools.get_bytes(0, 0x1000 - len(spidata)) outdata = spidata + outdata return outdata diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index ea2fa6eb83a..a0e8bde7901 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -8029,6 +8029,39 @@ fdt fdtmap Extract the devicetree blob from the fdtmap err = stderr.getvalue() self.assertRegex(err, "Image 'image'.*missing bintools.*: cst") + def testNxpImx8mCSTPKCS11(self): + """Test CST signing with IVT-format input (pkcs11 auth, no unlock)""" + # Create fake IVT blob: magic(4) + padding(20) + signsize_addr(4) + # + padding(36) = 64 bytes + ivt_data = struct.pack('<I', 0x412000d1) + ivt_data += b'\x00' * 20 + ivt_data += struct.pack('<I', 0) + ivt_data += b'\x00' * 36 + self._MakeInputFile('imx8m-ivt.bin', ivt_data) + with terminal.capture() as (_, stderr): + self._DoTestFile('vendor/nxp_imx8_csf_pkcs11.dts', + force_missing_bintools='cst') + err = stderr.getvalue() + self.assertRegex(err, "Image 'image'.*missing bintools.*: cst") + + def testNxpImx8mCSTFCFB(self): + """Test CST signing with FCFB-format input (normal auth, no unlock)""" + # Create fake FCFB blob: magic(4) + padding(4116) + ivt_data = struct.pack('<I', 0x42464346) + ivt_data += b'\x00' * 4116 + # Create fake IVT blob: magic(4) + padding(20) + signsize_addr(4) + # + padding(36) = 64 bytes + ivt_data += struct.pack('<I', 0x412000d1) + ivt_data += b'\x00' * 20 + ivt_data += struct.pack('<I', 0) + ivt_data += b'\x00' * 36 + self._MakeInputFile('imx8m-ivt.bin', ivt_data) + with terminal.capture() as (_, stderr): + self._DoTestFile('vendor/nxp_imx8_csf.dts', + force_missing_bintools='cst') + err = stderr.getvalue() + self.assertRegex(err, "Image 'image'.*missing bintools.*: cst") + def testNxpImx8mCSTFastAuth(self): """Test CST signing with fast-auth mode, unlock, and FIT format""" # FIT magic covers the FIT-signing path; fast-auth/unlock cover the @@ -8106,17 +8139,18 @@ fdt fdtmap Extract the devicetree blob from the fdtmap def testNxpImx8MFSPI(self): """Test that binman can produce an iMX8m FSPI image""" - testdir = tempfile.mkdtemp(prefix='binman.') - - tools.write_file(os.path.join(testdir, 'fspi_header.bin'), tools.get_bytes(0, 448)) - with terminal.capture(): - self._DoTestFile('vendor/nxp_imx8m_fspi.dts', output_dir=testdir) - self._DoTestFile('vendor/nxp_imx8m_fspi_pass.dts', output_dir=testdir) - - tools.write_file(os.path.join(testdir, 'fspi_header_fail.bin'), tools.get_bytes(0, 4097)) - with terminal.capture(): - with self.assertRaises(ValueError) as e: - self._DoTestFile('vendor/nxp_imx8m_fspi_fail.dts', output_dir=testdir) + self._DoTestFile('vendor/nxp_imx8m_fspi.dts') + self._DoTestFile('vendor/nxp_imx8m_fspi_pass.dts') + with self.assertRaises(ValueError) as e: + self._DoTestFile('vendor/nxp_imx8m_fspi_fail_columnadresswidth.dts') + with self.assertRaises(ValueError) as e: + self._DoTestFile('vendor/nxp_imx8m_fspi_fail_devicetype.dts') + with self.assertRaises(ValueError) as e: + self._DoTestFile('vendor/nxp_imx8m_fspi_fail_flashpadtype.dts') + with self.assertRaises(ValueError) as e: + self._DoTestFile('vendor/nxp_imx8m_fspi_fail_readsampleclksrc.dts') + with self.assertRaises(ValueError) as e: + self._DoTestFile('vendor/nxp_imx8m_fspi_fail_serialclkfreq.dts') def testNxpHeaderDdrfw(self): """Test that binman can add a header to DDR PHY firmware images""" @@ -8172,6 +8206,31 @@ fdt fdtmap Extract the devicetree blob from the fdtmap self.assertIsNotNone(signature) self.assertIsNotNone(signature.props.get('value')) + def testFitSignKeydir(self): + """Test that the keydir EntryArg is passed to mkimage""" + if not elf.ELF_TOOLS: + self.skipTest('Python elftools not available') + data = tools.read_file(self.TestFile("fit/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") + entry_args = { + 'of-list': 'test-fdt1', + 'default-dt': 'test-fdt1', + 'atf-bl31-path': 'bl31.elf', + 'keydir': keys_subdir, + } + data = self._DoReadFileDtb( + 'fit/signature.dts', + entry_args=entry_args, + extra_indirs=[test_subdir])[0] + + dtb = fdt.Fdt.FromData(data) + dtb.Scan() + signature = dtb.GetNode('/configurations/conf-uboot-1/signature') + self.assertIsNotNone(signature.props.get('value')) + def testFitSignEngineSimple(self): """Test that image with FIT and signature nodes can be signed with an OpenSSL Engine""" @@ -8512,6 +8571,21 @@ fdt fdtmap Extract the devicetree blob from the fdtmap dec_data = file.read() self.assertEqual(U_BOOT_NODTB_DATA, dec_data.encode('ascii')) + def testSimpleFitEncryptedDataKeydir(self): + """Test that encrypted FIT data uses the keydir EntryArg""" + data = tools.read_file(self.TestFile("fit/aes256.bin")) + self._MakeInputFile("keys/aes256.bin", data) + + keys_subdir = os.path.join(self._indir, "keys") + data = self._DoReadFileDtb( + 'fit/encrypt_data.dts', + entry_args={'keydir': keys_subdir})[0] + + fit = fdt.Fdt.FromData(data) + fit.Scan() + node = fit.GetNode('/images/u-boot') + self.assertIn('data-size-unciphered', fit.GetProps(node)) + def testSimpleFitEncryptedDataMissingKey(self): """Test an image with a FIT containing data to be encrypted but with a missing key""" with self.assertRaises(ValueError) as e: diff --git a/tools/binman/pyproject.toml b/tools/binman/pyproject.toml index fd43a71b02b..46204f477ca 100644 --- a/tools/binman/pyproject.toml +++ b/tools/binman/pyproject.toml @@ -20,7 +20,7 @@ classifiers = [ [project.urls] "Homepage" = "https://docs.u-boot-project.org/en/latest/develop/package/index.html" -"Bug Tracker" = "https://source.denx.de/groups/u-boot/-/issues" +"Bug Tracker" = "https://git.u-boot-project.org/groups/u-boot/-/issues" [project.scripts] binman = "binman.main:start_binman" diff --git a/tools/binman/test/vendor/nxp_imx8_csf_pkcs11.dts b/tools/binman/test/vendor/nxp_imx8_csf_pkcs11.dts new file mode 100644 index 00000000000..835ea236826 --- /dev/null +++ b/tools/binman/test/vendor/nxp_imx8_csf_pkcs11.dts @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + nxp-imx8mcst { + args; + nxp,loader-address = <0x10>; + nxp,cst-backend = "pkcs11"; + + blob { + filename = "imx8m-ivt.bin"; + }; + + imagename { + type = "section"; + + u-boot { + }; + }; + }; + }; +}; diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi.dts b/tools/binman/test/vendor/nxp_imx8m_fspi.dts index ae6cc5981e6..140e9bea2e7 100644 --- a/tools/binman/test/vendor/nxp_imx8m_fspi.dts +++ b/tools/binman/test/vendor/nxp_imx8m_fspi.dts @@ -10,7 +10,6 @@ nxp-imx8mimage { args; /* TODO: Needed by mkimage etype superclass */ nxp,boot-from = "fspi"; - nxp,fspi-header-filename = "fspi_header.bin"; nxp,rom-version = <1>; nxp,loader-address = <0x10>; }; diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_fail_columnadresswidth.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_columnadresswidth.dts new file mode 100644 index 00000000000..95efa33b5bf --- /dev/null +++ b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_columnadresswidth.dts @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + nxp-imx8mimage { + args; /* TODO: Needed by mkimage etype superclass */ + nxp,boot-from = "fspi"; + nxp,rom-version = <2>; + nxp,loader-address = <0x10>; + /* Bogus value */ + nxp,fspi-columnaddresswidth = <1>; + }; + }; +}; diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_fail.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_devicetype.dts index 5a0d758e5a3..f3b343f942f 100644 --- a/tools/binman/test/vendor/nxp_imx8m_fspi_fail.dts +++ b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_devicetype.dts @@ -10,9 +10,10 @@ nxp-imx8mimage { args; /* TODO: Needed by mkimage etype superclass */ nxp,boot-from = "fspi"; - nxp,fspi-header-filename = "fspi_header_fail.bin"; nxp,rom-version = <2>; nxp,loader-address = <0x10>; + /* Bogus value */ + nxp,fspi-devicetype = <3>; }; }; }; diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_fail_flashpadtype.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_flashpadtype.dts new file mode 100644 index 00000000000..515f81ba9f4 --- /dev/null +++ b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_flashpadtype.dts @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + nxp-imx8mimage { + args; /* TODO: Needed by mkimage etype superclass */ + nxp,boot-from = "fspi"; + nxp,rom-version = <2>; + nxp,loader-address = <0x10>; + /* Bogus value */ + nxp,fspi-flashpadtype = <9>; + }; + }; +}; diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_fail_readsampleclksrc.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_readsampleclksrc.dts new file mode 100644 index 00000000000..b409a6099a3 --- /dev/null +++ b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_readsampleclksrc.dts @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + nxp-imx8mimage { + args; /* TODO: Needed by mkimage etype superclass */ + nxp,boot-from = "fspi"; + nxp,rom-version = <2>; + nxp,loader-address = <0x10>; + /* Bogus value */ + nxp,fspi-readsampleclksrc = <2>; + }; + }; +}; diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_fail_serialclkfreq.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_serialclkfreq.dts new file mode 100644 index 00000000000..a71522838e8 --- /dev/null +++ b/tools/binman/test/vendor/nxp_imx8m_fspi_fail_serialclkfreq.dts @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + nxp-imx8mimage { + args; /* TODO: Needed by mkimage etype superclass */ + nxp,boot-from = "fspi"; + nxp,rom-version = <2>; + nxp,loader-address = <0x10>; + /* Bogus value */ + nxp,fspi-serialclkfreq = <9>; + }; + }; +}; diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts b/tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts index 448d93d277a..1545cf6e44c 100644 --- a/tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts +++ b/tools/binman/test/vendor/nxp_imx8m_fspi_pass.dts @@ -10,7 +10,6 @@ nxp-imx8mimage { args; /* TODO: Needed by mkimage etype superclass */ nxp,boot-from = "fspi"; - /* Default nxp,fspi-header-filename = "fspi_header.bin"; */ nxp,rom-version = <2>; nxp,loader-address = <0x10>; }; diff --git a/tools/buildman/board.py b/tools/buildman/board.py index 248d8bfff18..231454dc8cd 100644 --- a/tools/buildman/board.py +++ b/tools/buildman/board.py @@ -10,7 +10,7 @@ class Board: """Create a new board type. Args: - status: define whether the board is 'Active' or 'Orphaned' + status: define whether the board is 'Active' or 'Orphan' arch: Architecture name (e.g. arm) cpu: Cpu name (e.g. arm1136) soc: Name of SOC, or '' if none (e.g. mx31) diff --git a/tools/buildman/func_test.py b/tools/buildman/func_test.py index 51c6855420e..fce615ba8b8 100644 --- a/tools/buildman/func_test.py +++ b/tools/buildman/func_test.py @@ -951,7 +951,7 @@ Active aarch64 armv8 - armltd total_compute board2 self.assertEqual(["WARNING: no maintainers for 'board0'"], warnings) # Mark a board as orphaned - this should give a warning - lines = ['S: Orphaned' if line.startswith('S') else line + lines = ['S: Orphan' if line.startswith('S') else line for line in orig_data.splitlines(keepends=True)] tools.write_file(main, ''.join(lines), binary=False) params_list, warnings = self._boards.build_board_list(config_dir, src) diff --git a/tools/buildman/pyproject.toml b/tools/buildman/pyproject.toml index 5f5c405afbf..8a27bbaf167 100644 --- a/tools/buildman/pyproject.toml +++ b/tools/buildman/pyproject.toml @@ -24,7 +24,7 @@ classifiers = [ [project.urls] "Homepage" = "https://docs.u-boot-project.org/en/latest/build/buildman.html" -"Bug Tracker" = "https://source.denx.de/groups/u-boot/-/issues" +"Bug Tracker" = "https://git.u-boot-project.org/groups/u-boot/-/issues" [project.scripts] buildman = "buildman.main:run_buildman" diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index a91a1060cc4..ebb679a5f46 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -358,11 +358,11 @@ USER uboot:uboot # Populate the cache for pip to use. Get these via wget as the # COPY / ADD directives don't work as we need them to. -RUN wget -O /tmp/pytest-requirements.txt https://source.denx.de/u-boot/u-boot/-/raw/master/test/py/requirements.txt -RUN wget -O /tmp/sphinx-requirements.txt https://source.denx.de/u-boot/u-boot/-/raw/master/doc/sphinx/requirements.txt -RUN wget -O /tmp/binman-requirements.txt https://source.denx.de/u-boot/u-boot/-/raw/master/tools/binman/requirements.txt -RUN wget -O /tmp/buildman-requirements.txt https://source.denx.de/u-boot/u-boot/-/raw/master/tools/buildman/requirements.txt -RUN wget -O /tmp/u_boot_pylib-requirements.txt https://source.denx.de/u-boot/u-boot/-/raw/master/tools/u_boot_pylib/requirements.txt +RUN wget -O /tmp/pytest-requirements.txt https://git.u-boot-project.org/u-boot/u-boot/-/raw/master/test/py/requirements.txt +RUN wget -O /tmp/sphinx-requirements.txt https://git.u-boot-project.org/u-boot/u-boot/-/raw/master/doc/sphinx/requirements.txt +RUN wget -O /tmp/binman-requirements.txt https://git.u-boot-project.org/u-boot/u-boot/-/raw/master/tools/binman/requirements.txt +RUN wget -O /tmp/buildman-requirements.txt https://git.u-boot-project.org/u-boot/u-boot/-/raw/master/tools/buildman/requirements.txt +RUN wget -O /tmp/u_boot_pylib-requirements.txt https://git.u-boot-project.org/u-boot/u-boot/-/raw/master/tools/u_boot_pylib/requirements.txt RUN python3 -m venv /tmp/venv && \ . /tmp/venv/bin/activate && \ pip install -r /tmp/pytest-requirements.txt \ diff --git a/tools/dtoc/pyproject.toml b/tools/dtoc/pyproject.toml index 53b09dba885..895bdc9b763 100644 --- a/tools/dtoc/pyproject.toml +++ b/tools/dtoc/pyproject.toml @@ -20,7 +20,7 @@ classifiers = [ [project.urls] "Homepage" = "https://docs.u-boot-project.org/en/latest/develop/driver-model/of-plat.html" -"Bug Tracker" = "https://source.denx.de/groups/u-boot/-/issues" +"Bug Tracker" = "https://git.u-boot-project.org/groups/u-boot/-/issues" [project.scripts] dtoc = "dtoc.main:run_dtoc" diff --git a/tools/fit_image.c b/tools/fit_image.c index 5831b07c090..7e59bc43b77 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -898,8 +898,6 @@ err: static int fit_import_data(struct image_tool_params *params, const char *fname) { void *fdt, *old_fdt; - void *data = NULL; - const char *ext_data_prop = NULL; int fit_size, new_size, size, data_base; int fd; struct stat sbuf; @@ -941,6 +939,8 @@ static int fit_import_data(struct image_tool_params *params, const char *fname) for (node = fdt_first_subnode(fdt, images); node >= 0; node = fdt_next_subnode(fdt, node)) { + const char *ext_data_prop = NULL; + void *data = NULL; int buf_ptr; int len; diff --git a/tools/image-host.c b/tools/image-host.c index 8f1e7be4066..16a5ad6c22d 100644 --- a/tools/image-host.c +++ b/tools/image-host.c @@ -1184,6 +1184,41 @@ static const char *fit_config_get_image_list(const void *fit, int noffset, } /** + * fit_config_add_node() - Add a node's path to a list of nodes to hash + * + * @fit: Pointer to the FIT format image header + * @noffset: Offset of the node whose path should be added + * @node_inc: List of nodes to add to + * @conf_name Configuration-node name, child of /configurations node (only + * used for error messages) + * @sig_name Signature-node name (only used for error messages) + * @iname: Name of image being processed (e.g. "kernel-1" (only used + * for error messages) + */ +static int fit_config_add_node(const void *fit, int noffset, + struct strlist *node_inc, const char *conf_name, + const char *sig_name, const char *iname) +{ + char path[200]; + int ret; + + ret = fdt_get_path(fit, noffset, path, sizeof(path)); + if (ret < 0) { + fprintf(stderr, + "Failed to get path for image '%s' in configuration '%s/%s': %s\n", + iname, conf_name, sig_name, fdt_strerror(ret)); + return -ENOENT; + } + if (strlist_add(node_inc, path)) { + fprintf(stderr, "Out of memory processing configuration '%s/%s'\n", + conf_name, sig_name); + return -ENOMEM; + } + + return 0; +} + +/** * fit_config_add_hash() - Add a list of nodes to hash for an image * * This adds a list of paths to image nodes (as referred to by a particular @@ -1202,16 +1237,14 @@ static int fit_config_add_hash(const void *fit, int image_noffset, struct strlist *node_inc, const char *conf_name, const char *sig_name, const char *iname) { - char path[200]; int noffset; int hash_count; int ret; - ret = fdt_get_path(fit, image_noffset, path, sizeof(path)); - if (ret < 0) - goto err_path; - if (strlist_add(node_inc, path)) - goto err_mem; + ret = fit_config_add_node(fit, image_noffset, node_inc, conf_name, + sig_name, iname); + if (ret) + return ret; /* Add all this image's hashes */ hash_count = 0; @@ -1223,11 +1256,10 @@ static int fit_config_add_hash(const void *fit, int image_noffset, if (strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) continue; - ret = fdt_get_path(fit, noffset, path, sizeof(path)); - if (ret < 0) - goto err_path; - if (strlist_add(node_inc, path)) - goto err_mem; + ret = fit_config_add_node(fit, noffset, node_inc, conf_name, + sig_name, iname); + if (ret) + return ret; hash_count++; } @@ -1249,24 +1281,34 @@ static int fit_config_add_hash(const void *fit, int image_noffset, fdt_strerror(noffset)); return -EIO; } - ret = fdt_get_path(fit, noffset, path, sizeof(path)); - if (ret < 0) - goto err_path; - if (strlist_add(node_inc, path)) - goto err_mem; + ret = fit_config_add_node(fit, noffset, node_inc, conf_name, + sig_name, iname); + if (ret) + return ret; } - return 0; - -err_mem: - fprintf(stderr, "Out of memory processing configuration '%s/%s'\n", conf_name, - sig_name); - return -ENOMEM; + /* + * Add this image's dm-verity node if present. Its roothash is the + * only integrity anchor for a dm-verity filesystem image, so it must + * be covered by the configuration signature. + */ + noffset = fdt_subnode_offset(fit, image_noffset, + FIT_VERITY_NODENAME); + if (noffset != -FDT_ERR_NOTFOUND) { + if (noffset < 0) { + fprintf(stderr, + "Failed to get dm-verity node in configuration '%s/%s' image '%s': %s\n", + conf_name, sig_name, iname, + fdt_strerror(noffset)); + return -EIO; + } + ret = fit_config_add_node(fit, noffset, node_inc, conf_name, + sig_name, iname); + if (ret) + return ret; + } -err_path: - fprintf(stderr, "Failed to get path for image '%s' in configuration '%s/%s': %s\n", - iname, conf_name, sig_name, fdt_strerror(ret)); - return -ENOENT; + return 0; } /** diff --git a/tools/patman/settings.py b/tools/patman/settings.py index 17229e0d823..fe65b1d3fb7 100644 --- a/tools/patman/settings.py +++ b/tools/patman/settings.py @@ -162,7 +162,7 @@ class _ProjectConfigParser(ConfigParser.ConfigParser): def ReadGitAliases(fname): """Read a git alias file. This is in the form used by git: - alias uboot [email protected] + alias uboot [email protected] alias wd Wolfgang Denk <[email protected]> Args: diff --git a/tools/u_boot_pylib/gitutil.py b/tools/u_boot_pylib/gitutil.py index 34b4dbb4839..59688aa7147 100644 --- a/tools/u_boot_pylib/gitutil.py +++ b/tools/u_boot_pylib/gitutil.py @@ -528,7 +528,7 @@ send --cc-cmd cc-fname" cover p1 p2' "Please add something like this to a commit\n" "Series-to: Fred Bloggs <[email protected]>\n" "Or do something like this\n" - "git config sendemail.to [email protected]") + "git config sendemail.to [email protected]") return None cc = build_email_list(list(set(series.get('cc')) - set(series.get('to'))), alias, '--cc', warn_on_error) diff --git a/tools/u_boot_pylib/pyproject.toml b/tools/u_boot_pylib/pyproject.toml index 1c6a023ee4b..300d14441c8 100644 --- a/tools/u_boot_pylib/pyproject.toml +++ b/tools/u_boot_pylib/pyproject.toml @@ -19,7 +19,7 @@ classifiers = [ [project.urls] "Homepage" = "https://docs.u-boot-project.org" -"Bug Tracker" = "https://source.denx.de/groups/u-boot/-/issues" +"Bug Tracker" = "https://git.u-boot-project.org/groups/u-boot/-/issues" [tool.setuptools] packages = ["u_boot_pylib"] |
