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 <s...@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 { > + }; > + }; > +}; > + > ðmac { > 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 <s...@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"; > + }; > + }; > +}; >