summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2023-10-02 10:55:44 -0400
committerTom Rini <trini@konsulko.com>2023-10-02 10:55:44 -0400
commitac897385bbfa30cfdfb62ccf24acfcd4b274b2ff (patch)
treeae567980737beb24ca24e2ee8cfeaf6eb9e26e3f /tools
parent4459ed60cb1e0562bc5b40405e2b4b9bbf766d57 (diff)
parente29b932aa07fa0226d325b35d96cd4eea0370129 (diff)
downloadu-boot-ac897385bbfa30cfdfb62ccf24acfcd4b274b2ff.tar.gz
u-boot-ac897385bbfa30cfdfb62ccf24acfcd4b274b2ff.tar.bz2
u-boot-ac897385bbfa30cfdfb62ccf24acfcd4b274b2ff.zip
Merge branch 'next'
Signed-off-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile1
-rw-r--r--tools/binman/bintool.py19
-rw-r--r--tools/binman/btool/mkeficapsule.py101
-rw-r--r--tools/binman/entries.rst64
-rw-r--r--tools/binman/etype/efi_capsule.py143
-rw-r--r--tools/binman/ftest.py118
-rw-r--r--tools/binman/test/311_capsule.dts21
-rw-r--r--tools/binman/test/312_capsule_signed.dts23
-rw-r--r--tools/binman/test/313_capsule_version.dts22
-rw-r--r--tools/binman/test/314_capsule_signed_ver.dts24
-rw-r--r--tools/binman/test/315_capsule_oemflags.dts22
-rw-r--r--tools/binman/test/316_capsule_missing_key.dts22
-rw-r--r--tools/binman/test/317_capsule_missing_index.dts20
-rw-r--r--tools/binman/test/318_capsule_missing_guid.dts19
-rw-r--r--tools/buildman/boards.py15
-rw-r--r--tools/buildman/builder.py3
-rw-r--r--tools/buildman/builderthread.py12
-rw-r--r--tools/buildman/control.py3
-rw-r--r--tools/buildman/toolchain.py2
-rw-r--r--tools/default_image.c1
-rw-r--r--tools/docker/Dockerfile65
-rwxr-xr-xtools/expo.py22
-rw-r--r--tools/image-host.c202
-rw-r--r--tools/logos/ti_logo_414x97_32bpp.bmp (renamed from tools/logos/ti.bmp)bin160770 -> 160770 bytes
-rw-r--r--tools/logos/ti_logo_414x97_32bpp.bmp.gz (renamed from tools/logos/ti.gz)bin12285 -> 12285 bytes
-rw-r--r--tools/relocate-rela.c134
-rw-r--r--tools/sfspl.c174
27 files changed, 1064 insertions, 188 deletions
diff --git a/tools/Makefile b/tools/Makefile
index 3d0c4b0dd6..1aa1e36137 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -123,6 +123,7 @@ dumpimage-mkimage-objs := aisimage.o \
pblimage.o \
pbl_crc32.o \
renesas_spkgimage.o \
+ sfspl.o \
vybridimage.o \
stm32image.o \
$(ROCKCHIP_OBS) \
diff --git a/tools/binman/bintool.py b/tools/binman/bintool.py
index 0b0f56dbbb..3c4ad1adbb 100644
--- a/tools/binman/bintool.py
+++ b/tools/binman/bintool.py
@@ -328,7 +328,7 @@ class Bintool:
return result.stdout
@classmethod
- def build_from_git(cls, git_repo, make_target, bintool_path, flags=None):
+ def build_from_git(cls, git_repo, make_targets, bintool_path, flags=None):
"""Build a bintool from a git repo
This clones the repo in a temporary directory, builds it with 'make',
@@ -336,7 +336,8 @@ class Bintool:
Args:
git_repo (str): URL of git repo
- make_target (str): Target to pass to 'make' to build the tool
+ make_targets (list of str): List of targets to pass to 'make' to build
+ the tool
bintool_path (str): Relative path of the tool in the repo, after
build is complete
flags (list of str): Flags or variables to pass to make, or None
@@ -350,12 +351,14 @@ class Bintool:
tmpdir = tempfile.mkdtemp(prefix='binmanf.')
print(f"- clone git repo '{git_repo}' to '{tmpdir}'")
tools.run('git', 'clone', '--depth', '1', git_repo, tmpdir)
- print(f"- build target '{make_target}'")
- cmd = ['make', '-C', tmpdir, '-j', f'{multiprocessing.cpu_count()}',
- make_target]
- if flags:
- cmd += flags
- tools.run(*cmd)
+ for target in make_targets:
+ print(f"- build target '{target}'")
+ cmd = ['make', '-C', tmpdir, '-j', f'{multiprocessing.cpu_count()}',
+ target]
+ if flags:
+ cmd += flags
+ tools.run(*cmd)
+
fname = os.path.join(tmpdir, bintool_path)
if not os.path.exists(fname):
print(f"- File '{fname}' was not produced")
diff --git a/tools/binman/btool/mkeficapsule.py b/tools/binman/btool/mkeficapsule.py
new file mode 100644
index 0000000000..61179747ff
--- /dev/null
+++ b/tools/binman/btool/mkeficapsule.py
@@ -0,0 +1,101 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2023 Linaro Limited
+#
+"""Bintool implementation for mkeficapsule tool
+
+mkeficapsule is a tool used for generating EFI capsules.
+
+The following are the commandline options to be provided
+to the tool
+Usage: mkeficapsule [options] <image blob> <output file>
+Options:
+ -g, --guid <guid string> guid for image blob type
+ -i, --index <index> update image index
+ -I, --instance <instance> update hardware instance
+ -v, --fw-version <version> firmware version
+ -p, --private-key <privkey file> private key file
+ -c, --certificate <cert file> signer's certificate file
+ -m, --monotonic-count <count> monotonic count
+ -d, --dump_sig dump signature (*.p7)
+ -A, --fw-accept firmware accept capsule, requires GUID, no image blob
+ -R, --fw-revert firmware revert capsule, takes no GUID, no image blob
+ -o, --capoemflag Capsule OEM Flag, an integer between 0x0000 and 0xffff
+ -h, --help print a help message
+"""
+
+from binman import bintool
+
+class Bintoolmkeficapsule(bintool.Bintool):
+ """Handles the 'mkeficapsule' tool
+
+ This bintool is used for generating the EFI capsules. The
+ capsule generation parameters can either be specified through
+ commandline, or through a config file.
+ """
+ def __init__(self, name):
+ super().__init__(name, 'mkeficapsule tool for generating capsules')
+
+ def generate_capsule(self, image_index, image_guid, hardware_instance,
+ payload, output_fname, priv_key, pub_key,
+ monotonic_count=0, version=0, oemflags=0):
+ """Generate a capsule through commandline-provided parameters
+
+ Args:
+ image_index (int): Unique number for identifying payload image
+ image_guid (str): GUID used for identifying the image
+ hardware_instance (int): Optional unique hardware instance of
+ a device in the system. 0 if not being used
+ payload (str): Path to the input payload image
+ output_fname (str): Path to the output capsule file
+ priv_key (str): Path to the private key
+ pub_key(str): Path to the public key
+ monotonic_count (int): Count used when signing an image
+ version (int): Image version (Optional)
+ oemflags (int): Optional 16 bit OEM flags
+
+ Returns:
+ str: Tool output
+ """
+ args = [
+ f'--index={image_index}',
+ f'--guid={image_guid}',
+ f'--instance={hardware_instance}'
+ ]
+
+ if version:
+ args += [f'--fw-version={version}']
+ if oemflags:
+ args += [f'--capoemflag={oemflags}']
+ if priv_key and pub_key:
+ args += [
+ f'--monotonic-count={monotonic_count}',
+ f'--private-key={priv_key}',
+ f'--certificate={pub_key}'
+ ]
+
+ args += [
+ payload,
+ output_fname
+ ]
+
+ return self.run_cmd(*args)
+
+ def fetch(self, method):
+ """Fetch handler for mkeficapsule
+
+ This builds the tool from source
+
+ Returns:
+ tuple:
+ str: Filename of fetched file to copy to a suitable directory
+ str: Name of temp directory to remove, or None
+ """
+ if method != bintool.FETCH_BUILD:
+ return None
+
+ cmd = ['tools-only_defconfig', 'tools']
+ result = self.build_from_git(
+ 'https://source.denx.de/u-boot/u-boot.git',
+ cmd,
+ 'tools/mkeficapsule')
+ return result
diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
index e7dfe6b2a3..801bd94674 100644
--- a/tools/binman/entries.rst
+++ b/tools/binman/entries.rst
@@ -468,6 +468,70 @@ updating the EC on startup via software sync.
+.. _etype_efi_capsule:
+
+Entry: capsule: Entry for generating EFI Capsule files
+------------------------------------------------------
+
+The parameters needed for generation of the capsules can be provided
+as properties in the entry.
+
+Properties / Entry arguments:
+ - image-index: Unique number for identifying corresponding
+ payload image. Number between 1 and descriptor count, i.e.
+ the total number of firmware images that can be updated. Mandatory
+ property.
+ - image-guid: Image GUID which will be used for identifying the
+ updatable image on the board. Mandatory property.
+ - hardware-instance: Optional number for identifying unique
+ hardware instance of a device in the system. Default value of 0
+ for images where value is not to be used.
+ - fw-version: Value of image version that can be put on the capsule
+ through the Firmware Management Protocol(FMP) header.
+ - monotonic-count: Count used when signing an image.
+ - private-key: Path to PEM formatted .key private key file. Mandatory
+ property for generating signed capsules.
+ - public-key-cert: Path to PEM formatted .crt public key certificate
+ file. Mandatory property for generating signed capsules.
+ - oem-flags - OEM flags to be passed through capsule header.
+
+ Since this is a subclass of Entry_section, all properties of the parent
+ class also apply here. Except for the properties stated as mandatory, the
+ rest of the properties are optional.
+
+For more details on the description of the capsule format, and the capsule
+update functionality, refer Section 8.5 and Chapter 23 in the `UEFI
+specification`_.
+
+The capsule parameters like image index and image GUID are passed as
+properties in the entry. The payload to be used in the capsule is to be
+provided as a subnode of the capsule entry.
+
+A typical capsule entry node would then look something like this::
+
+ capsule {
+ type = "efi-capsule";
+ image-index = <0x1>;
+ /* Image GUID for testing capsule update */
+ image-guid = SANDBOX_UBOOT_IMAGE_GUID;
+ hardware-instance = <0x0>;
+ private-key = "path/to/the/private/key";
+ public-key-cert = "path/to/the/public-key-cert";
+ oem-flags = <0x8000>;
+
+ u-boot {
+ };
+ };
+
+In the above example, the capsule payload is the U-Boot image. The
+capsule entry would read the contents of the payload and put them
+into the capsule. Any external file can also be specified as the
+payload using the blob-ext subnode.
+
+.. _`UEFI specification`: https://uefi.org/sites/default/files/resources/UEFI_Spec_2_10_Aug29.pdf
+
+
+
.. _etype_encrypted:
Entry: encrypted: Externally built encrypted binary blob
diff --git a/tools/binman/etype/efi_capsule.py b/tools/binman/etype/efi_capsule.py
new file mode 100644
index 0000000000..006eb630ad
--- /dev/null
+++ b/tools/binman/etype/efi_capsule.py
@@ -0,0 +1,143 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2023 Linaro Limited
+#
+# Entry-type module for producing a EFI capsule
+#
+
+import os
+
+from binman.entry import Entry
+from binman.etype.section import Entry_section
+from dtoc import fdt_util
+from u_boot_pylib import tools
+
+class Entry_efi_capsule(Entry_section):
+ """Generate EFI capsules
+
+ The parameters needed for generation of the capsules can
+ be provided as properties in the entry.
+
+ Properties / Entry arguments:
+ - image-index: Unique number for identifying corresponding
+ payload image. Number between 1 and descriptor count, i.e.
+ the total number of firmware images that can be updated. Mandatory
+ property.
+ - image-guid: Image GUID which will be used for identifying the
+ updatable image on the board. Mandatory property.
+ - hardware-instance: Optional number for identifying unique
+ hardware instance of a device in the system. Default value of 0
+ for images where value is not to be used.
+ - fw-version: Value of image version that can be put on the capsule
+ through the Firmware Management Protocol(FMP) header.
+ - monotonic-count: Count used when signing an image.
+ - private-key: Path to PEM formatted .key private key file. Mandatory
+ property for generating signed capsules.
+ - public-key-cert: Path to PEM formatted .crt public key certificate
+ file. Mandatory property for generating signed capsules.
+ - oem-flags - OEM flags to be passed through capsule header.
+
+ Since this is a subclass of Entry_section, all properties of the parent
+ class also apply here. Except for the properties stated as mandatory, the
+ rest of the properties are optional.
+
+ For more details on the description of the capsule format, and the capsule
+ update functionality, refer Section 8.5 and Chapter 23 in the `UEFI
+ specification`_.
+
+ The capsule parameters like image index and image GUID are passed as
+ properties in the entry. The payload to be used in the capsule is to be
+ provided as a subnode of the capsule entry.
+
+ A typical capsule entry node would then look something like this
+
+ capsule {
+ type = "efi-capsule";
+ image-index = <0x1>;
+ /* Image GUID for testing capsule update */
+ image-guid = SANDBOX_UBOOT_IMAGE_GUID;
+ hardware-instance = <0x0>;
+ private-key = "path/to/the/private/key";
+ public-key-cert = "path/to/the/public-key-cert";
+ oem-flags = <0x8000>;
+
+ u-boot {
+ };
+ };
+
+ In the above example, the capsule payload is the U-Boot image. The
+ capsule entry would read the contents of the payload and put them
+ into the capsule. Any external file can also be specified as the
+ payload using the blob-ext subnode.
+
+ .. _`UEFI specification`: https://uefi.org/sites/default/files/resources/UEFI_Spec_2_10_Aug29.pdf
+ """
+ def __init__(self, section, etype, node):
+ super().__init__(section, etype, node)
+ self.required_props = ['image-index', 'image-guid']
+ self.image_index = 0
+ self.image_guid = ''
+ self.hardware_instance = 0
+ self.monotonic_count = 0
+ self.fw_version = 0
+ self.oem_flags = 0
+ self.private_key = ''
+ self.public_key_cert = ''
+ self.auth = 0
+
+ def ReadNode(self):
+ super().ReadNode()
+
+ self.image_index = fdt_util.GetInt(self._node, 'image-index')
+ self.image_guid = fdt_util.GetString(self._node, 'image-guid')
+ self.fw_version = fdt_util.GetInt(self._node, 'fw-version')
+ self.hardware_instance = fdt_util.GetInt(self._node, 'hardware-instance')
+ self.monotonic_count = fdt_util.GetInt(self._node, 'monotonic-count')
+ self.oem_flags = fdt_util.GetInt(self._node, 'oem-flags')
+
+ self.private_key = fdt_util.GetString(self._node, 'private-key')
+ self.public_key_cert = fdt_util.GetString(self._node, 'public-key-cert')
+ if ((self.private_key and not self.public_key_cert) or (self.public_key_cert and not self.private_key)):
+ self.Raise('Both private key and public key certificate need to be provided')
+ elif not (self.private_key and self.public_key_cert):
+ self.auth = 0
+ else:
+ self.auth = 1
+
+ def BuildSectionData(self, required):
+ def get_binman_test_guid(type_str):
+ TYPE_TO_GUID = {
+ 'binman-test' : '09d7cf52-0720-4710-91d1-08469b7fe9c8'
+ }
+ return TYPE_TO_GUID[type_str]
+
+ private_key = ''
+ public_key_cert = ''
+ if self.auth:
+ if not os.path.isabs(self.private_key):
+ private_key = tools.get_input_filename(self.private_key)
+ if not os.path.isabs(self.public_key_cert):
+ public_key_cert = tools.get_input_filename(self.public_key_cert)
+ data, payload, uniq = self.collect_contents_to_file(
+ self._entries.values(), 'capsule_in')
+ outfile = self._filename if self._filename else 'capsule.%s' % uniq
+ capsule_fname = tools.get_output_filename(outfile)
+ guid = self.image_guid
+ if self.image_guid == "binman-test":
+ guid = get_binman_test_guid('binman-test')
+
+ ret = self.mkeficapsule.generate_capsule(self.image_index,
+ guid,
+ self.hardware_instance,
+ payload,
+ capsule_fname,
+ private_key,
+ public_key_cert,
+ self.monotonic_count,
+ self.fw_version,
+ self.oem_flags)
+ if ret is not None:
+ os.remove(payload)
+ return tools.read_file(capsule_fname)
+
+ def AddBintools(self, btools):
+ self.mkeficapsule = self.AddBintool(btools, 'mkeficapsule')
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 1293e9dbf4..8e419645a6 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -48,6 +48,7 @@ U_BOOT_VPL_DATA = b'vpl76543210fedcbazywxyz_'
BLOB_DATA = b'89'
ME_DATA = b'0abcd'
VGA_DATA = b'vga'
+EFI_CAPSULE_DATA = b'efi'
U_BOOT_DTB_DATA = b'udtb'
U_BOOT_SPL_DTB_DATA = b'spldtb'
U_BOOT_TPL_DTB_DATA = b'tpldtb'
@@ -119,6 +120,11 @@ COMP_BINTOOLS = ['bzip2', 'gzip', 'lz4', 'lzma_alone', 'lzop', 'xz', 'zstd']
TEE_ADDR = 0x5678
+# Firmware Management Protocol(FMP) GUID
+FW_MGMT_GUID = 'edd5cb6d2de8444cbda17194199ad92a'
+# Image GUID specified in the DTS
+CAPSULE_IMAGE_GUID = '52cfd7092007104791d108469b7fe9c8'
+
class TestFunctional(unittest.TestCase):
"""Functional tests for binman
@@ -215,6 +221,7 @@ class TestFunctional(unittest.TestCase):
TestFunctional._MakeInputFile('scp.bin', SCP_DATA)
TestFunctional._MakeInputFile('rockchip-tpl.bin', ROCKCHIP_TPL_DATA)
TestFunctional._MakeInputFile('ti_unsecure.bin', TI_UNSECURE_DATA)
+ TestFunctional._MakeInputFile('capsule_input.bin', EFI_CAPSULE_DATA)
# Add a few .dtb files for testing
TestFunctional._MakeInputFile('%s/test-fdt1.dtb' % TEST_FDT_SUBDIR,
@@ -7216,5 +7223,116 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
self.assertRegex(err,
"Image 'image'.*missing bintools.*: bootgen")
+ def _CheckCapsule(self, data, signed_capsule=False, version_check=False,
+ capoemflags=False):
+ fmp_signature = "4d535331" # 'M', 'S', 'S', '1'
+ fmp_size = "10"
+ fmp_fw_version = "02"
+ oemflag = "0080"
+
+ payload_data = EFI_CAPSULE_DATA
+
+ # TODO - Currently, these offsets for capsule fields are hardcoded.
+ # There are plans to add support to the mkeficapsule tool to dump
+ # the capsule contents which can then be used for capsule
+ # verification.
+
+ # Firmware Management Protocol(FMP) GUID - offset(0 - 32)
+ self.assertEqual(FW_MGMT_GUID, data.hex()[:32])
+ # Image GUID - offset(96 - 128)
+ self.assertEqual(CAPSULE_IMAGE_GUID, data.hex()[96:128])
+
+ if capoemflags:
+ # OEM Flags - offset(40 - 44)
+ self.assertEqual(oemflag, data.hex()[40:44])
+ if signed_capsule and version_check:
+ # FMP header signature - offset(4770 - 4778)
+ self.assertEqual(fmp_signature, data.hex()[4770:4778])
+ # FMP header size - offset(4778 - 4780)
+ self.assertEqual(fmp_size, data.hex()[4778:4780])
+ # firmware version - offset(4786 - 4788)
+ self.assertEqual(fmp_fw_version, data.hex()[4786:4788])
+ # payload offset signed capsule(4802 - 4808)
+ self.assertEqual(payload_data.hex(), data.hex()[4802:4808])
+ elif signed_capsule:
+ # payload offset signed capsule(4770 - 4776)
+ self.assertEqual(payload_data.hex(), data.hex()[4770:4776])
+ elif version_check:
+ # FMP header signature - offset(184 - 192)
+ self.assertEqual(fmp_signature, data.hex()[184:192])
+ # FMP header size - offset(192 - 194)
+ self.assertEqual(fmp_size, data.hex()[192:194])
+ # firmware version - offset(200 - 202)
+ self.assertEqual(fmp_fw_version, data.hex()[200:202])
+ # payload offset for non-signed capsule with version header(216 - 222)
+ self.assertEqual(payload_data.hex(), data.hex()[216:222])
+ else:
+ # payload offset for non-signed capsule with no version header(184 - 190)
+ self.assertEqual(payload_data.hex(), data.hex()[184:190])
+
+ def testCapsuleGen(self):
+ """Test generation of EFI capsule"""
+ data = self._DoReadFile('311_capsule.dts')
+
+ self._CheckCapsule(data)
+
+ def testSignedCapsuleGen(self):
+ """Test generation of EFI capsule"""
+ data = tools.read_file(self.TestFile("key.key"))
+ self._MakeInputFile("key.key", data)
+ data = tools.read_file(self.TestFile("key.pem"))
+ self._MakeInputFile("key.crt", data)
+
+ data = self._DoReadFile('312_capsule_signed.dts')
+
+ self._CheckCapsule(data, signed_capsule=True)
+
+ def testCapsuleGenVersionSupport(self):
+ """Test generation of EFI capsule with version support"""
+ data = self._DoReadFile('313_capsule_version.dts')
+
+ self._CheckCapsule(data, version_check=True)
+
+ def testCapsuleGenSignedVer(self):
+ """Test generation of signed EFI capsule with version information"""
+ data = tools.read_file(self.TestFile("key.key"))
+ self._MakeInputFile("key.key", data)
+ data = tools.read_file(self.TestFile("key.pem"))
+ self._MakeInputFile("key.crt", data)
+
+ data = self._DoReadFile('314_capsule_signed_ver.dts')
+
+ self._CheckCapsule(data, signed_capsule=True, version_check=True)
+
+ def testCapsuleGenCapOemFlags(self):
+ """Test generation of EFI capsule with OEM Flags set"""
+ data = self._DoReadFile('315_capsule_oemflags.dts')
+
+ self._CheckCapsule(data, capoemflags=True)
+
+ def testCapsuleGenKeyMissing(self):
+ """Test that binman errors out on missing key"""
+ with self.assertRaises(ValueError) as e:
+ self._DoReadFile('316_capsule_missing_key.dts')
+
+ self.assertIn("Both private key and public key certificate need to be provided",
+ str(e.exception))
+
+ def testCapsuleGenIndexMissing(self):
+ """Test that binman errors out on missing image index"""
+ with self.assertRaises(ValueError) as e:
+ self._DoReadFile('317_capsule_missing_index.dts')
+
+ self.assertIn("entry is missing properties: image-index",
+ str(e.exception))
+
+ def testCapsuleGenGuidMissing(self):
+ """Test that binman errors out on missing image GUID"""
+ with self.assertRaises(ValueError) as e:
+ self._DoReadFile('318_capsule_missing_guid.dts')
+
+ self.assertIn("entry is missing properties: image-guid",
+ str(e.exception))
+
if __name__ == "__main__":
unittest.main()
diff --git a/tools/binman/test/311_capsule.dts b/tools/binman/test/311_capsule.dts
new file mode 100644
index 0000000000..8eb4250b14
--- /dev/null
+++ b/tools/binman/test/311_capsule.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ efi-capsule {
+ image-index = <0x1>;
+ /* Image GUID for testing capsule update */
+ image-guid = "binman-test";
+ hardware-instance = <0x0>;
+
+ blob {
+ filename = "capsule_input.bin";
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/312_capsule_signed.dts b/tools/binman/test/312_capsule_signed.dts
new file mode 100644
index 0000000000..d1c76e269c
--- /dev/null
+++ b/tools/binman/test/312_capsule_signed.dts
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ efi-capsule {
+ image-index = <0x1>;
+ /* Image GUID for testing capsule update */
+ image-guid = "binman-test";
+ hardware-instance = <0x0>;
+ private-key = "key.key";
+ public-key-cert = "key.crt";
+
+ blob {
+ filename = "capsule_input.bin";
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/313_capsule_version.dts b/tools/binman/test/313_capsule_version.dts
new file mode 100644
index 0000000000..bafef3609e
--- /dev/null
+++ b/tools/binman/test/313_capsule_version.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ efi-capsule {
+ image-index = <0x1>;
+ fw-version = <0x2>;
+ /* Image GUID for testing capsule update */
+ image-guid = "binman-test";
+ hardware-instance = <0x0>;
+
+ blob {
+ filename = "capsule_input.bin";
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/314_capsule_signed_ver.dts b/tools/binman/test/314_capsule_signed_ver.dts
new file mode 100644
index 0000000000..85c784bba4
--- /dev/null
+++ b/tools/binman/test/314_capsule_signed_ver.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ efi-capsule {
+ image-index = <0x1>;
+ fw-version = <0x2>;
+ /* Image GUID for testing capsule update */
+ image-guid = "binman-test";
+ hardware-instance = <0x0>;
+ private-key = "key.key";
+ public-key-cert = "key.crt";
+
+ blob {
+ filename = "capsule_input.bin";
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/315_capsule_oemflags.dts b/tools/binman/test/315_capsule_oemflags.dts
new file mode 100644
index 0000000000..f736e8758f
--- /dev/null
+++ b/tools/binman/test/315_capsule_oemflags.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ efi-capsule {
+ image-index = <0x1>;
+ /* Image GUID for testing capsule update */
+ image-guid = "binman-test";
+ hardware-instance = <0x0>;
+ oem-flags = <0x8000>;
+
+ blob {
+ filename = "capsule_input.bin";
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/316_capsule_missing_key.dts b/tools/binman/test/316_capsule_missing_key.dts
new file mode 100644
index 0000000000..2080b50e3d
--- /dev/null
+++ b/tools/binman/test/316_capsule_missing_key.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ efi-capsule {
+ image-index = <0x1>;
+ /* Image GUID for testing capsule update */
+ image-guid = "binman-test";
+ hardware-instance = <0x0>;
+ private-key = "tools/binman/test/key.key";
+
+ blob {
+ filename = "capsule_input.bin";
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/317_capsule_missing_index.dts b/tools/binman/test/317_capsule_missing_index.dts
new file mode 100644
index 0000000000..aadb61f647
--- /dev/null
+++ b/tools/binman/test/317_capsule_missing_index.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ efi-capsule {
+ /* Image GUID for testing capsule update */
+ image-guid = "binman-test";
+ hardware-instance = <0x0>;
+
+ blob {
+ filename = "capsule_input.bin";
+ };
+ };
+ };
+};
diff --git a/tools/binman/test/318_capsule_missing_guid.dts b/tools/binman/test/318_capsule_missing_guid.dts
new file mode 100644
index 0000000000..d76afba853
--- /dev/null
+++ b/tools/binman/test/318_capsule_missing_guid.dts
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ efi-capsule {
+ image-index = <0x1>;
+ hardware-instance = <0x0>;
+
+ blob {
+ filename = "capsule_input.bin";
+ };
+ };
+ };
+};
diff --git a/tools/buildman/boards.py b/tools/buildman/boards.py
index eef3f19f7a..341a5056df 100644
--- a/tools/buildman/boards.py
+++ b/tools/buildman/boards.py
@@ -19,6 +19,7 @@ import time
from buildman import board
from buildman import kconfiglib
+from u_boot_pylib.terminal import print_clear, tprint
### constant variables ###
OUTPUT_FILE = 'boards.cfg'
@@ -863,11 +864,19 @@ class Boards:
Returns:
bool: True if all is well, False if there were warnings
"""
- if not force and output_is_new(output, CONFIG_DIR, '.'):
+ if not force:
if not quiet:
- print(f'{output} is up to date. Nothing to do.')
- return True
+ tprint('\rChecking for Kconfig changes...', newline=False)
+ is_new = output_is_new(output, CONFIG_DIR, '.')
+ print_clear()
+ if is_new:
+ if not quiet:
+ print(f'{output} is up to date. Nothing to do.')
+ return True
+ if not quiet:
+ tprint('\rGenerating board list...', newline=False)
params_list, warnings = self.build_board_list(CONFIG_DIR, '.', jobs)
+ print_clear()
for warn in warnings:
print(warn, file=sys.stderr)
self.format_and_output(params_list, output)
diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py
index ecbd368c47..5305477c5b 100644
--- a/tools/buildman/builder.py
+++ b/tools/buildman/builder.py
@@ -328,7 +328,7 @@ class Builder:
self._build_period_us = None
self._complete_delay = None
self._next_delay_update = datetime.now()
- self._start_time = datetime.now()
+ self._start_time = None
self._step = step
self._error_lines = 0
self.no_subdirs = no_subdirs
@@ -1778,6 +1778,7 @@ class Builder:
self._prepare_output_space()
if not self._ide:
tprint('\rStarting build...', newline=False)
+ self._start_time = datetime.now()
self.setup_build(board_selected, commits)
self.process_result(None)
self.thread_exceptions = []
diff --git a/tools/buildman/builderthread.py b/tools/buildman/builderthread.py
index 25f460c207..6a61f64da1 100644
--- a/tools/buildman/builderthread.py
+++ b/tools/buildman/builderthread.py
@@ -23,6 +23,9 @@ from u_boot_pylib import command
RETURN_CODE_RETRY = -1
BASE_ELF_FILENAMES = ['u-boot', 'spl/u-boot-spl', 'tpl/u-boot-tpl']
+# Common extensions for images
+COMMON_EXTS = ['.bin', '.rom', '.itb', '.img']
+
def mkdir(dirname, parents=False):
"""Make a directory if it doesn't already exist.
@@ -636,10 +639,11 @@ class BuilderThread(threading.Thread):
# Now write the actual build output
if keep_outputs:
- copy_files(
- result.out_dir, build_dir, '',
- ['u-boot*', '*.bin', '*.map', '*.img', 'MLO', 'SPL',
- 'include/autoconf.mk', 'spl/u-boot-spl*'])
+ to_copy = ['u-boot*', '*.map', 'MLO', 'SPL',
+ 'include/autoconf.mk', 'spl/u-boot-spl*',
+ 'tpl/u-boot-tpl*', 'vpl/u-boot-vpl*']
+ to_copy += [f'*{ext}' for ext in COMMON_EXTS]
+ copy_files(result.out_dir, build_dir, '', to_copy)
def _send_result(self, result):
"""Send a result to the builder for processing
diff --git a/tools/buildman/control.py b/tools/buildman/control.py
index f2ffb7f5b4..8f6850c521 100644
--- a/tools/buildman/control.py
+++ b/tools/buildman/control.py
@@ -621,7 +621,8 @@ def do_buildman(args, toolchains=None, make_func=None, brds=None,
if not brds:
brds = get_boards_obj(output_dir, args.regen_board_list,
args.maintainer_check, args.full_check,
- args.threads, args.verbose)
+ args.threads, args.verbose and
+ not args.print_arch and not args.print_prefix)
if isinstance(brds, int):
return brds
diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py
index b05001194e..79c7c11a11 100644
--- a/tools/buildman/toolchain.py
+++ b/tools/buildman/toolchain.py
@@ -499,7 +499,7 @@ class Toolchains:
if arch == 'aarch64':
arch = 'arm64'
base = 'https://www.kernel.org/pub/tools/crosstool/files/bin'
- versions = ['13.1.0', '12.2.0']
+ versions = ['13.2.0', '12.2.0']
links = []
for version in versions:
url = '%s/%s/%s/' % (base, arch, version)
diff --git a/tools/default_image.c b/tools/default_image.c
index 0e49ab3301..04bc85bf93 100644
--- a/tools/default_image.c
+++ b/tools/default_image.c
@@ -15,7 +15,6 @@
#include "imagetool.h"
#include "mkimage.h"
-#include <u-boot/crc.h>
#include <image.h>
#include <tee/optee.h>
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
index ff16829887..c4a2596b48 100644
--- a/tools/docker/Dockerfile
+++ b/tools/docker/Dockerfile
@@ -2,7 +2,7 @@
# 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-20230624
+FROM ubuntu:jammy-20230804
MAINTAINER Tom Rini <trini@konsulko.com>
LABEL Description=" This image is for building U-Boot inside a container"
@@ -14,19 +14,19 @@ RUN apt-get update && apt-get install -y gnupg2 wget xz-utils && rm -rf /var/lib
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-16 main | tee /etc/apt/sources.list.d/llvm.list
-# Manually install the kernel.org "Crosstool" based toolchains for gcc-13.1.0
-RUN wget -O - https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/13.1.0/x86_64-gcc-13.1.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.1.0/x86_64-gcc-13.1.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.1.0/x86_64-gcc-13.1.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.1.0/x86_64-gcc-13.1.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.1.0/x86_64-gcc-13.1.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.1.0/x86_64-gcc-13.1.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.1.0/x86_64-gcc-13.1.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.1.0/x86_64-gcc-13.1.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.1.0/x86_64-gcc-13.1.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.1.0/x86_64-gcc-13.1.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.1.0/x86_64-gcc-13.1.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.1.0/x86_64-gcc-13.1.0-nolibc-sh2-linux.tar.xz | tar -C /opt -xJ
+# 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
# 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
@@ -39,10 +39,10 @@ RUN apt-get update && apt-get install -y \
binutils-dev \
bison \
build-essential \
+ cgpt \
clang-16 \
coreutils \
cpio \
- cppcheck \
curl \
device-tree-compiler \
dosfstools \
@@ -104,7 +104,6 @@ RUN apt-get update && apt-get install -y \
python3-virtualenv \
rpm2cpio \
sbsigntool \
- sloccount \
socat \
softhsm2 \
sparse \
@@ -115,6 +114,8 @@ RUN apt-get update && apt-get install -y \
util-linux \
uuid-dev \
virtualenv \
+ vboot-kernel-utils \
+ vboot-utils \
xxd \
zip \
&& rm -rf /var/lib/apt/lists/*
@@ -134,11 +135,11 @@ RUN git clone git://git.savannah.gnu.org/grub.git /tmp/grub && \
mkdir -p /opt/grub && \
./configure --target=aarch64 --with-platform=efi \
CC=gcc \
- TARGET_CC=/opt/gcc-13.1.0-nolibc/aarch64-linux/bin/aarch64-linux-gcc \
- TARGET_OBJCOPY=/opt/gcc-13.1.0-nolibc/aarch64-linux/bin/aarch64-linux-objcopy \
- TARGET_STRIP=/opt/gcc-13.1.0-nolibc/aarch64-linux/bin/aarch64-linux-strip \
- TARGET_NM=/opt/gcc-13.1.0-nolibc/aarch64-linux/bin/aarch64-linux-nm \
- TARGET_RANLIB=/opt/gcc-13.1.0-nolibc/aarch64-linux/bin/aarch64-linux-ranlib && \
+ 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 && \
./grub-mkimage -O arm64-efi -o /opt/grub/grubaa64.efi --prefix= -d \
grub-core cat chain configfile echo efinet ext2 fat halt help linux \
@@ -148,11 +149,11 @@ 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.1.0-nolibc/arm-linux-gnueabi/bin/arm-linux-gnueabi-gcc \
- TARGET_OBJCOPY=/opt/gcc-13.1.0-nolibc/arm-linux-gnueabi/bin/arm-linux-gnueabi-objcopy \
- TARGET_STRIP=/opt/gcc-13.1.0-nolibc/arm-linux-gnueabi/bin/arm-linux-gnueabi-strip \
- TARGET_NM=/opt/gcc-13.1.0-nolibc/arm-linux-gnueabi/bin/arm-linux-gnueabi-nm \
- TARGET_RANLIB=/opt/gcc-13.1.0-nolibc/arm-linux-gnueabi/bin/arm-linux-gnueabi-ranlib && \
+ 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 && \
./grub-mkimage -O arm-efi -o /opt/grub/grubarm.efi --prefix= -d \
grub-core cat chain configfile echo efinet ext2 fat halt help linux \
@@ -162,11 +163,11 @@ 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.1.0-nolibc/riscv64-linux/bin/riscv64-linux-gcc \
- TARGET_OBJCOPY=/opt/gcc-13.1.0-nolibc/riscv64-linux/bin/riscv64-linux-objcopy \
- TARGET_STRIP=/opt/gcc-13.1.0-nolibc/riscv64-linux/bin/riscv64-linux-strip \
- TARGET_NM=/opt/gcc-13.1.0-nolibc/riscv64-linux/bin/riscv64-linux-nm \
- TARGET_RANLIB=/opt/gcc-13.1.0-nolibc/riscv64-linux/bin/riscv64-linux-ranlib && \
+ 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 && \
./grub-mkimage -O riscv64-efi -o /opt/grub/grubriscv64.efi --prefix= -d \
grub-core cat chain configfile echo efinet ext2 fat halt help linux \
@@ -246,7 +247,7 @@ RUN virtualenv -p /usr/bin/python3 /tmp/venv && \
# Create the buildman config file
RUN /bin/echo -e "[toolchain]\nroot = /usr" > ~/.buildman
-RUN /bin/echo -e "kernelorg = /opt/gcc-13.1.0-nolibc/*" >> ~/.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 "\n[toolchain-alias]\nsh = sh2" >> ~/.buildman
RUN /bin/echo -e "\nsandbox = x86_64" >> ~/.buildman
diff --git a/tools/expo.py b/tools/expo.py
index c6eb87aec7..ea80c70f04 100755
--- a/tools/expo.py
+++ b/tools/expo.py
@@ -69,7 +69,10 @@ def calc_ids(fname):
def run_expo(args):
"""Run the expo program"""
- ids = calc_ids(args.enum_fname)
+ fname = args.enum_fname or args.layout
+ ids = calc_ids(fname)
+ if not ids:
+ print(f"Warning: No enum ID values found in file '{fname}'")
indata = tools.read_file(args.layout)
@@ -88,10 +91,10 @@ def run_expo(args):
with open('/tmp/asc', 'wb') as outf:
outf.write(data)
- proc = subprocess.run('dtc', input=data, capture_output=True, check=True)
+ proc = subprocess.run('dtc', input=data, capture_output=True)
edtb = proc.stdout
if proc.stderr:
- print(proc.stderr)
+ print(f"Devicetree compiler error:\n{proc.stderr.decode('utf-8')}")
return 1
tools.write_file(args.outfile, edtb)
return 0
@@ -109,11 +112,13 @@ def parse_args(argv):
args is a list of string arguments
"""
parser = argparse.ArgumentParser()
+ parser.add_argument('-D', '--debug', action='store_true',
+ help='Enable full debug traceback')
parser.add_argument('-e', '--enum-fname', type=str,
- help='C file containing enum declaration for expo items')
- parser.add_argument('-l', '--layout', type=str,
- help='Devicetree file source .dts for expo layout')
- parser.add_argument('-o', '--outfile', type=str,
+ help='.dts or C file containing enum declaration for expo items')
+ parser.add_argument('-l', '--layout', type=str, required=True,
+ help='Devicetree file source .dts for expo layout (and perhaps enums)')
+ parser.add_argument('-o', '--outfile', type=str, required=True,
help='Filename to write expo layout dtb')
return parser.parse_args(argv)
@@ -122,6 +127,9 @@ def start_expo():
"""Start the expo program"""
args = parse_args(sys.argv[1:])
+ if not args.debug:
+ sys.tracebacklimit = 0
+
ret_code = run_expo(args)
sys.exit(ret_code)
diff --git a/tools/image-host.c b/tools/image-host.c
index 4a24dee815..ca4950312f 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -38,9 +38,9 @@ static int fit_set_hash_value(void *fit, int noffset, uint8_t *value,
ret = fdt_setprop(fit, noffset, FIT_VALUE_PROP, value, value_len);
if (ret) {
- printf("Can't set hash '%s' property for '%s' node(%s)\n",
- FIT_VALUE_PROP, fit_get_name(fit, noffset, NULL),
- fdt_strerror(ret));
+ fprintf(stderr, "Can't set hash '%s' property for '%s' node(%s)\n",
+ FIT_VALUE_PROP, fit_get_name(fit, noffset, NULL),
+ fdt_strerror(ret));
return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO;
}
@@ -72,21 +72,23 @@ static int fit_image_process_hash(void *fit, const char *image_name,
node_name = fit_get_name(fit, noffset, NULL);
if (fit_image_hash_get_algo(fit, noffset, &algo)) {
- printf("Can't get hash algo property for '%s' hash node in '%s' image node\n",
- node_name, image_name);
+ fprintf(stderr,
+ "Can't get hash algo property for '%s' hash node in '%s' image node\n",
+ node_name, image_name);
return -ENOENT;
}
if (calculate_hash(data, size, algo, value, &value_len)) {
- printf("Unsupported hash algorithm (%s) for '%s' hash node in '%s' image node\n",
- algo, node_name, image_name);
+ fprintf(stderr,
+ "Unsupported hash algorithm (%s) for '%s' hash node in '%s' image node\n",
+ algo, node_name, image_name);
return -EPROTONOSUPPORT;
}
ret = fit_set_hash_value(fit, noffset, value, value_len);
if (ret) {
- printf("Can't set hash value for '%s' hash node in '%s' image node\n",
- node_name, image_name);
+ fprintf(stderr, "Can't set hash value for '%s' hash node in '%s' image node\n",
+ node_name, image_name);
return ret;
}
@@ -170,8 +172,9 @@ static int fit_image_setup_sig(struct image_sign_info *info,
node_name = fit_get_name(fit, noffset, NULL);
if (!algo_name) {
if (fit_image_hash_get_algo(fit, noffset, &algo_name)) {
- printf("Can't get algo property for '%s' signature node in '%s' image node\n",
- node_name, image_name);
+ fprintf(stderr,
+ "Can't get algo property for '%s' signature node in '%s' image node\n",
+ node_name, image_name);
return -1;
}
}
@@ -191,8 +194,9 @@ static int fit_image_setup_sig(struct image_sign_info *info,
info->require_keys = require_keys;
info->engine_id = engine_id;
if (!info->checksum || !info->crypto) {
- printf("Unsupported signature algorithm (%s) for '%s' signature node in '%s' image node\n",
- algo_name, node_name, image_name);
+ fprintf(stderr,
+ "Unsupported signature algorithm (%s) for '%s' signature node in '%s' image node\n",
+ algo_name, node_name, image_name);
return -1;
}
@@ -241,8 +245,8 @@ static int fit_image_process_sig(const char *keydir, const char *keyfile,
region.size = size;
ret = info.crypto->sign(&info, &region, 1, &value, &value_len);
if (ret) {
- printf("Failed to sign '%s' signature node in '%s' image node: %d\n",
- node_name, image_name, ret);
+ fprintf(stderr, "Failed to sign '%s' signature node in '%s' image node: %d\n",
+ node_name, image_name, ret);
/* We allow keys to be missing */
if (ret == -ENOENT)
@@ -255,8 +259,9 @@ static int fit_image_process_sig(const char *keydir, const char *keyfile,
if (ret) {
if (ret == -FDT_ERR_NOSPACE)
return -ENOSPC;
- printf("Can't write signature for '%s' signature node in '%s' conf node: %s\n",
- node_name, image_name, fdt_strerror(ret));
+ fprintf(stderr,
+ "Can't write signature for '%s' signature node in '%s' conf node: %s\n",
+ node_name, image_name, fdt_strerror(ret));
return -1;
}
free(value);
@@ -272,8 +277,9 @@ static int fit_image_process_sig(const char *keydir, const char *keyfile,
if (keydest) {
ret = info.crypto->add_verify_data(&info, keydest);
if (ret < 0) {
- printf("Failed to add verification data for '%s' signature node in '%s' image node\n",
- node_name, image_name);
+ fprintf(stderr,
+ "Failed to add verification data for '%s' signature node in '%s' image node\n",
+ node_name, image_name);
return ret;
}
/* Return the node that was written to */
@@ -293,37 +299,37 @@ static int fit_image_read_data(char *filename, unsigned char *data,
/* Open file */
fd = open(filename, O_RDONLY | O_BINARY);
if (fd < 0) {
- printf("Can't open file %s (err=%d => %s)\n",
- filename, errno, strerror(errno));
+ fprintf(stderr, "Can't open file %s (err=%d => %s)\n",
+ filename, errno, strerror(errno));
return -1;
}
/* Compute file size */
if (fstat(fd, &sbuf) < 0) {
- printf("Can't fstat file %s (err=%d => %s)\n",
- filename, errno, strerror(errno));
+ fprintf(stderr, "Can't fstat file %s (err=%d => %s)\n",
+ filename, errno, strerror(errno));
goto err;
}
/* Check file size */
if (sbuf.st_size != expected_size) {
- printf("File %s don't have the expected size (size=%lld, expected=%d)\n",
- filename, (long long)sbuf.st_size, expected_size);
+ fprintf(stderr, "File %s don't have the expected size (size=%lld, expected=%d)\n",
+ filename, (long long)sbuf.st_size, expected_size);
goto err;
}
/* Read data */
n = read(fd, data, sbuf.st_size);
if (n < 0) {
- printf("Can't read file %s (err=%d => %s)\n",
- filename, errno, strerror(errno));
+ fprintf(stderr, "Can't read file %s (err=%d => %s)\n",
+ filename, errno, strerror(errno));
goto err;
}
/* Check that we have read all the file */
if (n != sbuf.st_size) {
- printf("Can't read all file %s (read %zd bytes, expected %lld)\n",
- filename, n, (long long)sbuf.st_size);
+ fprintf(stderr, "Can't read all file %s (read %zd bytes, expected %lld)\n",
+ filename, n, (long long)sbuf.st_size);
goto err;
}
@@ -341,15 +347,15 @@ static int get_random_data(void *data, int size)
int i, ret;
if (!tmp) {
- printf("%s: pointer data is NULL\n", __func__);
+ fprintf(stderr, "%s: pointer data is NULL\n", __func__);
ret = -1;
goto out;
}
ret = clock_gettime(CLOCK_MONOTONIC, &date);
if (ret) {
- printf("%s: clock_gettime has failed (%s)\n", __func__,
- strerror(errno));
+ fprintf(stderr, "%s: clock_gettime has failed (%s)\n", __func__,
+ strerror(errno));
goto out;
}
@@ -374,8 +380,8 @@ static int fit_image_setup_cipher(struct image_cipher_info *info,
int ret = -1;
if (fit_image_cipher_get_algo(fit, noffset, &algo_name)) {
- printf("Can't get algo name for cipher in image '%s'\n",
- image_name);
+ fprintf(stderr, "Can't get algo name for cipher in image '%s'\n",
+ image_name);
goto out;
}
@@ -384,8 +390,8 @@ static int fit_image_setup_cipher(struct image_cipher_info *info,
/* Read the key name */
info->keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
if (!info->keyname) {
- printf("Can't get key name for cipher in image '%s'\n",
- image_name);
+ fprintf(stderr, "Can't get key name for cipher in image '%s'\n",
+ image_name);
goto out;
}
@@ -403,7 +409,7 @@ static int fit_image_setup_cipher(struct image_cipher_info *info,
info->cipher = image_get_cipher_algo(algo_name);
if (!info->cipher) {
- printf("Can't get algo for cipher '%s'\n", image_name);
+ fprintf(stderr, "Can't get algo for cipher '%s'\n", image_name);
goto out;
}
@@ -412,7 +418,7 @@ static int fit_image_setup_cipher(struct image_cipher_info *info,
info->keydir, info->keyname, ".bin");
info->key = malloc(info->cipher->key_len);
if (!info->key) {
- printf("Can't allocate memory for key\n");
+ fprintf(stderr, "Can't allocate memory for key\n");
ret = -1;
goto out;
}
@@ -423,7 +429,7 @@ static int fit_image_setup_cipher(struct image_cipher_info *info,
info->iv = malloc(info->cipher->iv_len);
if (!info->iv) {
- printf("Can't allocate memory for iv\n");
+ fprintf(stderr, "Can't allocate memory for iv\n");
ret = -1;
goto out;
}
@@ -457,7 +463,7 @@ int fit_image_write_cipher(void *fit, int image_noffset, int noffset,
goto out;
}
if (ret) {
- printf("Can't replace data with ciphered data (err = %d)\n", ret);
+ fprintf(stderr, "Can't replace data with ciphered data (err = %d)\n", ret);
goto out;
}
@@ -468,7 +474,7 @@ int fit_image_write_cipher(void *fit, int image_noffset, int noffset,
goto out;
}
if (ret) {
- printf("Can't add unciphered data size (err = %d)\n", ret);
+ fprintf(stderr, "Can't add unciphered data size (err = %d)\n", ret);
goto out;
}
@@ -508,8 +514,9 @@ fit_image_process_cipher(const char *keydir, void *keydest, void *fit,
if (keydest) {
ret = info.cipher->add_cipher_data(&info, keydest, fit, node_noffset);
if (ret) {
- printf("Failed to add verification data for cipher '%s' in image '%s'\n",
- info.keyname, image_name);
+ fprintf(stderr,
+ "Failed to add verification data for cipher '%s' in image '%s'\n",
+ info.keyname, image_name);
goto out;
}
}
@@ -538,13 +545,13 @@ int fit_image_cipher_data(const char *keydir, void *keydest,
/* Get image name */
image_name = fit_get_name(fit, image_noffset, NULL);
if (!image_name) {
- printf("Can't get image name\n");
+ fprintf(stderr, "Can't get image name\n");
return -1;
}
/* Get image data and data length */
if (fit_image_get_data(fit, image_noffset, &data, &size)) {
- printf("Can't get image data/size\n");
+ fprintf(stderr, "Can't get image data/size\n");
return -1;
}
@@ -558,7 +565,7 @@ int fit_image_cipher_data(const char *keydir, void *keydest,
if (fdt_getprop(fit, image_noffset, "data-size-unciphered", &len))
return 0;
if (len != -FDT_ERR_NOTFOUND) {
- printf("Failure testing for data-size-unciphered\n");
+ fprintf(stderr, "Failure testing for data-size-unciphered\n");
return -1;
}
@@ -568,7 +575,7 @@ int fit_image_cipher_data(const char *keydir, void *keydest,
if (cipher_node_offset == -FDT_ERR_NOTFOUND)
return 0;
if (cipher_node_offset < 0) {
- printf("Failure getting cipher node\n");
+ fprintf(stderr, "Failure getting cipher node\n");
return -1;
}
if (!IMAGE_ENABLE_ENCRYPT || !keydir)
@@ -624,7 +631,7 @@ int fit_image_add_verification_data(const char *keydir, const char *keyfile,
/* Get image data and data length */
if (fit_image_get_data(fit, image_noffset, &data, &size)) {
- printf("Can't get image data/size\n");
+ fprintf(stderr, "Can't get image data/size\n");
return -1;
}
@@ -765,8 +772,9 @@ static int fit_config_add_hash(const void *fit, int image_noffset,
}
if (!hash_count) {
- printf("Failed to find any hash nodes in configuration '%s/%s' image '%s' - without these it is not possible to verify this image\n",
- conf_name, sig_name, iname);
+ fprintf(stderr,
+ "Failed to find any hash nodes in configuration '%s/%s' image '%s' - without these it is not possible to verify this image\n",
+ conf_name, sig_name, iname);
return -ENOMSG;
}
@@ -775,9 +783,10 @@ static int fit_config_add_hash(const void *fit, int image_noffset,
FIT_CIPHER_NODENAME);
if (noffset != -FDT_ERR_NOTFOUND) {
if (noffset < 0) {
- printf("Failed to get cipher node in configuration '%s/%s' image '%s': %s\n",
- conf_name, sig_name, iname,
- fdt_strerror(noffset));
+ fprintf(stderr,
+ "Failed to get cipher node in configuration '%s/%s' image '%s': %s\n",
+ conf_name, sig_name, iname,
+ fdt_strerror(noffset));
return -EIO;
}
ret = fdt_get_path(fit, noffset, path, sizeof(path));
@@ -790,13 +799,13 @@ static int fit_config_add_hash(const void *fit, int image_noffset,
return 0;
err_mem:
- printf("Out of memory processing configuration '%s/%s'\n", conf_name,
- sig_name);
+ fprintf(stderr, "Out of memory processing configuration '%s/%s'\n", conf_name,
+ sig_name);
return -ENOMEM;
err_path:
- printf("Failed to get path for image '%s' in configuration '%s/%s': %s\n",
- iname, conf_name, sig_name, fdt_strerror(ret));
+ 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;
}
@@ -857,8 +866,9 @@ static int fit_config_get_hash_list(const void *fit, int conf_noffset,
iname, index);
if (image_noffset < 0) {
- printf("Failed to find image '%s' in configuration '%s/%s'\n",
- iname, conf_name, sig_name);
+ fprintf(stderr,
+ "Failed to find image '%s' in configuration '%s/%s'\n",
+ iname, conf_name, sig_name);
if (allow_missing)
continue;
@@ -875,16 +885,16 @@ static int fit_config_get_hash_list(const void *fit, int conf_noffset,
}
if (!image_count) {
- printf("Failed to find any images for configuration '%s/%s'\n",
- conf_name, sig_name);
+ fprintf(stderr, "Failed to find any images for configuration '%s/%s'\n",
+ conf_name, sig_name);
return -ENOMSG;
}
return 0;
err_mem:
- printf("Out of memory processing configuration '%s/%s'\n", conf_name,
- sig_name);
+ fprintf(stderr, "Out of memory processing configuration '%s/%s'\n", conf_name,
+ sig_name);
return -ENOMEM;
}
@@ -946,21 +956,21 @@ static int fit_config_get_regions(const void *fit, int conf_noffset,
fdt_regions, ARRAY_SIZE(fdt_regions),
path, sizeof(path), 1);
if (count < 0) {
- printf("Failed to hash configuration '%s/%s': %s\n", conf_name,
- sig_name, fdt_strerror(ret));
+ fprintf(stderr, "Failed to hash configuration '%s/%s': %s\n", conf_name,
+ sig_name, fdt_strerror(ret));
return -EIO;
}
if (count == 0) {
- printf("No data to hash for configuration '%s/%s': %s\n",
- conf_name, sig_name, fdt_strerror(ret));
+ fprintf(stderr, "No data to hash for configuration '%s/%s': %s\n",
+ conf_name, sig_name, fdt_strerror(ret));
return -EINVAL;
}
/* Build our list of data blocks */
region = fit_region_make_list(fit, fdt_regions, count, NULL);
if (!region) {
- printf("Out of memory hashing configuration '%s/%s'\n",
- conf_name, sig_name);
+ fprintf(stderr, "Out of memory hashing configuration '%s/%s'\n",
+ conf_name, sig_name);
return -ENOMEM;
}
@@ -972,8 +982,8 @@ static int fit_config_get_regions(const void *fit, int conf_noffset,
}
region_prop = malloc(len);
if (!region_prop) {
- printf("Out of memory setting up regions for configuration '%s/%s'\n",
- conf_name, sig_name);
+ fprintf(stderr, "Out of memory setting up regions for configuration '%s/%s'\n",
+ conf_name, sig_name);
return -ENOMEM;
}
for (i = len = 0; i < node_inc.count;
@@ -1038,8 +1048,8 @@ static int fit_config_process_sig(const char *keydir, const char *keyfile,
&value_len);
free(region);
if (ret) {
- printf("Failed to sign '%s' signature node in '%s' conf node\n",
- node_name, conf_name);
+ fprintf(stderr, "Failed to sign '%s' signature node in '%s' conf node\n",
+ node_name, conf_name);
/* We allow keys to be missing */
if (ret == -ENOENT)
@@ -1053,8 +1063,9 @@ static int fit_config_process_sig(const char *keydir, const char *keyfile,
if (ret) {
if (ret == -FDT_ERR_NOSPACE)
return -ENOSPC;
- printf("Can't write signature for '%s' signature node in '%s' conf node: %s\n",
- node_name, conf_name, fdt_strerror(ret));
+ fprintf(stderr,
+ "Can't write signature for '%s' signature node in '%s' conf node: %s\n",
+ node_name, conf_name, fdt_strerror(ret));
return -1;
}
free(value);
@@ -1067,8 +1078,9 @@ static int fit_config_process_sig(const char *keydir, const char *keyfile,
if (keydest) {
ret = info.crypto->add_verify_data(&info, keydest);
if (ret < 0) {
- printf("Failed to add verification data for '%s' signature node in '%s' configuration node\n",
- node_name, conf_name);
+ fprintf(stderr,
+ "Failed to add verification data for '%s' signature node in '%s' configuration node\n",
+ node_name, conf_name);
}
return ret;
}
@@ -1148,7 +1160,7 @@ static int read_pub_key(const char *keydir, const void *name,
/* Read the certificate */
cert = NULL;
if (!PEM_read_X509(f, &cert, NULL, NULL)) {
- printf("Couldn't read certificate");
+ fprintf(stderr, "Couldn't read certificate");
ret = -EINVAL;
goto err_cert;
}
@@ -1156,7 +1168,7 @@ static int read_pub_key(const char *keydir, const void *name,
/* Get the public key from the certificate. */
key = X509_get_pubkey(cert);
if (!key) {
- printf("Couldn't read public key\n");
+ fprintf(stderr, "Couldn't read public key\n");
ret = -EINVAL;
goto err_pubkey;
}
@@ -1164,7 +1176,7 @@ static int read_pub_key(const char *keydir, const void *name,
/* Get DER form */
ret = i2d_PublicKey(key, pubkey);
if (ret < 0) {
- printf("Couldn't get DER form\n");
+ fprintf(stderr, "Couldn't get DER form\n");
ret = -EINVAL;
goto err_pubkey;
}
@@ -1203,11 +1215,11 @@ int fit_pre_load_data(const char *keydir, void *keydest, void *fit)
/* Check that all mandatory properties are present */
if (!algo_name || !key_name) {
if (!algo_name)
- printf("The property algo-name is missing in the node %s\n",
- IMAGE_PRE_LOAD_PATH);
+ fprintf(stderr, "The property algo-name is missing in the node %s\n",
+ IMAGE_PRE_LOAD_PATH);
if (!key_name)
- printf("The property key-name is missing in the node %s\n",
- IMAGE_PRE_LOAD_PATH);
+ fprintf(stderr, "The property key-name is missing in the node %s\n",
+ IMAGE_PRE_LOAD_PATH);
ret = -EINVAL;
goto out;
}
@@ -1221,8 +1233,8 @@ int fit_pre_load_data(const char *keydir, void *keydest, void *fit)
ret = fdt_setprop(keydest, pre_load_noffset, "public-key",
pubkey, pubkey_len);
if (ret)
- printf("Can't set public-key in node %s (ret = %d)\n",
- IMAGE_PRE_LOAD_PATH, ret);
+ fprintf(stderr, "Can't set public-key in node %s (ret = %d)\n",
+ IMAGE_PRE_LOAD_PATH, ret);
out:
return ret;
@@ -1239,8 +1251,8 @@ int fit_cipher_data(const char *keydir, void *keydest, void *fit,
/* Find images parent node offset */
images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
if (images_noffset < 0) {
- printf("Can't find images parent node '%s' (%s)\n",
- FIT_IMAGES_PATH, fdt_strerror(images_noffset));
+ fprintf(stderr, "Can't find images parent node '%s' (%s)\n",
+ FIT_IMAGES_PATH, fdt_strerror(images_noffset));
return images_noffset;
}
@@ -1276,8 +1288,8 @@ int fit_add_verification_data(const char *keydir, const char *keyfile,
/* Find images parent node offset */
images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
if (images_noffset < 0) {
- printf("Can't find images parent node '%s' (%s)\n",
- FIT_IMAGES_PATH, fdt_strerror(images_noffset));
+ fprintf(stderr, "Can't find images parent node '%s' (%s)\n",
+ FIT_IMAGES_PATH, fdt_strerror(images_noffset));
return images_noffset;
}
@@ -1293,9 +1305,9 @@ int fit_add_verification_data(const char *keydir, const char *keyfile,
fit, noffset, comment, require_keys, engine_id,
cmdname, algo_name);
if (ret) {
- printf("Can't add verification data for node '%s' (%s)\n",
- fdt_get_name(fit, noffset, NULL),
- fdt_strerror(ret));
+ fprintf(stderr, "Can't add verification data for node '%s' (%s)\n",
+ fdt_get_name(fit, noffset, NULL),
+ fdt_strerror(ret));
return ret;
}
}
@@ -1307,8 +1319,8 @@ int fit_add_verification_data(const char *keydir, const char *keyfile,
/* Find configurations parent node offset */
confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
if (confs_noffset < 0) {
- printf("Can't find images parent node '%s' (%s)\n",
- FIT_CONFS_PATH, fdt_strerror(confs_noffset));
+ fprintf(stderr, "Can't find images parent node '%s' (%s)\n",
+ FIT_CONFS_PATH, fdt_strerror(confs_noffset));
return -ENOENT;
}
diff --git a/tools/logos/ti.bmp b/tools/logos/ti_logo_414x97_32bpp.bmp
index 7fee6e81e0..7fee6e81e0 100644
--- a/tools/logos/ti.bmp
+++ b/tools/logos/ti_logo_414x97_32bpp.bmp
Binary files differ
diff --git a/tools/logos/ti.gz b/tools/logos/ti_logo_414x97_32bpp.bmp.gz
index 3a5b45e035..3a5b45e035 100644
--- a/tools/logos/ti.gz
+++ b/tools/logos/ti_logo_414x97_32bpp.bmp.gz
Binary files differ
diff --git a/tools/relocate-rela.c b/tools/relocate-rela.c
index f230ec5676..613abd25ef 100644
--- a/tools/relocate-rela.c
+++ b/tools/relocate-rela.c
@@ -24,6 +24,30 @@
#define R_AARCH64_RELATIVE 1027
#endif
+#ifndef EM_M68K
+#define EM_M68K 4
+#endif
+
+#ifndef R_68K_NONE
+#define R_68K_NONE 0
+#endif
+
+#ifndef R_68K_32
+#define R_68K_32 1
+#endif
+
+#ifndef R_68K_GLOB_DAT
+#define R_68K_GLOB_DAT 20
+#endif
+
+#ifndef R_68K_JMP_SLOT
+#define R_68K_JMP_SLOT 21
+#endif
+
+#ifndef R_68K_RELATIVE
+#define R_68K_RELATIVE 22
+#endif
+
#ifndef EM_MICROBLAZE
#define EM_MICROBLAZE 189
#endif
@@ -46,6 +70,7 @@
static int ei_class;
static int ei_data;
+static int machine;
static uint64_t rela_start, rela_end, text_base, dyn_start;
@@ -78,6 +103,14 @@ static uint32_t elf32_to_cpu(uint32_t data)
return be32_to_cpu(data);
}
+static uint32_t cpu_to_elf32(uint32_t data)
+{
+ if (ei_data == ELFDATA2LSB)
+ return cpu_to_le32(data);
+
+ return cpu_to_be32(data);
+}
+
static bool supported_rela(Elf64_Rela *rela)
{
uint64_t mask = 0xffffffffULL; /* would be different on 32-bit */
@@ -103,7 +136,7 @@ static int decode_elf64(FILE *felf, char **argv)
uint64_t sh_addr, sh_offset, sh_size;
Elf64_Half sh_index, sh_num;
Elf64_Shdr *sh_table; /* Elf symbol table */
- int ret, i, machine;
+ int ret, i;
char *sh_str;
debug("64bit version\n");
@@ -237,7 +270,7 @@ static int decode_elf32(FILE *felf, char **argv)
uint32_t sh_addr, sh_offset, sh_size;
Elf32_Half sh_index, sh_num;
Elf32_Shdr *sh_table; /* Elf symbol table */
- int ret, i, machine;
+ int ret, i;
char *sh_str;
debug("32bit version\n");
@@ -254,12 +287,20 @@ static int decode_elf32(FILE *felf, char **argv)
machine = elf16_to_cpu(header.e_machine);
debug("Machine %d\n", machine);
- if (machine != EM_MICROBLAZE) {
+ if (machine != EM_MICROBLAZE && machine != EM_M68K) {
fprintf(stderr, "%s: Not supported machine type\n", argv[0]);
return 30;
}
text_base = elf32_to_cpu(header.e_entry);
+ /*
+ * M68K ELF entry point is MONITOR_BASE, not TEXT_BASE.
+ * TEXT_BASE is always MONITOR_BASE &~ 0x7ff, so clear
+ * those bits here.
+ */
+ if (machine == EM_M68K)
+ text_base &= ~0x7ff;
+
section_header_base = elf32_to_cpu(header.e_shoff);
section_header_size = elf16_to_cpu(header.e_shentsize) *
elf16_to_cpu(header.e_shnum);
@@ -480,25 +521,44 @@ static bool supported_rela32(Elf32_Rela *rela, uint32_t *type)
debug("Type:\t");
- switch (*type) {
- case R_MICROBLAZE_32:
- debug("R_MICROBLAZE_32\n");
- return true;
- case R_MICROBLAZE_GLOB_DAT:
- debug("R_MICROBLAZE_GLOB_DAT\n");
- return true;
- case R_MICROBLAZE_NONE:
- debug("R_MICROBLAZE_NONE - ignoring - do nothing\n");
- return false;
- case R_MICROBLAZE_REL:
- debug("R_MICROBLAZE_REL\n");
- return true;
- default:
- fprintf(stderr, "warning: unsupported relocation type %"
- PRIu32 " at %" PRIx32 "\n", *type, rela->r_offset);
-
- return false;
+ if (machine == EM_M68K) {
+ switch (*type) {
+ case R_68K_32:
+ debug("R_68K_32\n");
+ return true;
+ case R_68K_GLOB_DAT:
+ debug("R_68K_GLOB_DAT\n");
+ return true;
+ case R_68K_JMP_SLOT:
+ debug("R_68K_JMP_SLOT\n");
+ return true;
+ case R_68K_NONE:
+ debug("R_68K_NONE - ignoring - do nothing\n");
+ return false;
+ case R_68K_RELATIVE:
+ debug("R_68K_RELATIVE\n");
+ return true;
+ }
+ } else {
+ switch (*type) {
+ case R_MICROBLAZE_32:
+ debug("R_MICROBLAZE_32\n");
+ return true;
+ case R_MICROBLAZE_GLOB_DAT:
+ debug("R_MICROBLAZE_GLOB_DAT\n");
+ return true;
+ case R_MICROBLAZE_NONE:
+ debug("R_MICROBLAZE_NONE - ignoring - do nothing\n");
+ return false;
+ case R_MICROBLAZE_REL:
+ debug("R_MICROBLAZE_REL\n");
+ return true;
+ }
}
+ fprintf(stderr, "warning: unsupported relocation type %"
+ PRIu32 " at %" PRIx32 "\n", *type, rela->r_offset);
+
+ return false;
}
static int rela_elf32(char **argv, FILE *f)
@@ -561,8 +621,8 @@ static int rela_elf32(char **argv, FILE *f)
debug("Addr:\t0x%" PRIx32 "\n", addr);
- switch (type) {
- case R_MICROBLAZE_REL:
+ if ((machine == EM_M68K && type == R_68K_RELATIVE) ||
+ (machine == EM_MICROBLAZE && type == R_MICROBLAZE_REL)) {
if (fseek(f, addr, SEEK_SET) < 0) {
fprintf(stderr, "%s: %s: seek to %"
PRIx32 " failed: %s\n",
@@ -577,9 +637,12 @@ static int rela_elf32(char **argv, FILE *f)
argv[0], argv[1], addr);
return 4;
}
- break;
- case R_MICROBLAZE_32:
- case R_MICROBLAZE_GLOB_DAT:
+ } else if ((machine == EM_M68K &&
+ (type == R_68K_32 || type == R_68K_GLOB_DAT ||
+ type == R_68K_JMP_SLOT)) ||
+ (machine == EM_MICROBLAZE &&
+ (type == R_MICROBLAZE_32 ||
+ type == R_MICROBLAZE_GLOB_DAT))) {
/* global symbols read it and add reloc offset */
index = swrela.r_info >> 8;
pos_dyn = dyn_start + sizeof(Elf32_Sym) * index;
@@ -602,14 +665,16 @@ static int rela_elf32(char **argv, FILE *f)
}
debug("Symbol description:\n");
- debug(" st_name:\t0x%x\n", symbols.st_name);
- debug(" st_value:\t0x%x\n", symbols.st_value);
- debug(" st_size:\t0x%x\n", symbols.st_size);
+ debug(" st_name:\t0x%x\n", elf32_to_cpu(symbols.st_name));
+ debug(" st_value:\t0x%x\n", elf32_to_cpu(symbols.st_value));
+ debug(" st_size:\t0x%x\n", elf32_to_cpu(symbols.st_size));
- value = swrela.r_addend + symbols.st_value;
+ value = swrela.r_addend + elf32_to_cpu(symbols.st_value);
debug("Value:\t0x%x\n", value);
+ value = cpu_to_elf32(value);
+
if (fseek(f, addr, SEEK_SET) < 0) {
fprintf(stderr, "%s: %s: seek to %"
PRIx32 " failed: %s\n",
@@ -622,12 +687,11 @@ static int rela_elf32(char **argv, FILE *f)
argv[0], argv[1], addr);
return 4;
}
-
- break;
- case R_MICROBLAZE_NONE:
+ } else if (machine == EM_M68K && type == R_68K_NONE) {
+ debug("R_68K_NONE - skip\n");
+ } else if (machine == EM_MICROBLAZE && type == R_MICROBLAZE_NONE) {
debug("R_MICROBLAZE_NONE - skip\n");
- break;
- default:
+ } else {
fprintf(stderr, "warning: unsupported relocation type %"
PRIu32 " at %" PRIx32 "\n",
type, rela.r_offset);
diff --git a/tools/sfspl.c b/tools/sfspl.c
new file mode 100644
index 0000000000..ec18a0a77e
--- /dev/null
+++ b/tools/sfspl.c
@@ -0,0 +1,174 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
+ *
+ * The StarFive JH7110 requires to prepend a header to u-boot-spl.bin describing
+ * the payload length and CRC32.
+ *
+ * This module implements support in mkimage and dumpimage for this file format.
+ *
+ * StarFive's spl_tool available under GPL-2.0-and-later at
+ * https://github.com/starfive-tech/Tools implements writing the same file
+ * format and served as a reference.
+ */
+
+#include <compiler.h>
+#include <fcntl.h>
+#include <u-boot/crc.h>
+#include <unistd.h>
+#include "imagetool.h"
+
+#define DEFAULT_VERSION 0x01010101
+#define DEFAULT_BACKUP 0x200000U
+#define DEFAULT_OFFSET 0x240
+
+/**
+ * struct spl_hdr - header for SPL on JH7110
+ *
+ * All fields are low-endian.
+ */
+struct spl_hdr {
+ /** @offset: offset to SPL header (0x240) */
+ unsigned int offset;
+ /** @bkp_offs: address of backup SPL, defaults to DEFAULT_BACKUP */
+ unsigned int bkp_offs;
+ /** @zero1: set to zero */
+ unsigned int zero1[159];
+ /** @version: header version, defaults to DEFAULT_VERSION */
+ unsigned int version;
+ /** @file_size: file size */
+ unsigned int file_size;
+ /** @hdr_size: size of the file header (0x400) */
+ unsigned int hdr_size;
+ /** @crc32: CRC32 */
+ unsigned int crc32;
+ /** @zero2: set to zero */
+ unsigned int zero2[91];
+};
+
+static int sfspl_check_params(struct image_tool_params *params)
+{
+ /* Only the RISC-V architecture is supported */
+ if (params->Aflag && params->arch != IH_ARCH_RISCV)
+ return EXIT_FAILURE;
+
+ return EXIT_SUCCESS;
+}
+
+static int sfspl_verify_header(unsigned char *buf, int size,
+ struct image_tool_params *params)
+{
+ struct spl_hdr *hdr = (void *)buf;
+ unsigned int hdr_size = le32_to_cpu(hdr->hdr_size);
+ unsigned int file_size = le32_to_cpu(hdr->file_size);
+ unsigned int crc = le32_to_cpu(hdr->crc32);
+ unsigned int crc_check;
+
+ if (size < 0 ||
+ (size_t)size < sizeof(struct spl_hdr) ||
+ (size_t)size < hdr_size + file_size) {
+ printf("Truncated file\n");
+ return EXIT_FAILURE;
+ }
+ if (hdr->version != DEFAULT_VERSION) {
+ printf("Unknown file format version\n");
+ return EXIT_FAILURE;
+ }
+ crc_check = crc32(0, &buf[hdr_size], size - hdr_size);
+ if (crc_check != crc) {
+ printf("Incorrect CRC32\n");
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
+
+static void sfspl_print_header(const void *buf,
+ struct image_tool_params *params)
+{
+ struct spl_hdr *hdr = (void *)buf;
+ unsigned int hdr_size = le32_to_cpu(hdr->hdr_size);
+ unsigned int file_size = le32_to_cpu(hdr->file_size);
+
+ printf("Header size: %u\n", hdr_size);
+ printf("Payload size: %u\n", file_size);
+}
+
+static int sfspl_image_extract_subimage(void *ptr,
+ struct image_tool_params *params)
+{
+ struct spl_hdr *hdr = (void *)ptr;
+ unsigned char *buf = ptr;
+ int fd;
+ unsigned int hdr_size = le32_to_cpu(hdr->hdr_size);
+ unsigned int file_size = le32_to_cpu(hdr->file_size);
+
+ if (params->pflag) {
+ printf("Invalid image index %d\n", params->pflag);
+ return EXIT_FAILURE;
+ }
+
+ fd = open(params->outfile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ if (fd == -1) {
+ perror("Can write file");
+ return EXIT_FAILURE;
+ }
+ if (write(fd, &buf[hdr_size], file_size) != file_size) {
+ perror("Cannot write file");
+ return EXIT_FAILURE;
+ }
+ close(fd);
+
+ return EXIT_SUCCESS;
+}
+
+static int sfspl_check_image_type(uint8_t type)
+{
+ if (type == IH_TYPE_STARFIVE_SPL)
+ return EXIT_SUCCESS;
+
+ return EXIT_FAILURE;
+}
+
+static void sfspl_set_header(void *buf, struct stat *sbuf, int infd,
+ struct image_tool_params *params)
+{
+ struct spl_hdr *hdr = buf;
+ unsigned int file_size;
+ unsigned int crc;
+
+ file_size = params->file_size - sizeof(struct spl_hdr);
+ crc = crc32(0, &((unsigned char *)buf)[sizeof(struct spl_hdr)],
+ file_size);
+
+ hdr->offset = cpu_to_le32(DEFAULT_OFFSET);
+ hdr->bkp_offs = cpu_to_le32(DEFAULT_BACKUP);
+ hdr->version = cpu_to_le32(DEFAULT_VERSION);
+ hdr->file_size = cpu_to_le32(file_size);
+ hdr->hdr_size = cpu_to_le32(sizeof(struct spl_hdr));
+ hdr->crc32 = cpu_to_le32(crc);
+}
+
+static int sfspl_vrec_header(struct image_tool_params *params,
+ struct image_type_params *tparams)
+{
+ tparams->hdr = calloc(sizeof(struct spl_hdr), 1);
+
+ /* No padding */
+ return 0;
+}
+
+U_BOOT_IMAGE_TYPE(
+ sfspl, /* id */
+ "StarFive SPL Image", /* name */
+ sizeof(struct spl_hdr), /* header_size */
+ NULL, /* header */
+ sfspl_check_params, /* check_params */
+ sfspl_verify_header, /* verify header */
+ sfspl_print_header, /* print header */
+ sfspl_set_header, /* set header */
+ sfspl_image_extract_subimage, /* extract_subimage */
+ sfspl_check_image_type, /* check_image_type */
+ NULL, /* fflag_handle */
+ sfspl_vrec_header /* vrec_header */
+);