diff mbox series

[7/7] RFC: Move Odroid-C2 to use binman to produce the image

Message ID 20211124040954.699821-8-sjg@chromium.org
State RFC
Delegated to: Simon Glass
Headers show
Series meson: Demonstration of using binman to produce the image | expand

Commit Message

Simon Glass Nov. 24, 2021, 4:09 a.m. UTC
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@chromium.org>
---

 arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi | 107 ++++++++++++++++
 arch/arm/mach-meson/Kconfig                  |   1 +
 doc/board/amlogic/odroid-c4.rst              | 127 +++++--------------
 scripts/pylint.base                          |   1 +
 tools/binman/etype/aml_encrypt.py            | 124 ++++++++++++++++++
 tools/binman/ftest.py                        |   3 +
 tools/binman/missing-blob-help               |   6 +
 tools/binman/test/213_aml_encrypt.dts        |  38 ++++++
 tools/binman/test/214_list_no_dtb.dts        |  23 ++++
 9 files changed, 338 insertions(+), 92 deletions(-)
 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

Comments

Neil Armstrong Nov. 24, 2021, 2:26 p.m. UTC | #1
Hi Simon,

On 24/11/2021 05:09, Simon Glass wrote:
> 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.

Thanks for demonstarting that !

I'm really not confident about using proprietary tools from mainline u-boot
source tree.

Will the binman step quietly fail if tools/bins aren't available ?

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

--------------------------------------------------- C4

But i get the spirit !

Seems it should work as-is on allmost all boards except Odroid-C2 which has
only pre-signed binaries provided by HK.

The only work will be to replace acs_tool.py for pre-G12 SoCs.

> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> 
>  arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi | 107 ++++++++++++++++
>  arch/arm/mach-meson/Kconfig                  |   1 +
>  doc/board/amlogic/odroid-c4.rst              | 127 +++++--------------
>  scripts/pylint.base                          |   1 +
>  tools/binman/etype/aml_encrypt.py            | 124 ++++++++++++++++++
>  tools/binman/ftest.py                        |   3 +
>  tools/binman/missing-blob-help               |   6 +
>  tools/binman/test/213_aml_encrypt.dts        |  38 ++++++
>  tools/binman/test/214_list_no_dtb.dts        |  23 ++++
>  9 files changed, 338 insertions(+), 92 deletions(-)
>  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";
> +					};
> +				};

This is nice way to get rid of blx_fix.sh !

> +			};
> +
> +			/* 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/scripts/pylint.base b/scripts/pylint.base
> index 1b320e421e3..2331ecd51e4 100644
> --- a/scripts/pylint.base
> +++ b/scripts/pylint.base
> @@ -1,4 +1,5 @@
>  _testing 0.83
> +aml_encrypt 2.71
>  atf_bl31 -6.00
>  atf_fip 0.44
>  binman.cbfs_util 7.70
> diff --git a/tools/binman/etype/aml_encrypt.py b/tools/binman/etype/aml_encrypt.py
> new file mode 100644
> index 00000000000..3f570702dc5
> --- /dev/null
> +++ b/tools/binman/etype/aml_encrypt.py
> @@ -0,0 +1,124 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +# Copyright (c) 2016 Google, Inc
> +# Written by Simon Glass <sjg@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):
> +    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
> +
> +    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._aml_ddrfw = {}
> +        #for i in range(1, DDR_FW_COUNT + 1):
> +            #self._aml_ddrfw[i] = fdt_util.GetString(self._node, f'aml-ddrfw{i}')
> +        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'aml_encrypt_{self._aml_algo}',
> +            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.external and self.section.GetAllowMissing())
> +            if not input_pathname:
> +                missing = True
> +            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))
> +        tools.Run(*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'
> +        data = tools.ReadFile(real_outfile)
> +        return data
> +
> +    def SetAllowMissing(self, allow_missing):
> +        self.allow_missing = allow_missing
> +
> +    def SetImagePos(self, image_pos):
> +        Entry.SetImagePos(self, image_pos)
> +
> +    def SetCalculatedProperties(self):
> +        Entry.SetCalculatedProperties(self)
> +
> +    def CheckEntries(self):
> +        Entry.CheckEntries(self)
> diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
> index acbe107d6ae..b05ff10ee5a 100644
> --- a/tools/binman/ftest.py
> +++ b/tools/binman/ftest.py
> @@ -4952,6 +4952,9 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
>          err = stderr.getvalue()
>          self.assertRegex(err, "Image 'main-section'.*missing.*: blob-ext")
>  
> +    def testAmlEncrypt(self):
> +        self._DoTestFile('213_aml_encrypt.dts', allow_missing=True)
> +
>  
>  if __name__ == "__main__":
>      unittest.main()
> diff --git a/tools/binman/missing-blob-help b/tools/binman/missing-blob-help
> index dc2d9c98111..849004adc00 100644
> --- a/tools/binman/missing-blob-help
> +++ b/tools/binman/missing-blob-help
> @@ -22,3 +22,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..513da65d500
> --- /dev/null
> +++ b/tools/binman/test/213_aml_encrypt.dts
> @@ -0,0 +1,38 @@
> +// 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-bl2 {
> +				filename = "bl2.n.bin.sig";
> +			};
> +			aml-bl30 {
> +				filename = "bl30_new.bin.enc";
> +			};
> +			aml-bl31 {
> +				filename = "bl31.img.enc";
> +			};
> +			aml-bl33 {
> +				filename = "bl33.bin.enc";
> +			};
> +			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";
> +			};
> +		};
> +	};
> +};
> 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";
> +		};
> +	};
> +};
>
Simon Glass Nov. 25, 2021, 12:12 a.m. UTC | #2
Hi Neil,

On Wed, 24 Nov 2021 at 07:26, Neil Armstrong <narmstrong@baylibre.com> wrote:
>
> Hi Simon,
>
> On 24/11/2021 05:09, Simon Glass wrote:
> > 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.
>
> Thanks for demonstarting that !

Thanks for looking at it.

>
> I'm really not confident about using proprietary tools from mainline u-boot
> source tree.

Arguably people already are doing this. At least this way it is in the
open. If people have the right tools installed it will just work, with
no extra steps.

>
> Will the binman step quietly fail if tools/bins aren't available ?

It handles the case where binaries are missing (that's the
--allow-missing) but not tools. I think we can do a similar thing,
where it just warns that the image won't work because of a missing
tool.

When a blob is missing there are instructions to tell the user how to
create it. For tools we could have instructions on where to download
the tool.

Is someone working on upstreaming the tools?

>
> > It needs some tidying up and only supports Odroid-C2 at present.
>
> --------------------------------------------------- C4
>
> But i get the spirit !
>
> Seems it should work as-is on allmost all boards except Odroid-C2 which has
> only pre-signed binaries provided by HK.

OK. There are a lot of instructions in doc/board/amlogic - are they
all mostly the same If so we can use a common binman description for
all boards.

>
> The only work will be to replace acs_tool.py for pre-G12 SoCs.
>
> >
> > Signed-off-by: Simon Glass <sjg@chromium.org>
> > ---
> >
> >  arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi | 107 ++++++++++++++++
> >  arch/arm/mach-meson/Kconfig                  |   1 +
> >  doc/board/amlogic/odroid-c4.rst              | 127 +++++--------------
> >  scripts/pylint.base                          |   1 +
> >  tools/binman/etype/aml_encrypt.py            | 124 ++++++++++++++++++
> >  tools/binman/ftest.py                        |   3 +
> >  tools/binman/missing-blob-help               |   6 +
> >  tools/binman/test/213_aml_encrypt.dts        |  38 ++++++
> >  tools/binman/test/214_list_no_dtb.dts        |  23 ++++
> >  9 files changed, 338 insertions(+), 92 deletions(-)
> >  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";
> > +                                     };
> > +                             };
>
> This is nice way to get rid of blx_fix.sh !

Yes that sort of thing is easy with Binman.

>
> > +                     };
> > +
> > +                     /* 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
> > -

[..]

Regards,
Simon
Neil Armstrong Nov. 25, 2021, 8:31 a.m. UTC | #3
On 25/11/2021 01:12, Simon Glass wrote:
> Hi Neil,
> 
> On Wed, 24 Nov 2021 at 07:26, Neil Armstrong <narmstrong@baylibre.com> wrote:
>>
>> Hi Simon,
>>
>> On 24/11/2021 05:09, Simon Glass wrote:
>>> 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.
>>
>> Thanks for demonstarting that !
> 
> Thanks for looking at it.
> 
>>
>> I'm really not confident about using proprietary tools from mainline u-boot
>> source tree.
> 
> Arguably people already are doing this. At least this way it is in the
> open. If people have the right tools installed it will just work, with
> no extra steps.

OK, no problem then

> 
>>
>> Will the binman step quietly fail if tools/bins aren't available ?
> 
> It handles the case where binaries are missing (that's the
> --allow-missing) but not tools. I think we can do a similar thing,
> where it just warns that the image won't work because of a missing
> tool.
> 
> When a blob is missing there are instructions to tell the user how to
> create it. For tools we could have instructions on where to download
> the tool.

Is there a easy way to bypass the binman step ? In case for example we
want to chainload the original u-boot binary, or wrap it using other
tools afterwards like for secure boot ?

> 
> Is someone working on upstreaming the tools?

There is 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)

But no unified tool, all this should probably be rewritten in a binman plugin at some point.

> 
>>
>>> It needs some tidying up and only supports Odroid-C2 at present.
>>
>> --------------------------------------------------- C4
>>
>> But i get the spirit !
>>
>> Seems it should work as-is on allmost all boards except Odroid-C2 which has
>> only pre-signed binaries provided by HK.
> 
> OK. There are a lot of instructions in doc/board/amlogic - are they
> all mostly the same If so we can use a common binman description for
> all boards.
> 
>>
>> The only work will be to replace acs_tool.py for pre-G12 SoCs.
>>
>>>
>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>> ---
>>>
>>>  arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi | 107 ++++++++++++++++
>>>  arch/arm/mach-meson/Kconfig                  |   1 +
>>>  doc/board/amlogic/odroid-c4.rst              | 127 +++++--------------
>>>  scripts/pylint.base                          |   1 +
>>>  tools/binman/etype/aml_encrypt.py            | 124 ++++++++++++++++++
>>>  tools/binman/ftest.py                        |   3 +
>>>  tools/binman/missing-blob-help               |   6 +
>>>  tools/binman/test/213_aml_encrypt.dts        |  38 ++++++
>>>  tools/binman/test/214_list_no_dtb.dts        |  23 ++++
>>>  9 files changed, 338 insertions(+), 92 deletions(-)
>>>  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";
>>> +                                     };
>>> +                             };
>>
>> This is nice way to get rid of blx_fix.sh !
> 
> Yes that sort of thing is easy with Binman.
> 
>>
>>> +                     };
>>> +
>>> +                     /* 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
>>> -
> 
> [..]
> 
> Regards,
> Simon
>
diff mbox series

Patch

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/scripts/pylint.base b/scripts/pylint.base
index 1b320e421e3..2331ecd51e4 100644
--- a/scripts/pylint.base
+++ b/scripts/pylint.base
@@ -1,4 +1,5 @@ 
 _testing 0.83
+aml_encrypt 2.71
 atf_bl31 -6.00
 atf_fip 0.44
 binman.cbfs_util 7.70
diff --git a/tools/binman/etype/aml_encrypt.py b/tools/binman/etype/aml_encrypt.py
new file mode 100644
index 00000000000..3f570702dc5
--- /dev/null
+++ b/tools/binman/etype/aml_encrypt.py
@@ -0,0 +1,124 @@ 
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2016 Google, Inc
+# Written by Simon Glass <sjg@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):
+    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
+
+    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._aml_ddrfw = {}
+        #for i in range(1, DDR_FW_COUNT + 1):
+            #self._aml_ddrfw[i] = fdt_util.GetString(self._node, f'aml-ddrfw{i}')
+        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'aml_encrypt_{self._aml_algo}',
+            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.external and self.section.GetAllowMissing())
+            if not input_pathname:
+                missing = True
+            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))
+        tools.Run(*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'
+        data = tools.ReadFile(real_outfile)
+        return data
+
+    def SetAllowMissing(self, allow_missing):
+        self.allow_missing = allow_missing
+
+    def SetImagePos(self, image_pos):
+        Entry.SetImagePos(self, image_pos)
+
+    def SetCalculatedProperties(self):
+        Entry.SetCalculatedProperties(self)
+
+    def CheckEntries(self):
+        Entry.CheckEntries(self)
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index acbe107d6ae..b05ff10ee5a 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -4952,6 +4952,9 @@  fdt         fdtmap                Extract the devicetree blob from the fdtmap
         err = stderr.getvalue()
         self.assertRegex(err, "Image 'main-section'.*missing.*: blob-ext")
 
+    def testAmlEncrypt(self):
+        self._DoTestFile('213_aml_encrypt.dts', allow_missing=True)
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/tools/binman/missing-blob-help b/tools/binman/missing-blob-help
index dc2d9c98111..849004adc00 100644
--- a/tools/binman/missing-blob-help
+++ b/tools/binman/missing-blob-help
@@ -22,3 +22,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..513da65d500
--- /dev/null
+++ b/tools/binman/test/213_aml_encrypt.dts
@@ -0,0 +1,38 @@ 
+// 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-bl2 {
+				filename = "bl2.n.bin.sig";
+			};
+			aml-bl30 {
+				filename = "bl30_new.bin.enc";
+			};
+			aml-bl31 {
+				filename = "bl31.img.enc";
+			};
+			aml-bl33 {
+				filename = "bl33.bin.enc";
+			};
+			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";
+			};
+		};
+	};
+};
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";
+		};
+	};
+};