[PATCH v2 38/38] RFC: Move Odroid-C2 to use binman to produce the image

Simon Glass sjg at chromium.org
Mon Jan 10 04:14:13 CET 2022


This shows how binman can be used to replace the long and complicated
instructions with an automated build. It is still complicated to read
but users don't have to worry about the details.

It needs some tidying up and only supports Odroid-C2 at present.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

Changes in v2:
- Substantial rewrite, introducing the concept of bintools

 arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi | 107 ++++++++
 arch/arm/mach-meson/Kconfig                  |   1 +
 doc/board/amlogic/odroid-c4.rst              | 127 +++------
 tools/binman/bintools.rst                    |  24 ++
 tools/binman/btool/_aml_common.py            |  47 ++++
 tools/binman/btool/aml_encrypt_g12a.py       |  82 ++++++
 tools/binman/btool/aml_encrypt_g12b.py       |  83 ++++++
 tools/binman/entries.rst                     | 138 ++++++++++
 tools/binman/etype/aml_encrypt.py            | 262 +++++++++++++++++++
 tools/binman/ftest.py                        |   9 +
 tools/binman/missing-blob-help               |   6 +
 tools/binman/test/213_aml_encrypt.dts        |  51 ++++
 tools/binman/test/214_list_no_dtb.dts        |  23 ++
 13 files changed, 868 insertions(+), 92 deletions(-)
 create mode 100644 tools/binman/btool/_aml_common.py
 create mode 100644 tools/binman/btool/aml_encrypt_g12a.py
 create mode 100644 tools/binman/btool/aml_encrypt_g12b.py
 create mode 100644 tools/binman/etype/aml_encrypt.py
 create mode 100644 tools/binman/test/213_aml_encrypt.dts
 create mode 100644 tools/binman/test/214_list_no_dtb.dts

diff --git a/arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi b/arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi
index 963bf96b256..b221ce6920b 100644
--- a/arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi
+++ b/arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi
@@ -6,6 +6,113 @@
 
 #include "meson-sm1-u-boot.dtsi"
 
+/{
+	binman {
+		/* run --bootmk on all the included inputs */
+		aml-encrypt {
+			missing-msg = "aml-encrypt";
+			aml-algo = "g12a";
+			aml-op = "bootmk";
+			aml-level = "v3";
+
+			/* produce a bl2, containing signed bl2 binaries */
+			bl2 {
+				type = "aml-encrypt";
+				aml-algo = "g12a";
+				aml-op = "bl2sig";
+
+				/* sign the binary contaiing bl2 and acs */
+				aml-input {
+					type = "section";
+					bl2 {
+						type = "blob-ext";
+						size = <0xe000>;
+						filename = "bl2.bin";
+					};
+					acs {
+						type = "blob-ext";
+						size = <0x1000>;
+						filename = "acs.bin";
+					};
+				};
+			};
+
+			/* produce a bl30, containing signed bl30 binaries */
+			bl30 {
+				type = "aml-encrypt";
+				aml-algo = "g12a";
+				aml-op = "bl3sig";
+				aml-level = "v3";
+				aml-type = "bl30";
+
+				/* sign the binary contaiing bl30 and bl301 */
+				aml-input {
+					type = "aml-encrypt";
+					aml-algo = "g12a";
+					aml-op = "bl30sig";
+					aml-level = "v3";
+
+					/*
+					 * put bl30 and bl301 together, with
+					 * the necessary paddiung
+					 */
+					aml-input {
+						type = "section";
+						bl30 {
+							type = "blob-ext";
+							size = <0xa000>;
+							filename = "bl30.bin";
+						};
+						bl301 {
+							type = "blob-ext";
+							size = <0x3400>;
+							filename = "bl301.bin";
+						};
+					};
+				};
+			};
+
+			/* sign the bl31 binary */
+			bl31 {
+				type = "aml-encrypt";
+				aml-algo = "g12a";
+				aml-op = "bl3sig";
+				aml-input = "bl31.img";
+				aml-level = "v3";
+				aml-type = "bl31";
+			};
+
+			/* sign the bl33 binary (which is U-Boot) */
+			bl33 {
+				type = "aml-encrypt";
+				aml-algo = "g12a";
+				aml-op = "bl3sig";
+				aml-compress = "lz4";
+				aml-level = "v3";
+				aml-type = "bl33";
+
+				aml-input {
+					type = "u-boot";
+				};
+			};
+
+			/* add the various DDR blobs */
+			aml-ddrfw {
+				missing-msg = "aml-ddrfw";
+				type = "blob-ext-list";
+				filenames = "ddr4_1d.fw", "ddr4_2d.fw",
+					"ddr3_1d.fw", "piei.fw",
+					"lpddr4_1d.fw", "lpddr4_2d.fw",
+					"diag_lpddr4.fw", "aml_ddr.fw",
+					"lpddr3_1d.fw";
+			};
+		};
+
+		fdtmap {
+		};
+	};
+};
+
 &ethmac {
 	snps,reset-gpio = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
 	snps,reset-delays-us = <0 10000 1000000>;
diff --git a/arch/arm/mach-meson/Kconfig b/arch/arm/mach-meson/Kconfig
index 6cba2c40dda..bcb87ea243c 100644
--- a/arch/arm/mach-meson/Kconfig
+++ b/arch/arm/mach-meson/Kconfig
@@ -48,6 +48,7 @@ config MESON_AXG
 config MESON_G12A
 	bool "G12A"
 	select MESON64_COMMON
+	select BINMAN
 	help
 	  Select this if your SoC is an S905X/D2
 
diff --git a/doc/board/amlogic/odroid-c4.rst b/doc/board/amlogic/odroid-c4.rst
index f66d60a54d1..5eae1e66e3a 100644
--- a/doc/board/amlogic/odroid-c4.rst
+++ b/doc/board/amlogic/odroid-c4.rst
@@ -22,17 +22,8 @@ applies for HC4.
 
 Schematics are available on the manufacturer website.
 
-U-Boot compilation
-------------------
-
-.. code-block:: bash
-
-    $ export CROSS_COMPILE=aarch64-none-elf-
-    $ make odroid-c4_defconfig
-    $ make
-
-Image creation
---------------
+Setting up binary blobs
+-----------------------
 
 Amlogic doesn't provide sources for the firmware and for tools needed
 to create the bootloader image, so it is necessary to obtain them from
@@ -40,98 +31,50 @@ the git tree published by the board vendor:
 
 .. code-block:: bash
 
-    $ wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
-    $ wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz
-    $ tar xvfJ gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
-    $ tar xvfJ gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz
-    $ export PATH=$PWD/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin:$PWD/gcc-linaro-arm-none-eabi-4.8-2013.11_linux/bin:$PATH
+    # This may be needed with this older U-Boot release
+    apt remove libfdt-dev
 
-    $ DIR=odroid-c4
-    $ git clone --depth 1 \
+    wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
+    wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz
+    tar xvfJ gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
+    tar xvfJ gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz
+    export PATH=$PWD/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin:$PWD/gcc-linaro-arm-none-eabi-4.8-2013.11_linux/bin:$PATH
+
+    DIR=odroid-c4
+    git clone --depth 1 \
        https://github.com/hardkernel/u-boot.git -b odroidg12-v2015.01 \
        $DIR
 
-    $ cd odroid-c4
-    $ make odroidc4_defconfig
-    $ make
-    $ export UBOOTDIR=$PWD
+    cd odroid-c4
+    make odroidc4_defconfig
+    make
+    export UBOOTDIR=$PWD
+
+U-Boot compilation
+------------------
 
 Go back to mainline U-Boot source tree then :
 
 .. code-block:: bash
 
-    $ mkdir fip
-
-    $ wget https://github.com/BayLibre/u-boot/releases/download/v2017.11-libretech-cc/blx_fix_g12a.sh -O fip/blx_fix.sh
-    $ cp $UBOOTDIR/build/scp_task/bl301.bin fip/
-    $ cp $UBOOTDIR/build/board/hardkernel/odroidc4/firmware/acs.bin fip/
-    $ cp $UBOOTDIR/fip/g12a/bl2.bin fip/
-    $ cp $UBOOTDIR/fip/g12a/bl30.bin fip/
-    $ cp $UBOOTDIR/fip/g12a/bl31.img fip/
-    $ cp $UBOOTDIR/fip/g12a/ddr3_1d.fw fip/
-    $ cp $UBOOTDIR/fip/g12a/ddr4_1d.fw fip/
-    $ cp $UBOOTDIR/fip/g12a/ddr4_2d.fw fip/
-    $ cp $UBOOTDIR/fip/g12a/diag_lpddr4.fw fip/
-    $ cp $UBOOTDIR/fip/g12a/lpddr3_1d.fw fip/
-    $ cp $UBOOTDIR/fip/g12a/lpddr4_1d.fw fip/
-    $ cp $UBOOTDIR/fip/g12a/lpddr4_2d.fw fip/
-    $ cp $UBOOTDIR/fip/g12a/piei.fw fip/
-    $ cp $UBOOTDIR/fip/g12a/aml_ddr.fw fip/
-    $ cp u-boot.bin fip/bl33.bin
-
-    $ sh fip/blx_fix.sh \
-    	fip/bl30.bin \
-    	fip/zero_tmp \
-    	fip/bl30_zero.bin \
-    	fip/bl301.bin \
-    	fip/bl301_zero.bin \
-    	fip/bl30_new.bin \
-    	bl30
-
-    $ sh fip/blx_fix.sh \
-    	fip/bl2.bin \
-    	fip/zero_tmp \
-    	fip/bl2_zero.bin \
-    	fip/acs.bin \
-    	fip/bl21_zero.bin \
-    	fip/bl2_new.bin \
-    	bl2
-
-    $ $UBOOTDIR/fip/g12a/aml_encrypt_g12a --bl30sig --input fip/bl30_new.bin \
-    					--output fip/bl30_new.bin.g12a.enc \
-    					--level v3
-    $ $UBOOTDIR/fip/g12a/aml_encrypt_g12a --bl3sig --input fip/bl30_new.bin.g12a.enc \
-    					--output fip/bl30_new.bin.enc \
-    					--level v3 --type bl30
-    $ $UBOOTDIR/fip/g12a/aml_encrypt_g12a --bl3sig --input fip/bl31.img \
-    					--output fip/bl31.img.enc \
-    					--level v3 --type bl31
-    $ $UBOOTDIR/fip/g12a/aml_encrypt_g12a --bl3sig --input fip/bl33.bin --compress lz4 \
-    					--output fip/bl33.bin.enc \
-    					--level v3 --type bl33 --compress lz4
-    $ $UBOOTDIR/fip/g12a/aml_encrypt_g12a --bl2sig --input fip/bl2_new.bin \
-    					--output fip/bl2.n.bin.sig
-    $ $UBOOTDIR/fip/g12a/aml_encrypt_g12a --bootmk \
-    		--output fip/u-boot.bin \
-    		--bl2 fip/bl2.n.bin.sig \
-    		--bl30 fip/bl30_new.bin.enc \
-    		--bl31 fip/bl31.img.enc \
-    		--bl33 fip/bl33.bin.enc \
-    		--ddrfw1 fip/ddr4_1d.fw \
-    		--ddrfw2 fip/ddr4_2d.fw \
-    		--ddrfw3 fip/ddr3_1d.fw \
-    		--ddrfw4 fip/piei.fw \
-    		--ddrfw5 fip/lpddr4_1d.fw \
-    		--ddrfw6 fip/lpddr4_2d.fw \
-    		--ddrfw7 fip/diag_lpddr4.fw \
-    		--ddrfw8 fip/aml_ddr.fw \
-    		--ddrfw9 fip/lpddr3_1d.fw \
-    		--level v3
+    $ export CROSS_COMPILE=aarch64-none-elf-
+    $ make odroid-c4_defconfig
+    $ BINMAN_TOOLPATHS=$UBOOTDIR/odroid-c4/fip/g12a \
+      BINMAN_INDIRS="$UBOOTDIR/fip/g12a \
+      $UBOOTDIR/build/board/hardkernel/odroidc4/firmware \
+      $UBOOTDIR/build/scp_task" make
 
 and then write the image to SD with:
 
 .. code-block:: bash
 
-    $ DEV=/dev/your_sd_device
-    $ dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=512 skip=1 seek=1
-    $ dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=1 count=444
+    DEV=/dev/your_sd_device
+    dd if=image.bin of=$DEV conv=fsync,notrunc
+
+If you copy the `$UBOOTDIR/odroid-c4/fip/g12a/aml_encrypt_g12a` tool somewhere
+in your path, you can omit the `BINMAN_TOOLPATHS` option. The `BINMAN_INDIRS`
+variable provides a space-seperated list of directories containing the various
+binary blobs needed by the build.
+
+To see these, look at the Binman image description in
+`arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi`.
diff --git a/tools/binman/bintools.rst b/tools/binman/bintools.rst
index edb373ab59b..7f77b7fe9dc 100644
--- a/tools/binman/bintools.rst
+++ b/tools/binman/bintools.rst
@@ -10,6 +10,30 @@ binaries. It is fairly easy to create new bintools. Just add a new file to the
 
 
 
+Bintool: aml_encrypt_g12a: Handles the 'aml_encrypt_g12a' tool
+--------------------------------------------------------------
+
+This bintool supports running `aml_encrypt_g12a` to support creation of
+Amlogic images in binman.
+
+aml_encrypt_g12a provides a way to package firmware for Amlogic devices.
+
+It is also possible to fetch a binary version of the tool.
+
+
+
+Bintool: aml_encrypt_g12b: Handles the 'aml_encrypt_g12b' tool
+--------------------------------------------------------------
+
+This bintool supports running `aml_encrypt_g12b` to support creation of
+Amlogic images in binman.
+
+aml_encrypt_g12b provides a way to package firmware for Amlogic devices.
+
+It is also possible to fetch a binary version of the tool.
+
+
+
 Bintool: cbfstool: Coreboot filesystem (CBFS) tool
 --------------------------------------------------
 
diff --git a/tools/binman/btool/_aml_common.py b/tools/binman/btool/_aml_common.py
new file mode 100644
index 00000000000..6d03cfa173e
--- /dev/null
+++ b/tools/binman/btool/_aml_common.py
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2022 Google LLC
+#
+"""Common bintool implementation for aml_encrypt_g12a/b"""
+
+import re
+
+from binman import bintool
+
+# pylint: disable=C0103
+class aml_common(bintool.Bintool):
+    """Common class for aml_encrypt_g12a/b tools"""
+    def version(self):
+        """Version handler
+
+        Returns:
+            str: Version number of tool
+        """
+        result = self.run_cmd_result('', raise_on_error=False)
+        lines = result.stdout.strip().splitlines()
+        if not lines:
+            return super().version()
+        out = lines[0]
+        # AMLOGIC-G12A-G12B-SIG-module : Ver-0.07 Built on Nov  1 2018 17:12:32
+        m_version = re.match(r'.*Ver-([^ ]*).*', out)
+        return m_version.group(1).strip() if m_version else out
+
+    def fetch(self, method):
+        """Fetch handler for aml_encrypt_g12a/b
+
+        This installs a binary version of this tool.
+
+        Args:
+            method (FETCH_...): Method to use
+
+        Returns:
+            True if the file was fetched, None if a method other than FETCH_BIN
+            was requested
+
+        Raises:
+            Valuerror: Fetching could not be completed
+        """
+        if method != bintool.FETCH_BIN:
+            return None
+        fname, tmpdir = self.fetch_from_drive(
+            '1o_OiFB5Lf9ib-nPuQDLub8OPuJ0mKIum')
+        return fname, tmpdir
diff --git a/tools/binman/btool/aml_encrypt_g12a.py b/tools/binman/btool/aml_encrypt_g12a.py
new file mode 100644
index 00000000000..112949a090a
--- /dev/null
+++ b/tools/binman/btool/aml_encrypt_g12a.py
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2022 Google LLC
+#
+"""Bintool implementation for aml_encrypt_g12a
+
+aml_encrypt_g12a provides a way to package firmware for Amlogic devices.
+
+Documentation is not really available so far as I can tell
+
+Source code also does not seem to be available, but there are some alternate
+open-source tools in C:
+
+https://github.com/afaerber/meson-tools
+    GXBB, GXL & GXM only
+https://github.com/repk/gxlimg
+    GXBB, GXL, GXM & AXG only
+https://github.com/angerman/meson64-tools
+    developed for G12B, should work on G12A & SM1
+
+Here is the help:
+
+    AMLOGIC-G12A-G12B-SIG-module : Ver-0.07 Built on Nov  1 2018 17:12:32
+
+    aml_encrypt_g12a --rsagen --keylen len --exp exp --ned rkey --nex puk
+        --nxd prk --txt tkey --aes akey
+            keylen        : RSA key length:1024,2048,4096
+            exp           : Exponent of RSA:3,0x10001,0x1374B
+            ned           : RSA key file name
+            nex           : RSA PUK file name
+            nxd           : RSA PRVK file name
+            txt           : RSA key file with text format
+            aes           : AES key file without IV,GX series used only
+            output        : signatured keymax
+
+    aml_encrypt_g12a --keysig --rkey1 rsakey [--rkey2 ..][--rkey3 ..]
+        [--rkey4 ..] --ukey1 rsakey --skey rsakey --output sig-rsa-key
+            rkey1[2,3,4]  : root RSA public key for create keymax
+            ukey1         : user RSA public key for create keymax
+            skey          : root RSA private key for signature keymax
+            output        : signatured keymax
+
+    aml_encrypt_g12a --keybnd --ukey file --rootkeymax file [--aeskey file]
+        --output file
+            ukey       : user RSA key to be used for secure boot
+            rootkeymax : signatured keymax for secure boot
+            aeskey     : AES key to be used for secure boot
+            output     : keys package for secure boot
+
+    aml_encrypt_g12a --bootsig --input file --amluserkey file --output file
+            input       : uboot image to be processed for normal or secure boot
+            amluserkey  : amlogic key package for secure boot
+            output      : signatured and encrypted uboot image
+
+    aml_encrypt_g12a --imgsig --input file --amluserkey file --output file
+            input      : image to be processed for secure boot
+            amluserkey : amlogic key package for secure boot
+            output     : signatured and encrypted kernel image
+
+    aml_encrypt_g12a --binsig --input file --amluserkey file --output file
+            input	   : binary file to be processed for secure boot
+            amluserkey : amlogic key package for secure boot
+            output	   : signatured and encrypted binary file
+
+Note that the aml_encrypt_g12a and aml_encrypt_g12b executables appear to be
+identical. Perhaps the executable name affects the behaviour?
+"""
+
+from binman.btool import _aml_common
+
+# pylint: disable=C0103
+class Bintoolaml_encrypt_g12a(_aml_common.aml_common):
+    """Handles the 'aml_encrypt_g12a' tool
+
+    This bintool supports running `aml_encrypt_g12a` to support creation of
+    Amlogic images in binman.
+
+    aml_encrypt_g12a provides a way to package firmware for Amlogic devices.
+
+    It is also possible to fetch a binary version of the tool.
+    """
+    def __init__(self, name):
+        super().__init__(name, 'Amlogic encrypt g12a')
diff --git a/tools/binman/btool/aml_encrypt_g12b.py b/tools/binman/btool/aml_encrypt_g12b.py
new file mode 100644
index 00000000000..ea5da846373
--- /dev/null
+++ b/tools/binman/btool/aml_encrypt_g12b.py
@@ -0,0 +1,83 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2022 Google LLC
+#
+"""Bintool implementation for aml_encrypt_g12b
+
+aml_encrypt_g12b provides a way to package firmware for Amlogic devices.
+
+Documentation is not really available so far as I can tell
+
+Source code also does not seem to be available, but there are some alternate
+open-source tools in C:
+
+https://github.com/afaerber/meson-tools
+    GXBB, GXL & GXM only
+https://github.com/repk/gxlimg
+    GXBB, GXL, GXM & AXG only
+https://github.com/angerman/meson64-tools
+    developed for G12B, should work on G12A & SM1
+
+Here is the help:
+
+    AMLOGIC-G12A-G12B-SIG-module : Ver-0.07 Built on Nov  1 2018 17:12:32
+
+    aml_encrypt_g12b --rsagen --keylen len --exp exp --ned rkey --nex puk
+        --nxd prk --txt tkey --aes akey
+            keylen        : RSA key length:1024,2048,4096
+            exp           : Exponent of RSA:3,0x10001,0x1374B
+            ned           : RSA key file name
+            nex           : RSA PUK file name
+            nxd           : RSA PRVK file name
+            txt           : RSA key file with text format
+            aes           : AES key file without IV,GX series used only
+            output        : signatured keymax
+
+    aml_encrypt_g12b --keysig --rkey1 rsakey [--rkey2 ..][--rkey3 ..]
+        [--rkey4 ..] --ukey1 rsakey --skey rsakey --output sig-rsa-key
+            rkey1[2,3,4]  : root RSA public key for create keymax
+            ukey1         : user RSA public key for create keymax
+            skey          : root RSA private key for signature keymax
+            output        : signatured keymax
+
+    aml_encrypt_g12b --keybnd --ukey file --rootkeymax file [--aeskey file]
+        --output file
+            ukey       : user RSA key to be used for secure boot
+            rootkeymax : signatured keymax for secure boot
+            aeskey     : AES key to be used for secure boot
+            output     : keys package for secure boot
+
+    aml_encrypt_g12b --bootsig --input file --amluserkey file --output file
+            input       : uboot image to be processed for normal or secure boot
+            amluserkey  : amlogic key package for secure boot
+            output      : signatured and encrypted uboot image
+
+    aml_encrypt_g12b --imgsig --input file --amluserkey file --output file
+            input      : image to be processed for secure boot
+            amluserkey : amlogic key package for secure boot
+            output     : signatured and encrypted kernel image
+
+    aml_encrypt_g12b --binsig --input file --amluserkey file --output file
+            input	   : binary file to be processed for secure boot
+            amluserkey : amlogic key package for secure boot
+            output	   : signatured and encrypted binary file
+
+Note that the aml_encrypt_g12a and aml_encrypt_g12b executables appear to be
+identical. Perhaps the executable name affects the behaviour?
+
+"""
+
+from binman.btool import _aml_common
+
+# pylint: disable=C0103
+class Bintoolaml_encrypt_g12b(_aml_common.aml_common):
+    """Handles the 'aml_encrypt_g12b' tool
+
+    This bintool supports running `aml_encrypt_g12b` to support creation of
+    Amlogic images in binman.
+
+    aml_encrypt_g12b provides a way to package firmware for Amlogic devices.
+
+    It is also possible to fetch a binary version of the tool.
+    """
+    def __init__(self, name):
+        super().__init__(name, 'Amlogic encrypt g12b')
diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
index c47f7df0980..0cbc3315337 100644
--- a/tools/binman/entries.rst
+++ b/tools/binman/entries.rst
@@ -11,6 +11,144 @@ features to produce new behaviours.
 
 
 
+Entry: aml-encrypt: Amlogic encryption support
+----------------------------------------------
+
+Some Amlogic chips use encryption with various firmware binaries. This
+entry supports running one of the tools to generate the required data
+formats.
+
+Available parameters are:
+
+aml-algo
+    Algorithm to use, either "g12a" or "g12b"
+
+aml-op
+    Operation to perform, one of "bootmk", "bl2sig", "bl3sig", "bl30sig"
+
+aml-level
+    Level, typically "v3"
+
+aml-compress
+    Optional compression type, e.g. "lz4"
+
+aml-type
+    Binary type to process, one of "bl30", "bl31", "bl32"
+
+The data to pass to the tool for processing is defined by an 'aml-input'
+property (for a single file) or subnode (for more flexibility). The subnode
+can be any entry type, including a section.
+
+For cases where multiple inputs are provided to one invocation of the tool,
+these are named, again using subnodes, corresponding to the tool flags.
+Available inputs are acs, bl2, bl30, sbl301, bl31, bl33 and aml-ddrfw. The
+last one is a bit different, in that it takes the form of a blob-ext-list,
+i.e. it has a 'filenames' property with a list of the DDR firmware binaries.
+
+Here is an example::
+
+    /* run --bootmk on all the included inputs */
+    aml-encrypt {
+        missing-msg = "aml-encrypt";
+        aml-algo = "g12a";
+        aml-op = "bootmk";
+        aml-level = "v3";
+
+        /* produce a bl2, containing signed bl2 binaries */
+        bl2 {
+            type = "aml-encrypt";
+            aml-algo = "g12a";
+            aml-op = "bl2sig";
+
+            /* sign the binary contaiing bl2 and acs */
+            aml-input {
+                type = "section";
+                bl2 {
+                    type = "blob-ext";
+                    size = <0xe000>;
+                    filename = "bl2.bin";
+                };
+                acs {
+                    type = "blob-ext";
+                    size = <0x1000>;
+                    filename = "acs.bin";
+                };
+            };
+        };
+
+        /* produce a bl30, containing signed bl30 binaries */
+        bl30 {
+            type = "aml-encrypt";
+            aml-algo = "g12a";
+            aml-op = "bl3sig";
+            aml-level = "v3";
+            aml-type = "bl30";
+
+            /* sign the binary contaiing bl30 and bl301 */
+            aml-input {
+                type = "aml-encrypt";
+                aml-algo = "g12a";
+                aml-op = "bl30sig";
+                aml-level = "v3";
+
+                /*
+                 * put bl30 and bl301 together, with
+                 * the necessary paddiung
+                 */
+                aml-input {
+                    type = "section";
+                    bl30 {
+                        type = "blob-ext";
+                        size = <0xa000>;
+                        filename = "bl30.bin";
+                    };
+                    bl301 {
+                        type = "blob-ext";
+                        size = <0x3400>;
+                        filename = "bl301.bin";
+                    };
+                };
+            };
+        };
+
+        /* sign the bl31 binary */
+        bl31 {
+            type = "aml-encrypt";
+            aml-algo = "g12a";
+            aml-op = "bl3sig";
+            aml-input = "bl31.img";
+            aml-level = "v3";
+            aml-type = "bl31";
+        };
+
+        /* sign the bl33 binary (which is U-Boot) */
+        bl33 {
+            type = "aml-encrypt";
+            aml-algo = "g12a";
+            aml-op = "bl3sig";
+            aml-compress = "lz4";
+            aml-level = "v3";
+            aml-type = "bl33";
+
+            aml-input {
+                type = "u-boot";
+            };
+        };
+
+        /* add the various DDR blobs */
+        aml-ddrfw {
+            missing-msg = "aml-ddrfw";
+            type = "blob-ext-list";
+            filenames = "ddr4_1d.fw", "ddr4_2d.fw",
+                "ddr3_1d.fw", "piei.fw",
+                "lpddr4_1d.fw", "lpddr4_2d.fw",
+                "diag_lpddr4.fw", "aml_ddr.fw",
+                "lpddr3_1d.fw";
+        };
+    };
+
+
+
 Entry: atf-bl31: ARM Trusted Firmware (ATF) BL31 blob
 -----------------------------------------------------
 
diff --git a/tools/binman/etype/aml_encrypt.py b/tools/binman/etype/aml_encrypt.py
new file mode 100644
index 00000000000..e9651abc416
--- /dev/null
+++ b/tools/binman/etype/aml_encrypt.py
@@ -0,0 +1,262 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2016 Google, Inc
+# Written by Simon Glass <sjg at chromium.org>
+#
+# Entry-type module for producing an image using aml-encrypt-g12a
+#
+
+from collections import OrderedDict
+
+from binman.entry import Entry
+from binman.etype.section import Entry_section
+from binman.etype.blob_ext import Entry_blob_ext
+from binman.etype.blob_ext_list import Entry_blob_ext_list
+from dtoc import fdt_util
+from patman import tools
+from patman import tout
+
+DDR_FW_COUNT = 9
+
+class Entry_aml_encrypt(Entry_section):
+    """Amlogic encryption support
+
+    Some Amlogic chips use encryption with various firmware binaries. This
+    entry supports running one of the tools to generate the required data
+    formats.
+
+    Available parameters are:
+
+    aml-algo
+        Algorithm to use, either "g12a" or "g12b"
+
+    aml-op
+        Operation to perform, one of "bootmk", "bl2sig", "bl3sig", "bl30sig"
+
+    aml-level
+        Level, typically "v3"
+
+    aml-compress
+        Optional compression type, e.g. "lz4"
+
+    aml-type
+        Binary type to process, one of "bl30", "bl31", "bl32"
+
+    The data to pass to the tool for processing is defined by an 'aml-input'
+    property (for a single file) or subnode (for more flexibility). The subnode
+    can be any entry type, including a section.
+
+    For cases where multiple inputs are provided to one invocation of the tool,
+    these are named, again using subnodes, corresponding to the tool flags.
+    Available inputs are acs, bl2, bl30, sbl301, bl31, bl33 and aml-ddrfw. The
+    last one is a bit different, in that it takes the form of a blob-ext-list,
+    i.e. it has a 'filenames' property with a list of the DDR firmware binaries.
+
+    Here is an example::
+
+        /* run --bootmk on all the included inputs */
+        aml-encrypt {
+            missing-msg = "aml-encrypt";
+            aml-algo = "g12a";
+            aml-op = "bootmk";
+            aml-level = "v3";
+
+            /* produce a bl2, containing signed bl2 binaries */
+            bl2 {
+                type = "aml-encrypt";
+                aml-algo = "g12a";
+                aml-op = "bl2sig";
+
+                /* sign the binary contaiing bl2 and acs */
+                aml-input {
+                    type = "section";
+                    bl2 {
+                        type = "blob-ext";
+                        size = <0xe000>;
+                        filename = "bl2.bin";
+                    };
+                    acs {
+                        type = "blob-ext";
+                        size = <0x1000>;
+                        filename = "acs.bin";
+                    };
+                };
+            };
+
+            /* produce a bl30, containing signed bl30 binaries */
+            bl30 {
+                type = "aml-encrypt";
+                aml-algo = "g12a";
+                aml-op = "bl3sig";
+                aml-level = "v3";
+                aml-type = "bl30";
+
+                /* sign the binary contaiing bl30 and bl301 */
+                aml-input {
+                    type = "aml-encrypt";
+                    aml-algo = "g12a";
+                    aml-op = "bl30sig";
+                    aml-level = "v3";
+
+                    /*
+                     * put bl30 and bl301 together, with
+                     * the necessary paddiung
+                     */
+                    aml-input {
+                        type = "section";
+                        bl30 {
+                            type = "blob-ext";
+                            size = <0xa000>;
+                            filename = "bl30.bin";
+                        };
+                        bl301 {
+                            type = "blob-ext";
+                            size = <0x3400>;
+                            filename = "bl301.bin";
+                        };
+                    };
+                };
+            };
+
+            /* sign the bl31 binary */
+            bl31 {
+                type = "aml-encrypt";
+                aml-algo = "g12a";
+                aml-op = "bl3sig";
+                aml-input = "bl31.img";
+                aml-level = "v3";
+                aml-type = "bl31";
+            };
+
+            /* sign the bl33 binary (which is U-Boot) */
+            bl33 {
+                type = "aml-encrypt";
+                aml-algo = "g12a";
+                aml-op = "bl3sig";
+                aml-compress = "lz4";
+                aml-level = "v3";
+                aml-type = "bl33";
+
+                aml-input {
+                    type = "u-boot";
+                };
+            };
+
+            /* add the various DDR blobs */
+            aml-ddrfw {
+                missing-msg = "aml-ddrfw";
+                type = "blob-ext-list";
+                filenames = "ddr4_1d.fw", "ddr4_2d.fw",
+                    "ddr3_1d.fw", "piei.fw",
+                    "lpddr4_1d.fw", "lpddr4_2d.fw",
+                    "diag_lpddr4.fw", "aml_ddr.fw",
+                    "lpddr3_1d.fw";
+            };
+        };
+    """
+    def __init__(self, section, etype, node):
+        super().__init__(section, etype, node)
+        self._entries = OrderedDict()
+        self.align_default = None
+        self._aml_algo = None
+        self._aml_op = None
+        self._aml_level = None
+        self.g12a = None
+        self.g12b = None
+
+    def ReadNode(self):
+        super().ReadNode()
+        self._aml_algo = fdt_util.GetString(self._node, 'aml-algo')
+        self._aml_op = fdt_util.GetString(self._node, 'aml-op')
+        self._aml_level = fdt_util.GetString(self._node, 'aml-level')
+        self._aml_input = fdt_util.GetString(self._node, 'aml-input')
+        self._aml_compress = fdt_util.GetString(self._node, 'aml-compress')
+        self._aml_type = fdt_util.GetString(self._node, 'aml-type')
+        self.ReadEntries()
+
+    def ReadEntries(self):
+        """Read the subnodes to find out what should go in this image"""
+        for node in self._node.subnodes:
+            etype = None
+            if node.name.startswith('aml-') and 'type' not in node.props:
+                etype = 'blob-ext'
+            entry = Entry.Create(self, node, etype)
+            entry.ReadNode()
+            self._entries[entry.name] = entry
+
+    def BuildSectionData(self, required):
+        uniq = self.GetUniqueName()
+        output_fname = tools.GetOutputFilename('aml-out.%s' % uniq)
+        args = [f'--{self._aml_op}', '--output', output_fname]
+        if self._aml_level:
+            args += ['--level', f'{self._aml_level}']
+        if self._aml_compress:
+            args += ['--compress', f'{self._aml_compress}']
+        if self._aml_type:
+            args += ['--type', f'{self._aml_type}']
+        if self._aml_input:
+            input_pathname = tools.GetInputFilename(
+                self._aml_input,
+                self.section.GetAllowMissing())
+            if not input_pathname:
+                missing = True
+                input_pathname = self.check_fake_fname(self._aml_input)
+            args += ['--input', f'{input_pathname}']
+
+        missing = False
+        for entry in self._entries.values():
+            # First get the input data and put it in a file. If not available,
+            # try later.
+            entry_data = entry.GetData(required)
+            if not required and entry_data is None:
+                return None
+            flag_name = entry.name.replace('aml-', '')  # Drop the aml- prefix
+            if isinstance(entry, Entry_blob_ext_list):
+                for i, pathname in enumerate(entry._pathnames):
+                    args += [f'--{flag_name}{i + 1}', pathname]
+            elif isinstance(entry, Entry_blob_ext):
+                pathname = entry._pathname
+                args += [f'--{flag_name}', pathname]
+            else:
+                data = self.GetPaddedDataForEntry(entry, entry_data)
+                fname = tools.GetOutputFilename('aml-in.%s' %
+                                                entry.GetUniqueName())
+                tools.WriteFile(fname, data)
+                args += [f'--{flag_name}', fname]
+            if entry.missing:
+                missing = True
+
+        if missing:
+            self.missing = True
+            return b''
+
+        tout.Debug(f"Node '{self._node.path}': running: %s" % ' '.join(args))
+        to_run = self.g12a if self._aml_algo == 'g12a' else self.g12b
+
+        out = to_run.run_cmd(*args)
+
+        # If an input file (or subnode!) is providing the input, the tools
+        # writes to the requested output file. Otherwise it uses the output file
+        # as a template for three files that it writes, ending in '.sd.bin',
+        # 'usb.bl2' and 'usb.tpl'. We use the first one as the image output
+        if self._aml_input or self._node.FindNode('aml-input'):
+            real_outfile = output_fname
+        else:
+            real_outfile = f'{output_fname}.sd.bin'
+        if out is not None:
+            data = tools.ReadFile(real_outfile)
+        else:
+            data = tools.GetBytes(0, 1024)
+        return data
+
+    def SetImagePos(self, image_pos):
+        Entry.SetImagePos(self, image_pos)
+
+    def SetCalculatedProperties(self):
+        Entry.SetCalculatedProperties(self)
+
+    def CheckEntries(self):
+        Entry.CheckEntries(self)
+
+    def AddBintools(self, tools):
+        self.g12a = self.AddBintool(tools, 'aml_encrypt_g12a')
+        self.g12b = self.AddBintool(tools, 'aml_encrypt_g12b')
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index ca200ae9f8f..c9aac143bf8 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -5100,6 +5100,15 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
         self.assertIn('Documentation is missing for modules: mkimage',
                       str(e.exception))
 
+    def testAmlEncrypt(self):
+        with test_util.capture_sys_output() as (_, stderr):
+            self._DoTestFile('213_aml_encrypt.dts', allow_missing=True,
+                                allow_fake_blobs=True)
+        err = stderr.getvalue()
+        self.assertRegex(
+            err,
+            "Image '.*' has faked external blobs and is non-functional: .*")
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/tools/binman/missing-blob-help b/tools/binman/missing-blob-help
index 551ca87f6cb..d58f954eae8 100644
--- a/tools/binman/missing-blob-help
+++ b/tools/binman/missing-blob-help
@@ -33,3 +33,9 @@ k3-rti-wdt-firmware:
 If CONFIG_WDT_K3_RTI_LOAD_FW is enabled, a firmware image is needed for
 the R5F core(s) to trigger the system reset. One possible source is
 https://github.com/siemens/k3-rti-wdt.
+
+aml-encrypt:
+Some AML messages
+
+aml-ddrfw
+Amlogic DDR firmware files are missing
diff --git a/tools/binman/test/213_aml_encrypt.dts b/tools/binman/test/213_aml_encrypt.dts
new file mode 100644
index 00000000000..f97e23b0e40
--- /dev/null
+++ b/tools/binman/test/213_aml_encrypt.dts
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		aml-encrypt {
+			missing-msg = "aml-encrypt";
+			aml-algo = "g12a";
+			aml-op = "bootmk";
+			aml-level = "v3";
+			aml-compress = "lz4";
+			aml-type = "bl30";
+
+			aml-bl2 {
+				filename = "bl2.n.bin.sig";
+			};
+			aml-bl30 {
+				filename = "bl30_new.bin.enc";
+			};
+			aml-bl31 {
+				filename = "bl31.img.enc";
+			};
+			aml-bl33 {
+				type = "_testing";
+				return-contents-later;
+			};
+			aml-ddrfw {
+				missing-msg = "aml-ddrfw";
+				type = "blob-ext-list";
+				filenames = "ddr4_1d.fw", "ddr4_2d.fw",
+					"ddr3_1d.fw", "piei.fw",
+					"lpddr4_1d.fw", "lpddr4_2d.fw",
+					"diag_lpddr4.fw", "aml_ddr.fw",
+					"lpddr3_1d.fw";
+			};
+		};
+
+		bl31 {
+			type = "aml-encrypt";
+			aml-algo = "g12a";
+			aml-op = "bl3sig";
+			aml-input = "bl31.img";
+			aml-level = "v3";
+			aml-type = "bl31";
+		};
+
+	};
+};
diff --git a/tools/binman/test/214_list_no_dtb.dts b/tools/binman/test/214_list_no_dtb.dts
new file mode 100644
index 00000000000..47ecd058644
--- /dev/null
+++ b/tools/binman/test/214_list_no_dtb.dts
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		size = <0x300>;
+		atf-bl31 {
+			filename = "bl31.bin";
+		};
+		scp {
+			filename = "scp.bin";
+		};
+		fdtmap {
+		};
+		image-header {
+			location = "end";
+		};
+	};
+};
-- 
2.34.1.575.g55b058a8bb-goog



More information about the U-Boot mailing list