summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/binman/btool/mkimage.py8
-rw-r--r--tools/binman/control.py9
-rw-r--r--tools/binman/entries.rst44
-rw-r--r--tools/binman/etype/fit.py47
-rw-r--r--tools/binman/ftest.py111
-rw-r--r--tools/binman/test/343_fit_encrypt_data.dts53
-rw-r--r--tools/binman/test/344_fit_encrypt_data_no_key.dts53
-rw-r--r--tools/binman/test/345_fit_fdt_name.dts58
-rw-r--r--tools/binman/test/aes256.bin1
-rw-r--r--tools/buildman/boards.py25
-rw-r--r--tools/buildman/buildman.rst63
-rw-r--r--tools/buildman/func_test.py85
-rwxr-xr-xtools/buildman/main.py9
-rw-r--r--tools/buildman/test.py50
-rw-r--r--tools/buildman/toolchain.py47
-rw-r--r--tools/docker/Dockerfile146
-rw-r--r--tools/dtoc/fdt_util.py5
-rw-r--r--tools/image-host.c2
-rw-r--r--tools/imx8image.c2
-rwxr-xr-xtools/imx_cntr_image.sh4
-rw-r--r--tools/u_boot_pylib/tools.py16
21 files changed, 707 insertions, 131 deletions
diff --git a/tools/binman/btool/mkimage.py b/tools/binman/btool/mkimage.py
index 78d3301bc10..3f84220fb1a 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, priv_keys_dir=None):
+ pad=None, align=None, keys_dir=None):
"""Run mkimage
Args:
@@ -34,7 +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
+ keys_dir: Path to directory containing private and encryption keys
version: True to get the mkimage version
"""
args = []
@@ -46,8 +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 keys_dir:
+ args += ['-k', f'{keys_dir}']
if output_fname:
args += ['-F', output_fname]
return self.run_cmd(*args)
diff --git a/tools/binman/control.py b/tools/binman/control.py
index 542c2b45644..e73c598298c 100644
--- a/tools/binman/control.py
+++ b/tools/binman/control.py
@@ -526,7 +526,7 @@ def _RemoveTemplates(parent):
if node.name.startswith('template'):
node.Delete()
-def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, use_expanded):
+def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, use_expanded, indir):
"""Prepare the images to be processed and select the device tree
This function:
@@ -543,6 +543,7 @@ def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, use_expanded):
use_expanded: True to use expanded versions of entries, if available.
So if 'u-boot' is called for, we use 'u-boot-expanded' instead. This
is needed if update_fdt is True (although tests may disable it)
+ indir: List of directories where input files can be found
Returns:
OrderedDict of images:
@@ -558,7 +559,9 @@ def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, use_expanded):
# Get the device tree ready by compiling it and copying the compiled
# output into a file in our output directly. Then scan it for use
# in binman.
- dtb_fname = fdt_util.EnsureCompiled(dtb_fname)
+ if indir is None:
+ indir = []
+ dtb_fname = fdt_util.EnsureCompiled(dtb_fname, indir=indir)
fname = tools.get_output_filename('u-boot.dtb.out')
tools.write_file(fname, tools.read_file(dtb_fname))
dtb = fdt.FdtScan(fname)
@@ -846,7 +849,7 @@ def Binman(args):
state.SetThreads(args.threads)
images = PrepareImagesAndDtbs(dtb_fname, args.image,
- args.update_fdt, use_expanded)
+ args.update_fdt, use_expanded, args.indir)
if args.test_section_timeout:
# Set the first image to timeout, used in testThreadTimeout()
diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
index e918162fb48..780e9817fb6 100644
--- a/tools/binman/entries.rst
+++ b/tools/binman/entries.rst
@@ -197,7 +197,7 @@ source files that the tool examples:
To run the tool::
- $ tools/binman/fip_util.py -s /path/to/trusted-firmware-a
+ $ tools/binman/fip_util.py -s /path/to/arm-trusted-firmware
Warning: UUID 'UUID_NON_TRUSTED_WORLD_KEY_CERT' is not mentioned in tbbr_config.c file
Existing code in 'tools/binman/fip_util.py' is up-to-date
@@ -862,14 +862,25 @@ The top-level 'fit' node supports the following special properties:
can be provided as a directory. Each .dtb file in the directory is
processed, , e.g.::
- fit,fdt-list-dir = "arch/arm/dts
+ fit,fdt-list-dir = "arch/arm/dts";
+
+ 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.
+ 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.
+
+ 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.
Substitutions
~~~~~~~~~~~~~
@@ -892,6 +903,9 @@ DEFAULT-SEQ:
Sequence number of the default fdt, as provided by the 'default-dt'
entry argument
+DEFAULT-NAME:
+ Name of the default fdt, as provided by the 'default-dt' entry argument
+
Available operations
~~~~~~~~~~~~~~~~~~~~
@@ -953,6 +967,21 @@ You can create config nodes in a similar way::
This tells binman to create nodes `config-1` and `config-2`, i.e. a config
for each of your two files.
+It is also possible to use NAME in the node names so that the FDT files name
+will be used instead of the sequence number. This can be useful to identify
+easily at runtime in U-Boot, the config to be used::
+
+ configurations {
+ default = "@config-DEFAULT-NAME";
+ @config-NAME {
+ description = "NAME";
+ firmware = "atf";
+ loadables = "uboot";
+ fdt = "fdt-NAME";
+ fit,compatible; // optional
+ };
+ };
+
Note that if no devicetree files are provided (with '-a of-list' as above)
then no nodes will be generated.
@@ -985,7 +1014,8 @@ same approach can of course be used for SPL images.
Note that the `of-spl-remove-props` entryarg can be used to indicate
additional properties to remove. It is often used to remove properties like
-`clock-names` and `pinctrl-names` which are not needed in SPL builds.
+`clock-names` and `pinctrl-names` which are not needed in SPL builds. This
+value is automatically passed to binman by the U-Boot build.
See :ref:`fdtgrep_filter` for more information.
diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py
index b5afbda41b5..803fb66ea83 100644
--- a/tools/binman/etype/fit.py
+++ b/tools/binman/etype/fit.py
@@ -110,6 +110,13 @@ class Entry_fit(Entry_section):
available at time of signing and must be located in single include
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.
+
Substitutions
~~~~~~~~~~~~~
@@ -131,6 +138,9 @@ class Entry_fit(Entry_section):
Sequence number of the default fdt, as provided by the 'default-dt'
entry argument
+ DEFAULT-NAME:
+ Name of the default fdt, as provided by the 'default-dt' entry argument
+
Available operations
~~~~~~~~~~~~~~~~~~~~
@@ -192,6 +202,21 @@ class Entry_fit(Entry_section):
This tells binman to create nodes `config-1` and `config-2`, i.e. a config
for each of your two files.
+ It is also possible to use NAME in the node names so that the FDT files name
+ will be used instead of the sequence number. This can be useful to identify
+ easily at runtime in U-Boot, the config to be used::
+
+ configurations {
+ default = "@config-DEFAULT-NAME";
+ @config-NAME {
+ description = "NAME";
+ firmware = "atf";
+ loadables = "uboot";
+ fdt = "fdt-NAME";
+ fit,compatible; // optional
+ };
+ };
+
Note that if no devicetree files are provided (with '-a of-list' as above)
then no nodes will be generated.
@@ -452,6 +477,8 @@ class Entry_fit(Entry_section):
self._fdt_dir = fdt_util.GetString(self._node, 'fit,fdt-list-dir')
if self._fdt_dir:
indir = tools.get_input_filename(self._fdt_dir)
+ if indir:
+ tools.append_input_dirs(indir)
fdts = glob.glob('*.dtb', root_dir=indir)
self._fdts = [os.path.splitext(f)[0] for f in sorted(fdts)]
else:
@@ -518,14 +545,14 @@ 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
+ def _get_keys_dir(self, data):
+ """Detect private and encryption keys path among binman include directories
Args:
data: FIT image in binary format
Returns:
- str: Single path containing all private keys found or None
+ str: Single path containing all keys found or None
Raises:
ValueError: Filename 'rsa2048.key' not found in input path
@@ -533,11 +560,14 @@ class Entry_fit(Entry_section):
"""
def _find_keys_dir(node):
for subnode in node.subnodes:
- if subnode.name.startswith('signature'):
+ if (subnode.name.startswith('signature') or
+ subnode.name.startswith('cipher')):
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")
+ name = tools.get_input_filename(
+ f"{hint}.key" if subnode.name.startswith('signature')
+ else f"{hint}.bin")
path = os.path.dirname(name)
if path not in paths:
paths.append(path)
@@ -587,8 +617,9 @@ 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._fit_props.get('fit,sign') is not None or
+ self._fit_props.get('fit,encrypt') is not None):
+ args.update({'keys_dir': self._get_keys_dir(data)})
if self.mkimage.run(reset_timestamp=True, output_fname=output_fname,
**args) is None:
if not self.GetAllowMissing():
@@ -663,6 +694,7 @@ class Entry_fit(Entry_section):
f"not found in fdt list: {', '.join(self._fdts)}")
seq = self._fdts.index(default_dt)
val = val[1:].replace('DEFAULT-SEQ', str(seq + 1))
+ val = val.replace('DEFAULT-NAME', self._fit_default_dt)
fsw.property_string(pname, val)
return
elif pname.startswith('fit,'):
@@ -729,6 +761,7 @@ class Entry_fit(Entry_section):
# Generate nodes for each FDT
for seq, fdt_fname in enumerate(self._fdts):
node_name = node.name[1:].replace('SEQ', str(seq + 1))
+ node_name = node_name.replace('NAME', fdt_fname)
if self._fdt_dir:
fname = os.path.join(self._fdt_dir, fdt_fname + '.dtb')
else:
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 156567ace77..a553ca9e564 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -4233,56 +4233,69 @@ class TestFunctional(unittest.TestCase):
self.assertEqual(SCP_DATA, data[:len(SCP_DATA)])
def CheckFitFdt(self, dts='170_fit_fdt.dts', use_fdt_list=True,
- default_dt=None):
+ default_dt=None, use_seq_num=True):
"""Check an image with an FIT with multiple FDT images"""
- def _CheckFdt(seq, expected_data):
+ def _CheckFdt(val, expected_data):
"""Check the FDT nodes
Args:
- seq: Sequence number to check (0 or 1)
+ val: Sequence number to check (0 or 1) or fdt name
expected_data: Expected contents of 'data' property
"""
- name = 'fdt-%d' % seq
+ name = 'fdt-%s' % val
fnode = dtb.GetNode('/images/%s' % name)
self.assertIsNotNone(fnode)
self.assertEqual({'description','type', 'compression', 'data'},
set(fnode.props.keys()))
self.assertEqual(expected_data, fnode.props['data'].bytes)
- self.assertEqual('fdt-test-fdt%d.dtb' % seq,
- fnode.props['description'].value)
+ description = (
+ 'fdt-test-fdt%s.dtb' % val if len(val) == 1 else
+ 'fdt-%s.dtb' % val
+ )
+ self.assertEqual(description, fnode.props['description'].value)
self.assertEqual(fnode.subnodes[0].name, 'hash')
- def _CheckConfig(seq, expected_data):
+ def _CheckConfig(val, expected_data):
"""Check the configuration nodes
Args:
- seq: Sequence number to check (0 or 1)
+ val: Sequence number to check (0 or 1) or fdt name
expected_data: Expected contents of 'data' property
"""
cnode = dtb.GetNode('/configurations')
self.assertIn('default', cnode.props)
- self.assertEqual('config-2', cnode.props['default'].value)
+ default = (
+ 'config-2' if len(val) == 1 else
+ 'config-test-fdt2'
+ )
+ self.assertEqual(default, cnode.props['default'].value)
- name = 'config-%d' % seq
+ name = 'config-%s' % val
fnode = dtb.GetNode('/configurations/%s' % name)
self.assertIsNotNone(fnode)
self.assertEqual({'description','firmware', 'loadables', 'fdt'},
set(fnode.props.keys()))
- self.assertEqual('conf-test-fdt%d.dtb' % seq,
- fnode.props['description'].value)
- self.assertEqual('fdt-%d' % seq, fnode.props['fdt'].value)
+ description = (
+ 'conf-test-fdt%s.dtb' % val if len(val) == 1 else
+ 'conf-%s.dtb' % val
+ )
+ self.assertEqual(description, fnode.props['description'].value)
+ self.assertEqual('fdt-%s' % val, fnode.props['fdt'].value)
entry_args = {
'default-dt': 'test-fdt2',
}
+ extra_indirs = None
if use_fdt_list:
entry_args['of-list'] = 'test-fdt1 test-fdt2'
if default_dt:
entry_args['default-dt'] = default_dt
+ if use_fdt_list:
+ extra_indirs = [os.path.join(self._indir, TEST_FDT_SUBDIR)]
data = self._DoReadFileDtb(
dts,
entry_args=entry_args,
- extra_indirs=[os.path.join(self._indir, TEST_FDT_SUBDIR)])[0]
+ extra_indirs=extra_indirs)[0]
self.assertEqual(U_BOOT_NODTB_DATA, data[-len(U_BOOT_NODTB_DATA):])
fit_data = data[len(U_BOOT_DATA):-len(U_BOOT_NODTB_DATA)]
@@ -4291,13 +4304,22 @@ class TestFunctional(unittest.TestCase):
fnode = dtb.GetNode('/images/kernel')
self.assertIn('data', fnode.props)
- # Check all the properties in fdt-1 and fdt-2
- _CheckFdt(1, TEST_FDT1_DATA)
- _CheckFdt(2, TEST_FDT2_DATA)
+ if use_seq_num == True:
+ # Check all the properties in fdt-1 and fdt-2
+ _CheckFdt('1', TEST_FDT1_DATA)
+ _CheckFdt('2', TEST_FDT2_DATA)
+
+ # Check configurations
+ _CheckConfig('1', TEST_FDT1_DATA)
+ _CheckConfig('2', TEST_FDT2_DATA)
+ else:
+ # Check all the properties in fdt-1 and fdt-2
+ _CheckFdt('test-fdt1', TEST_FDT1_DATA)
+ _CheckFdt('test-fdt2', TEST_FDT2_DATA)
- # Check configurations
- _CheckConfig(1, TEST_FDT1_DATA)
- _CheckConfig(2, TEST_FDT2_DATA)
+ # Check configurations
+ _CheckConfig('test-fdt1', TEST_FDT1_DATA)
+ _CheckConfig('test-fdt2', TEST_FDT2_DATA)
def testFitFdt(self):
"""Test an image with an FIT with multiple FDT images"""
@@ -7900,5 +7922,54 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
extra_indirs=[test_subdir])[0]
+ def testSimpleFitEncryptedData(self):
+ """Test an image with a FIT containing data to be encrypted"""
+ data = tools.read_file(self.TestFile("aes256.bin"))
+ self._MakeInputFile("keys/aes256.bin", data)
+
+ keys_subdir = os.path.join(self._indir, "keys")
+ data = self._DoReadFileDtb(
+ '343_fit_encrypt_data.dts',
+ extra_indirs=[keys_subdir])[0]
+
+ fit = fdt.Fdt.FromData(data)
+ fit.Scan()
+
+ # Extract the encrypted data and the Initialization Vector from the FIT
+ node = fit.GetNode('/images/u-boot')
+ subnode = fit.GetNode('/images/u-boot/cipher')
+ data_size_unciphered = int.from_bytes(fit.GetProps(node)['data-size-unciphered'].bytes,
+ byteorder='big')
+ self.assertEqual(data_size_unciphered, len(U_BOOT_NODTB_DATA))
+
+ # Retrieve the key name from the FIT removing any null byte
+ key_name = fit.GetProps(subnode)['key-name-hint'].bytes.replace(b'\x00', b'')
+ with open(self.TestFile(key_name.decode('ascii') + '.bin'), 'rb') as file:
+ key = file.read()
+ iv = fit.GetProps(subnode)['iv'].bytes.hex()
+ enc_data = fit.GetProps(node)['data'].bytes
+ outdir = tools.get_output_dir()
+ enc_data_file = os.path.join(outdir, 'encrypted_data.bin')
+ tools.write_file(enc_data_file, enc_data)
+ data_file = os.path.join(outdir, 'data.bin')
+
+ # Decrypt the encrypted data from the FIT and compare the data
+ tools.run('openssl', 'enc', '-aes-256-cbc', '-nosalt', '-d', '-in',
+ enc_data_file, '-out', data_file, '-K', key.hex(), '-iv', iv)
+ with open(data_file, 'r') as file:
+ dec_data = file.read()
+ self.assertEqual(U_BOOT_NODTB_DATA, dec_data.encode('ascii'))
+
+ 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:
+ self._DoReadFile('344_fit_encrypt_data_no_key.dts')
+
+ self.assertIn("Filename 'aes256.bin' not found in input path", str(e.exception))
+
+ def testFitFdtName(self):
+ """Test an image with an FIT with multiple FDT images using NAME"""
+ self.CheckFitFdt('345_fit_fdt_name.dts', use_seq_num=False)
+
if __name__ == "__main__":
unittest.main()
diff --git a/tools/binman/test/343_fit_encrypt_data.dts b/tools/binman/test/343_fit_encrypt_data.dts
new file mode 100644
index 00000000000..d70de3426cf
--- /dev/null
+++ b/tools/binman/test/343_fit_encrypt_data.dts
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ fit {
+ fit,encrypt;
+ description = "Test a FIT with encrypted data";
+ #address-cells = <1>;
+
+ images {
+ u-boot {
+ description = "U-Boot";
+ type = "firmware";
+ arch = "arm64";
+ os = "U-Boot";
+ compression = "none";
+ load = <00000000>;
+ entry = <00000000>;
+ cipher {
+ algo = "aes256";
+ key-name-hint = "aes256";
+ };
+ u-boot-nodtb {
+ };
+ };
+ fdt-1 {
+ description = "Flattened Device Tree blob";
+ type = "flat_dt";
+ arch = "arm64";
+ compression = "none";
+ cipher {
+ algo = "aes256";
+ key-name-hint = "aes256";
+ };
+ };
+ };
+
+ configurations {
+ default = "conf-1";
+ conf-1 {
+ description = "Boot U-Boot with FDT blob";
+ firmware = "u-boot";
+ fdt = "fdt-1";
+ };
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/344_fit_encrypt_data_no_key.dts b/tools/binman/test/344_fit_encrypt_data_no_key.dts
new file mode 100644
index 00000000000..d70de3426cf
--- /dev/null
+++ b/tools/binman/test/344_fit_encrypt_data_no_key.dts
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ fit {
+ fit,encrypt;
+ description = "Test a FIT with encrypted data";
+ #address-cells = <1>;
+
+ images {
+ u-boot {
+ description = "U-Boot";
+ type = "firmware";
+ arch = "arm64";
+ os = "U-Boot";
+ compression = "none";
+ load = <00000000>;
+ entry = <00000000>;
+ cipher {
+ algo = "aes256";
+ key-name-hint = "aes256";
+ };
+ u-boot-nodtb {
+ };
+ };
+ fdt-1 {
+ description = "Flattened Device Tree blob";
+ type = "flat_dt";
+ arch = "arm64";
+ compression = "none";
+ cipher {
+ algo = "aes256";
+ key-name-hint = "aes256";
+ };
+ };
+ };
+
+ configurations {
+ default = "conf-1";
+ conf-1 {
+ description = "Boot U-Boot with FDT blob";
+ firmware = "u-boot";
+ fdt = "fdt-1";
+ };
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/345_fit_fdt_name.dts b/tools/binman/test/345_fit_fdt_name.dts
new file mode 100644
index 00000000000..631a8e5f59b
--- /dev/null
+++ b/tools/binman/test/345_fit_fdt_name.dts
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ u-boot {
+ };
+ fit {
+ description = "test-desc";
+ #address-cells = <1>;
+ fit,fdt-list = "of-list";
+
+ 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-NAME {
+ description = "fdt-NAME.dtb";
+ type = "flat_dt";
+ compression = "none";
+ hash {
+ algo = "sha256";
+ };
+ };
+ };
+
+ configurations {
+ default = "@config-DEFAULT-NAME";
+ @config-NAME {
+ description = "conf-NAME.dtb";
+ firmware = "uboot";
+ loadables = "atf";
+ fdt = "fdt-NAME";
+ };
+ };
+ };
+ u-boot-nodtb {
+ };
+ };
+};
diff --git a/tools/binman/test/aes256.bin b/tools/binman/test/aes256.bin
new file mode 100644
index 00000000000..09b8bf6254a
--- /dev/null
+++ b/tools/binman/test/aes256.bin
@@ -0,0 +1 @@
+1234567890abcdefghijklmnopqrstuv \ No newline at end of file
diff --git a/tools/buildman/boards.py b/tools/buildman/boards.py
index 3c2822715f3..9e7b486656b 100644
--- a/tools/buildman/boards.py
+++ b/tools/buildman/boards.py
@@ -19,7 +19,10 @@ import time
from buildman import board
from buildman import kconfiglib
+from u_boot_pylib import command
from u_boot_pylib.terminal import print_clear, tprint
+from u_boot_pylib import tools
+from u_boot_pylib import tout
### constant variables ###
OUTPUT_FILE = 'boards.cfg'
@@ -202,6 +205,7 @@ class KconfigScanner:
os.environ['KCONFIG_OBJDIR'] = ''
self._tmpfile = None
self._conf = kconfiglib.Kconfig(warn=False)
+ self._srctree = srctree
def __del__(self):
"""Delete a leftover temporary file before exit.
@@ -239,7 +243,26 @@ class KconfigScanner:
expect_target, match, rear = leaf.partition('_defconfig')
assert match and not rear, f'{leaf} : invalid defconfig'
- self._conf.load_config(defconfig)
+ temp = None
+ if b'#include' in tools.read_file(defconfig):
+ cmd = [
+ os.getenv('CPP', 'cpp'),
+ '-nostdinc', '-P',
+ '-I', self._srctree,
+ '-undef',
+ '-x', 'assembler-with-cpp',
+ defconfig]
+ result = command.run_pipe([cmd], capture=True, capture_stderr=True)
+ temp = tempfile.NamedTemporaryFile(prefix='buildman-')
+ tools.write_file(temp.name, result.stdout, False)
+ fname = temp.name
+ tout.info(f'Processing #include to produce {defconfig}')
+ else:
+ fname = defconfig
+
+ self._conf.load_config(fname)
+ if temp:
+ del temp
self._tmpfile = None
params = {}
diff --git a/tools/buildman/buildman.rst b/tools/buildman/buildman.rst
index e873611e596..924564b5700 100644
--- a/tools/buildman/buildman.rst
+++ b/tools/buildman/buildman.rst
@@ -186,23 +186,22 @@ Setting up
#. Create ~/.buildman to tell buildman where to find tool chains (see
buildman_settings_ for details). As an example::
- # Buildman settings file
+ # Buildman settings file
- [toolchain]
- root: /
- rest: /toolchains/*
- eldk: /opt/eldk-4.2
- arm: /opt/linaro/gcc-linaro-arm-linux-gnueabihf-4.8-2013.08_linux
- aarch64: /opt/linaro/gcc-linaro-aarch64-none-elf-4.8-2013.10_linux
+ [toolchain]
+ root: /
+ rest: /toolchains/*
+ eldk: /opt/eldk-4.2
+ arm: /opt/linaro/gcc-linaro-arm-linux-gnueabihf-4.8-2013.08_linux
+ aarch64: /opt/linaro/gcc-linaro-aarch64-none-elf-4.8-2013.10_linux
- [toolchain-prefix]
- arc = /opt/arc/arc_gnu_2021.03_prebuilt_elf32_le_linux_install/bin/arc-elf32-
-
- [toolchain-alias]
- riscv = riscv32
- sh = sh4
- x86: i386
+ [toolchain-prefix]
+ arc = /opt/arc/arc_gnu_2021.03_prebuilt_elf32_le_linux_install/bin/arc-elf32-
+ [toolchain-alias]
+ riscv = riscv32
+ sh = sh4
+ x86: i386
This selects the available toolchain paths. Add the base directory for
each of your toolchains here. Buildman will search inside these directories
@@ -934,6 +933,18 @@ a set of (tag, value) pairs.
For example powerpc-linux-gcc will be noted as a toolchain for 'powerpc'
and CROSS_COMPILE will be set to powerpc-linux- when using it.
+ The tilde character ``~`` is supported in paths, to represent the home
+ directory.
+
+'[toolchain-prefix]' section
+ This can be used to provide the full toolchain-prefix for one or more
+ architectures. The full CROSS_COMPILE prefix must be provided. These
+ typically have a higher priority than matches in the '[toolchain]', due to
+ this prefix.
+
+ The tilde character ``~`` is supported in paths, to represent the home
+ directory.
+
'[toolchain-alias]' section
This converts toolchain architecture names to U-Boot names. For example,
if an x86 toolchains is called i386-linux-gcc it will not normally be
@@ -1112,6 +1123,30 @@ The -U option uses the u-boot.env files which are produced by a build.
Internally, buildman writes out an out-env file into the build directory for
later comparison.
+defconfig fragments
+-------------------
+
+Buildman provides some initial support for configuration fragments. It can scan
+these when present in defconfig files and handle the resuiting Kconfig
+correctly. Thus it is possible to build a board which has a ``#include`` in the
+defconfig file.
+
+For now, Buildman simply includes the files to produce a single output file,
+using the C preprocessor. It does not call the ``merge_config.sh`` script. The
+redefined/redundant logic in that script could fairly easily be repeated in
+Buildman, to detect potential problems. For now it is not clear that this is
+useful.
+
+To specify the C preprocessor to use, set the ``CPP`` environment variable. The
+default is ``cpp``.
+
+Note that Buildman does not support adding fragments to existing boards, e.g.
+like::
+
+ make qemu_riscv64_defconfig acpi.config
+
+This is partly because there is no way for Buildman to know which fragments are
+valid on which boards.
Building with clang
-------------------
diff --git a/tools/buildman/func_test.py b/tools/buildman/func_test.py
index 0ac9fc7e44f..4e12c671a3d 100644
--- a/tools/buildman/func_test.py
+++ b/tools/buildman/func_test.py
@@ -2,8 +2,10 @@
# Copyright (c) 2014 Google, Inc
#
+import io
import os
from pathlib import Path
+import re
import shutil
import sys
import tempfile
@@ -373,6 +375,22 @@ class TestFunctional(unittest.TestCase):
def _HandleCommandSize(self, args):
return command.CommandResult(return_code=0)
+ def _HandleCommandCpp(self, args):
+ # args ['-nostdinc', '-P', '-I', '/tmp/tmp7f17xk_o/src', '-undef',
+ # '-x', 'assembler-with-cpp', fname]
+ fname = args[7]
+ buf = io.StringIO()
+ for line in tools.read_file(fname, False).splitlines():
+ if line.startswith('#include'):
+ # Example: #include <configs/renesas_rcar2.config>
+ m_incfname = re.match('#include <(.*)>', line)
+ data = tools.read_file(m_incfname.group(1), False)
+ for line in data.splitlines():
+ print(line, file=buf)
+ else:
+ print(line, file=buf)
+ return command.CommandResult(stdout=buf.getvalue(), return_code=0)
+
def _HandleCommand(self, **kwargs):
"""Handle a command execution.
@@ -406,6 +424,8 @@ class TestFunctional(unittest.TestCase):
return self._HandleCommandObjcopy(args)
elif cmd.endswith( 'size'):
return self._HandleCommandSize(args)
+ elif cmd.endswith( 'cpp'):
+ return self._HandleCommandCpp(args)
if not result:
# Not handled, so abort
@@ -1067,3 +1087,68 @@ endif
result = self._RunControl('--print-arch', 'board0')
self.assertEqual('arm\n', stdout.getvalue())
self.assertEqual('', stderr.getvalue())
+
+ def test_kconfig_scanner(self):
+ """Test using the kconfig scanner to determine important values
+
+ Note that there is already a test_scan_defconfigs() which checks the
+ higher-level scan_defconfigs() function. This test checks just the
+ scanner itself
+ """
+ src = self._git_dir
+ scanner = boards.KconfigScanner(src)
+
+ # First do a simple sanity check
+ norm = os.path.join(src, 'board0_defconfig')
+ tools.write_file(norm, 'CONFIG_TARGET_BOARD0=y', False)
+ res = scanner.scan(norm, True)
+ self.assertEqual(({
+ 'arch': 'arm',
+ 'cpu': 'armv7',
+ 'soc': '-',
+ 'vendor': 'Tester',
+ 'board': 'ARM Board 0',
+ 'config': 'config0',
+ 'target': 'board0'}, []), res)
+
+ # Check that the SoC cannot be changed and the filename does not affect
+ # the resulting board
+ tools.write_file(norm, '''CONFIG_TARGET_BOARD2=y
+CONFIG_SOC="fred"
+''', False)
+ res = scanner.scan(norm, True)
+ self.assertEqual(({
+ 'arch': 'powerpc',
+ 'cpu': 'ppc',
+ 'soc': 'mpc85xx',
+ 'vendor': 'Tester',
+ 'board': 'PowerPC board 1',
+ 'config': 'config2',
+ 'target': 'board0'}, []), res)
+
+ # Check handling of missing information
+ tools.write_file(norm, '', False)
+ res = scanner.scan(norm, True)
+ self.assertEqual(({
+ 'arch': '-',
+ 'cpu': '-',
+ 'soc': '-',
+ 'vendor': '-',
+ 'board': '-',
+ 'config': '-',
+ 'target': 'board0'},
+ ['WARNING: board0_defconfig: No TARGET_BOARD0 enabled']), res)
+
+ # check handling of #include files; see _HandleCommandCpp()
+ inc = os.path.join(src, 'common')
+ tools.write_file(inc, b'CONFIG_TARGET_BOARD0=y\n')
+ tools.write_file(norm, f'#include <{inc}>', False)
+ res = scanner.scan(norm, True)
+ self.assertEqual(({
+ 'arch': 'arm',
+ 'cpu': 'armv7',
+ 'soc': '-',
+ 'vendor': 'Tester',
+ 'board': 'ARM Board 0',
+ 'config': 'config0',
+ 'target': 'board0'}, []), res)
diff --git a/tools/buildman/main.py b/tools/buildman/main.py
index 3cf877e5e68..a948f36d9c0 100755
--- a/tools/buildman/main.py
+++ b/tools/buildman/main.py
@@ -25,6 +25,7 @@ from buildman import cmdline
from buildman import control
from u_boot_pylib import test_util
from u_boot_pylib import tools
+from u_boot_pylib import tout
def run_tests(skip_net_tests, debug, verbose, args):
"""Run the buildman tests
@@ -93,8 +94,12 @@ def run_buildman():
# Build selected commits for selected boards
else:
- bsettings.setup(args.config_file)
- ret_code = control.do_buildman(args)
+ try:
+ tout.init(tout.INFO if args.verbose else tout.WARNING)
+ bsettings.setup(args.config_file)
+ ret_code = control.do_buildman(args)
+ finally:
+ tout.uninit()
return ret_code
diff --git a/tools/buildman/test.py b/tools/buildman/test.py
index 15801f6097f..385a34e5254 100644
--- a/tools/buildman/test.py
+++ b/tools/buildman/test.py
@@ -46,6 +46,16 @@ main: /usr/sbin
wrapper = ccache
'''
+settings_data_homedir = '''
+# Buildman settings file
+
+[toolchain]
+main = ~/mypath
+
+[toolchain-prefix]
+x86 = ~/mypath-x86-
+'''
+
migration = '''===================== WARNING ======================
This board does not use CONFIG_DM. CONFIG_DM will be
compulsory starting with the v2020.01 release.
@@ -1030,6 +1040,46 @@ class TestBuild(unittest.TestCase):
finally:
os.environ['PATH'] = old_path
+ def testHomedir(self):
+ """Test using ~ in a toolchain or toolchain-prefix section"""
+ # Add some test settings
+ bsettings.setup(None)
+ bsettings.add_file(settings_data_homedir)
+
+ # Set up the toolchains
+ home = os.path.expanduser('~')
+ toolchains = toolchain.Toolchains()
+ toolchains.GetSettings()
+ self.assertEqual([f'{home}/mypath'], toolchains.paths)
+
+ # Check scanning
+ with test_util.capture_sys_output() as (stdout, _):
+ toolchains.Scan(verbose=True, raise_on_error=False)
+ lines = iter(stdout.getvalue().splitlines() + ['##done'])
+ self.assertEqual('Scanning for tool chains', next(lines))
+ self.assertEqual(f" - scanning prefix '{home}/mypath-x86-'",
+ next(lines))
+ self.assertEqual(
+ f"Error: No tool chain found for prefix '{home}/mypath-x86-gcc'",
+ next(lines))
+ self.assertEqual(f" - scanning path '{home}/mypath'", next(lines))
+ self.assertEqual(f" - looking in '{home}/mypath/.'", next(lines))
+ self.assertEqual(f" - looking in '{home}/mypath/bin'", next(lines))
+ self.assertEqual(f" - looking in '{home}/mypath/usr/bin'",
+ next(lines))
+ self.assertEqual('##done', next(lines))
+
+ # Check adding a toolchain
+ with test_util.capture_sys_output() as (stdout, _):
+ toolchains.Add('~/aarch64-linux-gcc', test=True, verbose=True)
+ lines = iter(stdout.getvalue().splitlines() + ['##done'])
+ self.assertEqual('Tool chain test: BAD', next(lines))
+ self.assertEqual(f'Command: {home}/aarch64-linux-gcc --version',
+ next(lines))
+ self.assertEqual('', next(lines))
+ self.assertEqual('', next(lines))
+ self.assertEqual('##done', next(lines))
+
if __name__ == "__main__":
unittest.main()
diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py
index 0c8a4fa16eb..958f36f9f61 100644
--- a/tools/buildman/toolchain.py
+++ b/tools/buildman/toolchain.py
@@ -65,12 +65,13 @@ class Toolchain:
"""Create a new toolchain object.
Args:
- fname: Filename of the gcc component
+ fname: Filename of the gcc component, possibly with ~ or $HOME in it
test: True to run the toolchain to test it
verbose: True to print out the information
priority: Priority to use for this toolchain, or PRIORITY_CALC to
calculate it
"""
+ fname = os.path.expanduser(fname)
self.gcc = fname
self.path = os.path.dirname(fname)
self.override_toolchain = override_toolchain
@@ -109,7 +110,7 @@ class Toolchain:
self.priority))
else:
print('BAD')
- print('Command: ', cmd)
+ print(f"Command: {' '.join(cmd)}")
print(result.stdout)
print(result.stderr)
else:
@@ -296,10 +297,11 @@ class Toolchains:
paths = []
for name, value in toolchains:
+ fname = os.path.expanduser(value)
if '*' in value:
- paths += glob.glob(value)
+ paths += glob.glob(fname)
else:
- paths.append(value)
+ paths.append(fname)
return paths
def GetSettings(self, show_warning=True):
@@ -327,16 +329,17 @@ class Toolchains:
toolchain = Toolchain(fname, test, verbose, priority, arch,
self.override_toolchain)
add_it = toolchain.ok
- if toolchain.arch in self.toolchains:
- add_it = (toolchain.priority <
- self.toolchains[toolchain.arch].priority)
if add_it:
- self.toolchains[toolchain.arch] = toolchain
- elif verbose:
- print(("Toolchain '%s' at priority %d will be ignored because "
- "another toolchain for arch '%s' has priority %d" %
- (toolchain.gcc, toolchain.priority, toolchain.arch,
- self.toolchains[toolchain.arch].priority)))
+ if toolchain.arch in self.toolchains:
+ add_it = (toolchain.priority <
+ self.toolchains[toolchain.arch].priority)
+ if add_it:
+ self.toolchains[toolchain.arch] = toolchain
+ elif verbose:
+ print(("Toolchain '%s' at priority %d will be ignored because "
+ "another toolchain for arch '%s' has priority %d" %
+ (toolchain.gcc, toolchain.priority, toolchain.arch,
+ self.toolchains[toolchain.arch].priority)))
def ScanPath(self, path, verbose):
"""Scan a path for a valid toolchain
@@ -372,7 +375,7 @@ class Toolchains:
pathname_list.append(pathname)
return pathname_list
- def Scan(self, verbose):
+ def Scan(self, verbose, raise_on_error=True):
"""Scan for available toolchains and select the best for each arch.
We look for all the toolchains we can file, figure out the
@@ -384,11 +387,12 @@ class Toolchains:
"""
if verbose: print('Scanning for tool chains')
for name, value in self.prefixes:
- if verbose: print(" - scanning prefix '%s'" % value)
- if os.path.exists(value):
- self.Add(value, True, verbose, PRIORITY_FULL_PREFIX, name)
+ fname = os.path.expanduser(value)
+ if verbose: print(" - scanning prefix '%s'" % fname)
+ if os.path.exists(fname):
+ self.Add(fname, True, verbose, PRIORITY_FULL_PREFIX, name)
continue
- fname = value + 'gcc'
+ fname += 'gcc'
if os.path.exists(fname):
self.Add(fname, True, verbose, PRIORITY_PREFIX_GCC, name)
continue
@@ -396,8 +400,11 @@ class Toolchains:
for f in fname_list:
self.Add(f, True, verbose, PRIORITY_PREFIX_GCC_PATH, name)
if not fname_list:
- raise ValueError("No tool chain found for prefix '%s'" %
- value)
+ msg = f"No tool chain found for prefix '{fname}'"
+ if raise_on_error:
+ raise ValueError(msg)
+ else:
+ print(f'Error: {msg}')
for path in self.paths:
if verbose: print(" - scanning path '%s'" % path)
fnames = self.ScanPath(path, verbose)
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
index 967ac89fbde..d2848ab85f3 100644
--- a/tools/docker/Dockerfile
+++ b/tools/docker/Dockerfile
@@ -2,37 +2,62 @@
# This Dockerfile is used to build an image containing basic stuff to be used
# to build U-Boot and run our test suites.
-FROM ubuntu:jammy-20240808
+FROM ubuntu:jammy-20240911.1
LABEL org.opencontainers.image.authors="Tom Rini <trini@konsulko.com>"
LABEL org.opencontainers.image.description=" This image is for building U-Boot inside a container"
+# Used by docker to set the target platform: valid values are linux/arm64/v8
+# and linux/amd64
+ARG TARGETPLATFORM
+
+# Used by docker to set the build platform: the only valid value is linux/amd64
+ARG BUILDPLATFORM
+
# Make sure apt is happy
ENV DEBIAN_FRONTEND=noninteractive
+# Set architectures to build for (leaving out ARM which is an exception)
+ENV ARCHS="aarch64 arc i386 m68k mips microblaze nios2 powerpc riscv64 riscv32 sh2 x86_64"
+
+# Mirror containing the toolchains
+ENV MIRROR=https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin
+
+# Toolchain version
+ENV TCVER=13.2.0
+
+RUN echo "Building on $BUILDPLATFORM, for target $TARGETPLATFORM"
+
# Add LLVM repository
-RUN apt-get update && apt-get install -y gnupg2 wget xz-utils && rm -rf /var/lib/apt/lists/*
+RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
+ --mount=type=cache,target=/var/lib/apt,sharing=locked \
+ apt-get update && apt-get install -y gnupg2 wget xz-utils
RUN wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
RUN echo deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-17 main | tee /etc/apt/sources.list.d/llvm.list
-# Manually install the kernel.org "Crosstool" based toolchains for gcc-13.2.0
-RUN wget -O - https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/13.2.0/x86_64-gcc-13.2.0-nolibc-aarch64-linux.tar.xz | tar -C /opt -xJ
-RUN wget -O - https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/13.2.0/x86_64-gcc-13.2.0-nolibc-arc-linux.tar.xz | tar -C /opt -xJ
-RUN wget -O - https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/13.2.0/x86_64-gcc-13.2.0-nolibc-arm-linux-gnueabi.tar.xz | tar -C /opt -xJ
-RUN wget -O - https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/13.2.0/x86_64-gcc-13.2.0-nolibc-i386-linux.tar.xz | tar -C /opt -xJ
-RUN wget -O - https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/13.2.0/x86_64-gcc-13.2.0-nolibc-m68k-linux.tar.xz | tar -C /opt -xJ
-RUN wget -O - https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/13.2.0/x86_64-gcc-13.2.0-nolibc-mips-linux.tar.xz | tar -C /opt -xJ
-RUN wget -O - https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/13.2.0/x86_64-gcc-13.2.0-nolibc-microblaze-linux.tar.xz | tar -C /opt -xJ
-RUN wget -O - https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/13.2.0/x86_64-gcc-13.2.0-nolibc-nios2-linux.tar.xz | tar -C /opt -xJ
-RUN wget -O - https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/13.2.0/x86_64-gcc-13.2.0-nolibc-powerpc-linux.tar.xz | tar -C /opt -xJ
-RUN wget -O - https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/13.2.0/x86_64-gcc-13.2.0-nolibc-riscv64-linux.tar.xz | tar -C /opt -xJ
-RUN wget -O - https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/13.2.0/x86_64-gcc-13.2.0-nolibc-riscv32-linux.tar.xz | tar -C /opt -xJ
-RUN wget -O - https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/13.2.0/x86_64-gcc-13.2.0-nolibc-sh2-linux.tar.xz | tar -C /opt -xJ
+# Create a list of URLs to process, then pass them into a 'while read' loop
+RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then HOSTARCH=x86_64; else HOSTARCH=arm64; fi; ( \
+ # Manually install the kernel.org "Crosstool"-based toolchains
+ for arch in $ARCHS; do \
+ echo $MIRROR/$HOSTARCH/$TCVER/${HOSTARCH}-gcc-$TCVER-nolibc-${arch}-linux.tar.xz; \
+ done; \
+ \
+ # Deal with ARM, which has a 'gnueabi' suffix
+ echo $MIRROR/${HOSTARCH}/$TCVER/${HOSTARCH}-gcc-$TCVER-nolibc-arm-linux-gnueabi.tar.xz; \
+ \
+ ) | while read url; do \
+ # Read the URL and unpack it into /opt
+ wget -O - $url | tar -C /opt -xJ; \
+ done
# Manually install other toolchains
-RUN wget -O - https://github.com/foss-xtensa/toolchain/releases/download/2020.07/x86_64-2020.07-xtensa-dc233c-elf.tar.gz | tar -C /opt -xz
+RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \
+ wget -O - https://github.com/foss-xtensa/toolchain/releases/download/2020.07/x86_64-2020.07-xtensa-dc233c-elf.tar.gz | tar -C /opt -xz; \
+ fi
# Update and install things from apt now
-RUN apt-get update && apt-get install -y \
+RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
+ --mount=type=cache,target=/var/lib/apt,sharing=locked \
+ apt-get update && apt-get install -y \
automake \
autopoint \
bc \
@@ -54,17 +79,15 @@ RUN apt-get update && apt-get install -y \
flex \
gawk \
gdisk \
+ gettext \
git \
gnu-efi \
gnutls-dev \
graphviz \
- grub-efi-amd64-bin \
- grub-efi-ia32-bin \
help2man \
iasl \
imagemagick \
iputils-ping \
- libc6-i386 \
libconfuse-dev \
libgit2-dev \
libjson-glib-dev \
@@ -82,7 +105,7 @@ RUN apt-get update && apt-get install -y \
libtool \
libudev-dev \
libusb-1.0-0-dev \
- linux-image-kvm \
+ linux-image-generic \
lzma-alone \
lzop \
mount \
@@ -118,8 +141,7 @@ RUN apt-get update && apt-get install -y \
vboot-utils \
xilinx-bootgen \
xxd \
- zip \
- && rm -rf /var/lib/apt/lists/*
+ zip
# Make kernels readable for libguestfs tools to work correctly
RUN chmod +r /boot/vmlinu*
@@ -127,21 +149,19 @@ RUN chmod +r /boot/vmlinu*
# Build GRUB UEFI targets for ARM & RISC-V, 32-bit and 64-bit
RUN git clone git://git.savannah.gnu.org/grub.git /tmp/grub && \
cd /tmp/grub && \
- git checkout grub-2.06 && \
+ git checkout grub-2.12 && \
git config --global user.name "GitLab CI Runner" && \
git config --global user.email trini@konsulko.com && \
- git cherry-pick 049efdd72eb7baa7b2bf8884391ee7fe650da5a0 && \
- git cherry-pick 403d6540cd608b2706cfa0cb4713f7e4b490ff45 && \
./bootstrap && \
mkdir -p /opt/grub && \
./configure --target=aarch64 --with-platform=efi \
CC=gcc \
- TARGET_CC=/opt/gcc-13.2.0-nolibc/aarch64-linux/bin/aarch64-linux-gcc \
- TARGET_OBJCOPY=/opt/gcc-13.2.0-nolibc/aarch64-linux/bin/aarch64-linux-objcopy \
- TARGET_STRIP=/opt/gcc-13.2.0-nolibc/aarch64-linux/bin/aarch64-linux-strip \
- TARGET_NM=/opt/gcc-13.2.0-nolibc/aarch64-linux/bin/aarch64-linux-nm \
- TARGET_RANLIB=/opt/gcc-13.2.0-nolibc/aarch64-linux/bin/aarch64-linux-ranlib && \
- make && \
+ TARGET_CC=/opt/gcc-${TCVER}-nolibc/aarch64-linux/bin/aarch64-linux-gcc \
+ TARGET_OBJCOPY=/opt/gcc-${TCVER}-nolibc/aarch64-linux/bin/aarch64-linux-objcopy \
+ TARGET_STRIP=/opt/gcc-${TCVER}-nolibc/aarch64-linux/bin/aarch64-linux-strip \
+ TARGET_NM=/opt/gcc-${TCVER}-nolibc/aarch64-linux/bin/aarch64-linux-nm \
+ TARGET_RANLIB=/opt/gcc-${TCVER}-nolibc/aarch64-linux/bin/aarch64-linux-ranlib && \
+ make -j$(nproc) && \
./grub-mkimage -O arm64-efi -o /opt/grub/grubaa64.efi --prefix= -d \
grub-core cat chain configfile echo efinet ext2 fat halt help linux \
lsefisystab loadenv lvm minicmd normal part_msdos part_gpt reboot \
@@ -150,12 +170,12 @@ RUN git clone git://git.savannah.gnu.org/grub.git /tmp/grub && \
make clean && \
./configure --target=arm --with-platform=efi \
CC=gcc \
- TARGET_CC=/opt/gcc-13.2.0-nolibc/arm-linux-gnueabi/bin/arm-linux-gnueabi-gcc \
- TARGET_OBJCOPY=/opt/gcc-13.2.0-nolibc/arm-linux-gnueabi/bin/arm-linux-gnueabi-objcopy \
- TARGET_STRIP=/opt/gcc-13.2.0-nolibc/arm-linux-gnueabi/bin/arm-linux-gnueabi-strip \
- TARGET_NM=/opt/gcc-13.2.0-nolibc/arm-linux-gnueabi/bin/arm-linux-gnueabi-nm \
- TARGET_RANLIB=/opt/gcc-13.2.0-nolibc/arm-linux-gnueabi/bin/arm-linux-gnueabi-ranlib && \
- make && \
+ TARGET_CC=/opt/gcc-${TCVER}-nolibc/arm-linux-gnueabi/bin/arm-linux-gnueabi-gcc \
+ TARGET_OBJCOPY=/opt/gcc-${TCVER}-nolibc/arm-linux-gnueabi/bin/arm-linux-gnueabi-objcopy \
+ TARGET_STRIP=/opt/gcc-${TCVER}-nolibc/arm-linux-gnueabi/bin/arm-linux-gnueabi-strip \
+ TARGET_NM=/opt/gcc-${TCVER}-nolibc/arm-linux-gnueabi/bin/arm-linux-gnueabi-nm \
+ TARGET_RANLIB=/opt/gcc-${TCVER}-nolibc/arm-linux-gnueabi/bin/arm-linux-gnueabi-ranlib && \
+ make -j$(nproc) && \
./grub-mkimage -O arm-efi -o /opt/grub/grubarm.efi --prefix= -d \
grub-core cat chain configfile echo efinet ext2 fat halt help linux \
lsefisystab loadenv lvm minicmd normal part_msdos part_gpt reboot \
@@ -164,17 +184,39 @@ RUN git clone git://git.savannah.gnu.org/grub.git /tmp/grub && \
make clean && \
./configure --target=riscv64 --with-platform=efi \
CC=gcc \
- TARGET_CC=/opt/gcc-13.2.0-nolibc/riscv64-linux/bin/riscv64-linux-gcc \
- TARGET_OBJCOPY=/opt/gcc-13.2.0-nolibc/riscv64-linux/bin/riscv64-linux-objcopy \
- TARGET_STRIP=/opt/gcc-13.2.0-nolibc/riscv64-linux/bin/riscv64-linux-strip \
- TARGET_NM=/opt/gcc-13.2.0-nolibc/riscv64-linux/bin/riscv64-linux-nm \
- TARGET_RANLIB=/opt/gcc-13.2.0-nolibc/riscv64-linux/bin/riscv64-linux-ranlib && \
- make && \
+ TARGET_CC=/opt/gcc-${TCVER}-nolibc/riscv64-linux/bin/riscv64-linux-gcc \
+ TARGET_OBJCOPY=/opt/gcc-${TCVER}-nolibc/riscv64-linux/bin/riscv64-linux-objcopy \
+ TARGET_STRIP=/opt/gcc-${TCVER}-nolibc/riscv64-linux/bin/riscv64-linux-strip \
+ TARGET_NM=/opt/gcc-${TCVER}-nolibc/riscv64-linux/bin/riscv64-linux-nm \
+ TARGET_RANLIB=/opt/gcc-${TCVER}-nolibc/riscv64-linux/bin/riscv64-linux-ranlib && \
+ make -j$(nproc) && \
./grub-mkimage -O riscv64-efi -o /opt/grub/grubriscv64.efi --prefix= -d \
grub-core cat chain configfile echo efinet ext2 fat halt help linux \
lsefisystab loadenv lvm minicmd normal part_msdos part_gpt reboot \
search search_fs_file search_fs_uuid search_label serial sleep test \
true && \
+ make clean && \
+ ./configure --target=i386 --with-platform=efi \
+ CC=gcc \
+ TARGET_CC=/opt/gcc-${TCVER}-nolibc/i386-linux/bin/i386-linux-gcc \
+ TARGET_OBJCOPY=/opt/gcc-${TCVER}-nolibc/i386-linux/bin/i386-linux-objcopy \
+ TARGET_STRIP=/opt/gcc-${TCVER}-nolibc/i386-linux/bin/i386-linux-strip \
+ TARGET_NM=/opt/gcc-${TCVER}-nolibc/i386-linux/bin/i386-linux-nm \
+ TARGET_RANLIB=/opt/gcc-${TCVER}-nolibc/i386-linux/bin/i386-linux-ranlib && \
+ make -j$(nproc) && \
+ ./grub-mkimage -O i386-efi -o /opt/grub/grub_x86.efi --prefix= -d \
+ grub-core normal echo lsefimmap lsefi lsefisystab efinet tftp minicmd && \
+ make clean && \
+ ./configure --target=x86_64 --with-platform=efi \
+ CC=gcc \
+ TARGET_CC=/opt/gcc-${TCVER}-nolibc/x86_64-linux/bin/x86_64-linux-gcc \
+ TARGET_OBJCOPY=/opt/gcc-${TCVER}-nolibc/x86_64-linux/bin/x86_64-linux-objcopy \
+ TARGET_STRIP=/opt/gcc-${TCVER}-nolibc/x86_64-linux/bin/x86_64-linux-strip \
+ TARGET_NM=/opt/gcc-${TCVER}-nolibc/x86_64-linux/bin/x86_64-linux-nm \
+ TARGET_RANLIB=/opt/gcc-${TCVER}-nolibc/x86_64-linux/bin/x86_64-linux-ranlib && \
+ make -j$(nproc) && \
+ ./grub-mkimage -O x86_64-efi -o /opt/grub/grub_x64.efi --prefix= -d \
+ grub-core normal echo lsefimmap lsefi lsefisystab efinet tftp minicmd && \
rm -rf /tmp/grub
RUN git clone https://gitlab.com/qemu-project/qemu.git /tmp/qemu && \
@@ -195,7 +237,7 @@ RUN git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git /tmp/t
cd /tmp/tf-a/ && \
git checkout v2.10.0 && \
cd tools/fiptool && \
- make && \
+ make -j$(nproc) && \
mkdir -p /usr/local/bin && \
cp fiptool /usr/local/bin && \
rm -rf /tmp/tf-a
@@ -276,13 +318,17 @@ RUN virtualenv -p /usr/bin/python3 /tmp/venv && \
rm -rf /tmp/venv /tmp/*-requirements.txt
# Create the buildman config file
-RUN /bin/echo -e "[toolchain]\nroot = /usr" > ~/.buildman
-RUN /bin/echo -e "kernelorg = /opt/gcc-13.2.0-nolibc/*" >> ~/.buildman
-RUN /bin/echo -e "\n[toolchain-prefix]\nxtensa = /opt/2020.07/xtensa-dc233c-elf/bin/xtensa-dc233c-elf-" >> ~/.buildman;
+RUN /bin/echo -e "[toolchain]\nkernelorg = /opt/gcc-${TCVER}-nolibc/*" > ~/.buildman
+RUN /bin/echo -e "root = /usr" >> ~/.buildman
+RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \
+ /bin/echo -e "\n[toolchain-prefix]\nxtensa = /opt/2020.07/xtensa-dc233c-elf/bin/xtensa-dc233c-elf-" >> ~/.buildman; \
+ fi
+RUN if [ "$TARGETPLATFORM" = "linux/arm64" ]; then \
+ /bin/echo -e "\n[toolchain-prefix]\naarch64 = /opt/gcc-${TCVER}-nolibc/aarch64-linux/bin/aarch64-linux-" >> ~/.buildman; \
+ fi
RUN /bin/echo -e "\n[toolchain-alias]\nsh = sh2" >> ~/.buildman
-RUN /bin/echo -e "\nsandbox = x86_64" >> ~/.buildman
RUN /bin/echo -e "\nx86 = i386" >> ~/.buildman;
# Add mkbootimg tool
RUN git clone https://android.googlesource.com/platform/system/tools/mkbootimg /home/uboot/mkbootimg
-ENV PYTHONPATH "${PYTHONPATH}:/home/uboot/mkbootimg"
+ENV PYTHONPATH="${PYTHONPATH}:/home/uboot/mkbootimg"
diff --git a/tools/dtoc/fdt_util.py b/tools/dtoc/fdt_util.py
index f1f70568cfe..d5ecc4207d8 100644
--- a/tools/dtoc/fdt_util.py
+++ b/tools/dtoc/fdt_util.py
@@ -55,7 +55,7 @@ def fdt_cells_to_cpu(val, cells):
out = out << 32 | fdt32_to_cpu(val[1])
return out
-def EnsureCompiled(fname, tmpdir=None, capture_stderr=False):
+def EnsureCompiled(fname, tmpdir=None, capture_stderr=False, indir=None):
"""Compile an fdt .dts source file into a .dtb binary blob if needed.
Args:
@@ -63,6 +63,7 @@ def EnsureCompiled(fname, tmpdir=None, capture_stderr=False):
left alone
tmpdir: Temporary directory for output files, or None to use the
tools-module output directory
+ indir: List of directories where input files can be found
Returns:
Filename of resulting .dtb file
@@ -79,6 +80,8 @@ def EnsureCompiled(fname, tmpdir=None, capture_stderr=False):
dtb_output = tools.get_output_filename('source.dtb')
search_paths = [os.path.join(os.getcwd(), 'include')]
+ if indir is not None:
+ search_paths += indir
root, _ = os.path.splitext(fname)
cc, args = tools.get_target_compile_tool('cc')
args += ['-E', '-P', '-x', 'assembler-with-cpp', '-D__ASSEMBLY__']
diff --git a/tools/image-host.c b/tools/image-host.c
index 5e01b853c50..16389bd4880 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -535,7 +535,7 @@ fit_image_process_cipher(const char *keydir, void *keydest, void *fit,
* size values
* And, if needed, write the iv in the FIT file
*/
- if (keydest) {
+ if (keydest || (!keydest && !info.ivname)) {
ret = info.cipher->add_cipher_data(&info, keydest, fit, node_noffset);
if (ret) {
fprintf(stderr,
diff --git a/tools/imx8image.c b/tools/imx8image.c
index 7a060811c7e..15510d3e712 100644
--- a/tools/imx8image.c
+++ b/tools/imx8image.c
@@ -734,7 +734,7 @@ static int get_container_image_start_pos(image_t *image_stack, uint32_t align)
fclose(fd);
if (header.tag != IVT_HEADER_TAG_B0) {
- fprintf(stderr, "header tag mismatched \n");
+ fprintf(stderr, "header tag mismatched file %s\n", img_sp->filename);
exit(EXIT_FAILURE);
} else {
file_off +=
diff --git a/tools/imx_cntr_image.sh b/tools/imx_cntr_image.sh
index 972b95ccbee..07acd385631 100755
--- a/tools/imx_cntr_image.sh
+++ b/tools/imx_cntr_image.sh
@@ -14,6 +14,10 @@ for f in $blobs; do
continue
fi
+ if [ $f = "spl/u-boot-spl.bin" ]; then
+ continue
+ fi
+
if [ -f $f ]; then
continue
fi
diff --git a/tools/u_boot_pylib/tools.py b/tools/u_boot_pylib/tools.py
index 187725b5015..0499a75526f 100644
--- a/tools/u_boot_pylib/tools.py
+++ b/tools/u_boot_pylib/tools.py
@@ -123,6 +123,22 @@ def set_input_dirs(dirname):
indir = dirname
tout.debug("Using input directories %s" % indir)
+def append_input_dirs(dirname):
+ """Append a list of input directories to the current list of input
+ directories
+
+ Args:
+ dirname: a list of paths to input directories to use for obtaining
+ files needed by binman to place in the image.
+ """
+ global indir
+
+ for dir in dirname:
+ if dirname not in indir:
+ indir.append(dirname)
+
+ tout.debug("Updated input directories %s" % indir)
+
def get_input_filename(fname, allow_missing=False):
"""Return a filename for use as input.