binman: btool: Add Xilinx Bootgen btool
Add the Xilinx Bootgen as bintool. Xilinx Bootgen is used to create
bootable SPL (FSBL in Xilinx terms) images for Zynq/ZynqMP devices. The
btool creates a signed version of the SPL. Additionally to signing the
key source for the decryption engine can be passend to the boot image.
Signed-off-by: Lukas Funke <lukas.funke@weidmueller.com>
diff --git a/tools/binman/bintools.rst b/tools/binman/bintools.rst
index 20ee243..1336f4d 100644
--- a/tools/binman/bintools.rst
+++ b/tools/binman/bintools.rst
@@ -208,7 +208,7 @@
Bintool: bootgen: Sign ZynqMP FSBL image
----------------------------------------------
+----------------------------------------
This bintool supports running `bootgen` in order to sign a SPL for ZynqMP
devices.
diff --git a/tools/binman/btool/bootgen.py b/tools/binman/btool/bootgen.py
new file mode 100644
index 0000000..f2ca552
--- /dev/null
+++ b/tools/binman/btool/bootgen.py
@@ -0,0 +1,137 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (C) 2023 Weidmüller Interface GmbH & Co. KG
+# Lukas Funke <lukas.funke@weidmueller.com>
+#
+"""Bintool implementation for bootgen
+
+bootgen allows creating bootable SPL for Zynq(MP)
+
+Documentation is available via:
+https://www.xilinx.com/support/documents/sw_manuals/xilinx2022_1/ug1283-bootgen-user-guide.pdf
+
+Source code is available at:
+https://github.com/Xilinx/bootgen
+
+"""
+
+from binman import bintool
+from u_boot_pylib import tools
+
+# pylint: disable=C0103
+class Bintoolbootgen(bintool.Bintool):
+ """Generate bootable fsbl image for zynq/zynqmp
+
+ This bintools supports running Xilinx "bootgen" in order
+ to generate a bootable, authenticated image form an SPL.
+
+ """
+ def __init__(self, name):
+ super().__init__(name, 'Xilinx Bootgen',
+ version_regex=r'^\*\*\*\*\*\* *Xilinx Bootgen *(.*)',
+ version_args='-help')
+
+ # pylint: disable=R0913
+ def sign(self, arch, spl_elf_fname, pmufw_elf_fname,
+ psk_fname, ssk_fname, fsbl_config, auth_params, keysrc_enc,
+ output_fname):
+ """Sign SPL elf file and bundle it with PMU firmware into an image
+
+ The method bundels the SPL together with a 'Platform Management Unit'
+ (PMU)[1] firmware into a single bootable image. The image in turn is
+ signed with the provided 'secondary secret key' (ssk), which in turn is
+ signed with the 'primary secret key' (psk). In order to verify the
+ authenticity of the ppk, it's hash has to be fused into the device
+ itself.
+
+ In Xilinx terms the SPL is usually called 'FSBL'
+ (First Stage Boot Loader). The jobs of the SPL and the FSBL are mostly
+ the same: load bitstream, bootstrap u-boot.
+
+ Args:
+ arch (str): Xilinx SoC architecture. Currently only 'zynqmp' is
+ supported.
+ spl_elf_fname (str): Filename of SPL ELF file. The filename must end
+ with '.elf' in order for bootgen to recognized it as an ELF
+ file. Otherwise the start address field is missinterpreted.
+ pmufw_elf_fname (str): Filename PMU ELF firmware.
+ psk_fname (str): Filename of the primary secret key (psk). The psk
+ is a .pem file which holds the RSA private key used for signing
+ the secondary secret key.
+ ssk_fname (str): Filename of the secondary secret key. The ssk
+ is a .pem file which holds the RSA private key used for signing
+ the actual boot firmware.
+ fsbl_config (str): FSBL config options. A string list of fsbl config
+ options. Valid values according to [2] are:
+ "bh_auth_enable": Boot Header Authentication Enable: RSA
+ authentication of the bootimage is done
+ excluding the verification of PPK hash and SPK ID. This is
+ useful for debugging before bricking a device.
+ "auth_only": Boot image is only RSA signed. FSBL should not be
+ decrypted. See the
+ Zynq UltraScale+ Device Technical Reference Manual (UG1085)
+ for more information.
+ There are more options which relate to PUF (physical unclonable
+ functions). Please refer to Xilinx manuals for further info.
+ auth_params (str): Authentication parameter. A semicolon separated
+ list of authentication parameters. Valid values according to [3]
+ are:
+ "ppk_select=<0|1>" - Select which ppk to use
+ "spk_id=<32-bit spk id>" - Specifies which SPK can be
+ used or revoked, default is 0x0
+ "spk_select=<spk-efuse/user-efuse>" - To differentiate spk and
+ user efuses.
+ "auth_header" - To authenticate headers when no partition
+ is authenticated.
+ keysrc_enc (str): This specifies the Key source for encryption.
+ Valid values according to [3] are:
+ "bbram_red_key" - RED key stored in BBRAM
+ "efuse_red_key" - RED key stored in eFUSE
+ "efuse_gry_key" - Grey (Obfuscated) Key stored in eFUSE.
+ "bh_gry_key" - Grey (Obfuscated) Key stored in boot header
+ "bh_blk_key" - Black Key stored in boot header
+ "efuse_blk_key" - Black Key stored in eFUSE
+ "kup_key" - User Key
+
+ output_fname (str): Filename where bootgen should write the result
+
+ Returns:
+ str: Bootgen output from stdout
+
+ [1] https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841724/PMU+Firmware
+ [2] https://docs.xilinx.com/r/en-US/ug1283-bootgen-user-guide/fsbl_config
+ [3] https://docs.xilinx.com/r/en-US/ug1283-bootgen-user-guide/auth_params
+ [4] https://docs.xilinx.com/r/en-US/ug1283-bootgen-user-guide/keysrc_encryption
+ """
+
+ _fsbl_config = f"[fsbl_config] {fsbl_config}" if fsbl_config else ""
+ _auth_params = f"[auth_params] {auth_params}" if auth_params else ""
+ _keysrc_enc = f"[keysrc_encryption] {keysrc_enc}" if keysrc_enc else ""
+
+ bif_template = f"""u_boot_spl_aes_rsa: {{
+ [pskfile] {psk_fname}
+ [sskfile] {ssk_fname}
+ {_keysrc_enc}
+ {_fsbl_config}
+ {_auth_params}
+ [ bootloader,
+ authentication = rsa,
+ destination_cpu=a53-0] {spl_elf_fname}
+ [pmufw_image] {pmufw_elf_fname}
+ }}"""
+ args = ["-arch", arch]
+
+ bif_fname = tools.get_output_filename('bootgen-in.sign.bif')
+ tools.write_file(bif_fname, bif_template, False)
+ args += ["-image", bif_fname, '-w', '-o', output_fname]
+ return self.run_cmd(*args)
+
+ def fetch(self, method):
+ """Fetch bootgen from git"""
+ if method != bintool.FETCH_BUILD:
+ return None
+
+ result = self.build_from_git(
+ 'https://github.com/Xilinx/bootgen',
+ 'all',
+ 'bootgen')
+ return result