Re: [PATCH 2/3] image: Add support for starting TFA BL31 as fitImage loadables

Marek Vasut
2025-01-29T17:38:48Z

On 1/29/25 6:10 PM, Quentin Schulz wrote:
> Hi Marek,

Hi,

> On 1/12/25 11:36 PM, Marek Vasut wrote:
>> Add support for starting TFA from U-Boot running in EL3 as part of
>> fitImage boot, so the user can start U-Boot in the highest privilege
>> level on the platform, bundle TFA, Linux, DT into a single fitImage
>> and boot such a bundle as a whole.
>>
>> There are two main benefits of this approach. First is the ability
>> to run U-Boot in EL3, where it has unrestricted access to the entire
>> system and can act as a useful debug tool, as it was always intended
>> to be used. Second is the ability to easily and safely update of any
>> component in the fitImage, be it TFA, Linux or DT.
>>
>> The boot process is similar to regular Linux with DT fitImage boot
>> process, except the TFA has to be bundled into the fitImage. For the
>> bundling instructions, see below. The TFA is started as a 'loadables'
>> with custom U_BOOT_FIT_LOADABLE_HANDLER and armv8_switch_to_el2_prep()
>> handling implemented in board code, and performing the handoff and
>> boot in case the TFA was loaded.
>>
>> The loadables handler is optional and meant to set up any sort of
>> handoff structures used by the TFA BL31 or perform any other setup
>> that is needed by the blob. The custom armv8_switch_to_el2_prep()
>> has to implement the jump to TFA BL31 with return to U-Boot just
>> before booting the Linux kernel.
>>
>> Example fitImage image and configuration section:
>>
>> /dts-v1/;
>>
>> / {
>>      description = "Linux kernel with FDT blob and TFA BL31";
>>
>>      images {
>>          kernel-1 { ... };
>>          fdt-1 { ... };
>>          atf-1 {                  /* This is the TFA BL31 image */
>>              description = "TFA BL31";
>>              data = /incbin/("../build/plat/release/bl31.bin");
>>              type = "tfa-bl31";
>
> This would need to be added to the ITS spec, c.f. https://
> fitspec.osfw.foundation/

Where does one do that ?

>>              arch = "arm64";
>>              os = "arm-trusted-firmware";
>>              compression = "none";
>>              load = <0x46400000>;
>>              entry = <0x46400000>;
>>          };
>>      };
>>
>>      configurations {
>>          default = "conf-1";
>>          conf-1 {
>>              description = "Boot Linux";
>>              kernel = "kernel-1";
>>              fdt = "fdt-1";
>>              loadables = "atf-1"; /* This is the TFA BL31 loadable */
>
> We have some special stuff around TF-A (and TEE for that matter IIRC) on
> Rockchip. The ELF is split into multiple binaries to load at different
> addresses:

[...]

>   Loadables:    u-boot
>                 atf-2
>                 atf-3
>
> I assume this would be supported as well and we would "just" need some
> sort of SoC-specific implementation of what was added in patch 1 of this
> series?

Yes, I think so.

> Is this what you're recommending? We would then identify which
> part of the binary it is based on the hardcoded load address instead of
> reading the load address from the ITS. Or should we think of a way of
> identifying them directly inside the ITS with some property for example?

Maybe try and prototype this loading of TFA for Rockchip and see how
well it fits first (if at all), and then we can decide on the
integration later?

> Otherwise a global remark on that feature is I believe it may increase
> exposure to exploits. This means U-Boot will happily run anything
> provided in EL3. E.g. imagine I provide a script in the ITS which U-Boot
> loads and executes before loading the kernel, fdt and loadables. Let's
> imagine this is sideloading (we even have some wget support now in U-
> Boot so not too far fetched) some app to keep running in EL3 after the
> kernel has booted. Or modify registers only accessible from EL3. Now you
> better be even more careful about what you're booting from your
> linux.itb. Is this a correct interpretation of the situation?
You have freedom to do whatever you want with no restrictions, for
example shoot yourself in the leg by not authenticating random scripts
up front and running whatever unknown stuff, sure. That is not a bad thing.

Running U-Boot in EL2 on top of non-free blobs is not any better, rather
the opposite I think.