[PATCH 4/4] rockchip: binman: Add support for Falcon mode FIT images with ATF+Linux

Jonas Karlman jonas at kwiboo.se
Tue Jun 9 19:54:50 CEST 2026


Hi Alexey,

On 6/9/2026 6:52 PM, Alexey Charkov wrote:
> Modern Rockchip SoCs such as RK3576 require ATF to be running to provide
> firmware services to the OS. To enable booting Linux in Falcon mode on
> such SoCs, add binman support for generation of FIT images containing
> appropriately split ATF raw binaries (as is currently done by binman for
> U-boot proper images), externally preprocessed DTB and a Linux kernel.
> 
> Signed-off-by: Alexey Charkov <alchark at flipper.net>
> ---
>  Makefile                           |   2 +
>  arch/arm/dts/rockchip-u-boot.dtsi  | 109 +++++++++++++++++++++++++++++++++++++
>  tools/binman/etype/falcon_fdt.py   |  26 +++++++++
>  tools/binman/etype/linux_kernel.py |  22 ++++++++
>  4 files changed, 159 insertions(+)
> 
> diff --git a/Makefile b/Makefile
> index 4e5c1dd6a1c4..844e5adb7b31 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1690,6 +1690,8 @@ cmd_binman = $(srctree)/tools/binman/binman $(if $(BINMAN_DEBUG),-D) \
>  		$(foreach f,$(BINMAN_INDIRS),-I $(f)) \
>  		-a atf-bl1-path=${BL1} \
>  		-a atf-bl31-path=${BL31} \
> +		-a linux-kernel-path=${LINUX_KERNEL} \
> +		-a falcon-fdt-path=${FALCON_FDT} \
>  		-a tee-os-path=${TEE} \
>  		-a ti-dm-path=${TI_DM} \
>  		-a opensbi-path=${OPENSBI} \
> diff --git a/arch/arm/dts/rockchip-u-boot.dtsi b/arch/arm/dts/rockchip-u-boot.dtsi
> index 4ba6a87e78ab..866a6ab654ca 100644
> --- a/arch/arm/dts/rockchip-u-boot.dtsi
> +++ b/arch/arm/dts/rockchip-u-boot.dtsi
> @@ -161,6 +161,96 @@
>  			};
>  		};
>  	};
> +
> +#ifdef CONFIG_SPL_OS_BOOT
> +	fit_falcon_template: template-falcon {

Not sure it is possible, but this looks to add lots of duplicated
content. Could we try to re-use more, e.g. is it possible to extract
@atf-SEQ, and I also think we may want to support loading of TEE-OS?

> +		type = "fit";
> +		description = "FIT image for Falcon Linux with bl31 (TF-A)";
> +		#address-cells = <1>;
> +		fit,fdt-list-val = "u-boot";
> +		fit,external-offset = <CONFIG_FIT_EXTERNAL_OFFSET>;
> +		fit,align = <512>;
> +
> +		images {
> +			@atf-SEQ {
> +				fit,operation = "split-elf";
> +				description = "ARM Trusted Firmware";
> +				type = "firmware";
> +				arch = FIT_ARCH;
> +				os = "arm-trusted-firmware";
> +				compression = "none";
> +				fit,load;
> +				fit,entry;
> +				fit,data;
> +
> +				atf-bl31 {
> +				};
> +#ifdef FIT_HASH_ALGO
> +				hash {
> +					algo = FIT_HASH_ALGO;
> +				};
> +#endif
> +			};
> +
> +			kernel {
> +				description = "Linux kernel";
> +				type = "kernel";
> +				arch = FIT_ARCH;
> +				os = "linux";
> +				compression = "none";
> +				load = <0x48000000>;
> +				entry = <0x48000000>;

We should not hard-code these here, they seem to be RK3576 specific.

> +
> +				linux-kernel {
> +				};
> +#ifdef FIT_HASH_ALGO
> +				hash {
> +					algo = FIT_HASH_ALGO;
> +				};
> +#endif
> +			};
> +
> +			fdt-1 {
> +				description = "falcon-fdt";
> +				type = "flat_dt";
> +				arch = FIT_ARCH;
> +				compression = "none";
> +				load = <0x52000000>;

Same here.

> +
> +				falcon-fdt {
> +				};

If I am not mistaken we can already inject an external DT to be used as
control fdt during U-Boot build using EXT_DTB env, maybe it is better to
use that instead of passing in a new FDT?

We probably also want to use @fdt-SEQ and @config-SEQ to be able to
dynamically load a config based on e.g. board_fit_config_name_match()
that some boards already use to select config/fdt for U-Boot proper.

> +#ifdef FIT_HASH_ALGO
> +				hash {
> +					algo = FIT_HASH_ALGO;
> +				};
> +#endif
> +			};
> +		};
> +
> +		configurations {
> +			default = "config-1";
> +			@config-SEQ {
> +				description = "RK3576 Falcon Linux via ATF";

This is rockchip-u-boot.dtsi, drop RK3576 specific parts :-)

> +				fit,firmware = "atf-1", "kernel";
> +				fit,loadables;
> +				fdt = "fdt-SEQ";
> +#ifdef FIT_HASH_ALGO
> +				hash {
> +					algo = FIT_HASH_ALGO;
> +				};
> +#endif
> +			};
> +		};
> +	};
> +
> +	falcon-fit {
> +		filename = "u-boot-rockchip-falcon.itb";

Do we need to export this file? the old .itb-file is exported because
some distro build scripts or flash instructions still use the older
files instead of the preferred u-boot-rockchip.bin.

> +
> +		fit {
> +			insert-template = <&fit_falcon_template>;
> +		};
> +	};
> +#endif
>  #endif /* HAS_FIT */
>  
>  	simple-bin {
> @@ -260,6 +350,25 @@
>  		};
>  		};
>  	};
> +
> +#ifdef CONFIG_SPL_OS_BOOT
> +	simple-bin-usb472-falcon {

Do we really need this? As you notice the BootROM loader is not really
optimized for large payloads, I thought using a 1-2 MiB payload with
TF-A + U-Boot proper was stretching it, sending a full Linux kernel seem
like a big stretch, as evidenced by the 6 minute load time?

> +		filename = "u-boot-rockchip-usb472-falcon.bin";
> +		pad-byte = <0x00>;
> +
> +		u-boot-spl {
> +		};
> +
> +		payload {
> +			type = "section";
> +			align = <CONFIG_SYS_CACHELINE_SIZE>;

nit: blank line between props and nodes.

> +			u-boot-any {
> +				type = "fit";
> +				insert-template = <&fit_falcon_template>;
> +			};
> +		};
> +	};
> +#endif
>  #endif /* CONFIG_ROCKCHIP_MASKROM_IMAGE */
>  };
>  #endif /* CONFIG_SPL */
> diff --git a/tools/binman/etype/falcon_fdt.py b/tools/binman/etype/falcon_fdt.py
> new file mode 100644
> index 000000000000..7c5b13b60d05
> --- /dev/null
> +++ b/tools/binman/etype/falcon_fdt.py
> @@ -0,0 +1,26 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +# Copyright (c) 2026 Flipper FZCO
> +#
> +# Entry type for Linux DTB used in Falcon mode FIT images.
> +
> +from binman.etype.blob_named_by_arg import Entry_blob_named_by_arg
> +
> +
> +class Entry_falcon_fdt(Entry_blob_named_by_arg):
> +    """Falcon Linux DTB for Rockchip maskrom Falcon image
> +
> +    Properties / Entry arguments:
> +        - falcon-fdt-path: Filename containing the Falcon Linux DTB (optional,
> +            defaults to 'u-boot.dtb')
> +
> +    This allows selecting the Falcon DTB from an environment variable passed
> +    through binman entry arguments, while defaulting to the built U-Boot
> +    control DTB when not provided.
> +    """
> +
> +    def __init__(self, section, etype, node):
> +        super().__init__(section, etype, node, 'falcon-fdt')
> +        # Entry_blob defaults filename to etype when no filename is provided.
> +        # Treat that as "unset" and fall back to the control DTB.
> +        if not self._filename or self._filename == self.etype:
> +            self._filename = 'u-boot.dtb'
> diff --git a/tools/binman/etype/linux_kernel.py b/tools/binman/etype/linux_kernel.py
> new file mode 100644
> index 000000000000..15a1da690c4f
> --- /dev/null
> +++ b/tools/binman/etype/linux_kernel.py
> @@ -0,0 +1,22 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +# Copyright (c) 2026 Flipper FZCO
> +#
> +# Entry-type module for Linux kernel binary blob
> +
> +from binman.etype.blob_named_by_arg import Entry_blob_named_by_arg
> +
> +
> +class Entry_linux_kernel(Entry_blob_named_by_arg):
> +    """Linux kernel image blob
> +
> +    Properties / Entry arguments:
> +        - linux-kernel-path: Filename of file to read into entry. This is
> +            typically an uncompressed ARM64 Image.
> +
> +    This entry allows binman FIT templates to consume a kernel provided via
> +    make variable, similar to how BL31 is passed to atf-bl31.
> +    """
> +
> +    def __init__(self, section, etype, node):
> +        super().__init__(section, etype, node, 'linux-kernel', required=True)
> +        self.external = True
> 

New binman etypes require new tests for 100% code coverage.

Also do we need to update Rockchip documentation to cover Falcon mode?

Regards,
Jonas


More information about the U-Boot mailing list