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

Quentin Schulz quentin.schulz at cherry.de
Wed Jan 29 18:10:22 CET 2025


Hi Marek,

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/

>              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:

rk3399:
  Image 1 (atf-1)
   Description:  ARM Trusted Firmware
   Created:      Wed Jan 29 16:24:16 2025
   Type:         Firmware
   Compression:  uncompressed
   Data Size:    143438 Bytes = 140.08 KiB = 0.14 MiB
   Architecture: AArch64
   OS:           ARM Trusted Firmware
   Load Address: 0x00040000
   Hash algo:    sha256
   Hash value: 
44285ea3a629cceee42a5fbfe838b6193e7c9a2f6643b0496dae617e2f7e2e8a
  Image 2 (atf-2)
   Description:  ARM Trusted Firmware
   Created:      Wed Jan 29 16:24:16 2025
   Type:         Firmware
   Compression:  uncompressed
   Data Size:    8024 Bytes = 7.84 KiB = 0.01 MiB
   Architecture: AArch64
   OS:           ARM Trusted Firmware
   Load Address: 0xff3b0000
   Hash algo:    sha256
   Hash value: 
7da49d2642204ded0a8eff093ae5c0e7300cfb18427d7a3e2f4e4cb227e4c2e9
  Image 3 (atf-3)
   Description:  ARM Trusted Firmware
   Created:      Wed Jan 29 16:24:16 2025
   Type:         Firmware
   Compression:  uncompressed
   Data Size:    4096 Bytes = 4.00 KiB = 0.00 MiB
   Architecture: AArch64
   OS:           ARM Trusted Firmware
   Load Address: 0xff8c0000
   Hash algo:    sha256
   Hash value: 
52c626d345ceeab61d8ede858a191834843f234cb4c2d2145546fd824e09c815
  Image 4 (atf-4)
   Description:  ARM Trusted Firmware
   Created:      Wed Jan 29 16:24:16 2025
   Type:         Firmware
   Compression:  uncompressed
   Data Size:    4096 Bytes = 4.00 KiB = 0.00 MiB
   Architecture: AArch64
   OS:           ARM Trusted Firmware
   Load Address: 0xff8c1000
   Hash algo:    sha256
   Hash value: 
50a7da66c26f838220d3befe84dd070988d238fa8abb34d1342815dae1083ec6
  Image 5 (atf-5)
   Description:  ARM Trusted Firmware
   Created:      Wed Jan 29 16:24:16 2025
   Type:         Firmware
   Compression:  uncompressed
   Data Size:    0 Bytes = 0.00 KiB = 0.00 MiB
   Architecture: AArch64
   OS:           ARM Trusted Firmware
   Load Address: 0xff8c2000
   Hash algo:    sha256
   Hash value: 
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
  Image 6 (fdt-1)
   Description:  fdt-rockchip/rk3399-puma-haikou
   Created:      Wed Jan 29 16:24:16 2025
   Type:         Flat Device Tree
   Compression:  uncompressed
   Data Size:    93264 Bytes = 91.08 KiB = 0.09 MiB
   Architecture: Unknown Architecture
   Hash algo:    sha256
   Hash value: 
9bcaaba8ea986042273421510acb76d5043bde550e463e80c2ee306239864f4c
  Default Configuration: 'config-1'
  Configuration 0 (config-1)
   Description:  rockchip/rk3399-puma-haikou.dtb
   Kernel:       unavailable
   Firmware:     atf-1
   FDT:          fdt-1
   Loadables:    u-boot
                 atf-2
                 atf-3
                 atf-4
                 atf-5

px30:
Image 1 (atf-1)
   Description:  ARM Trusted Firmware
   Created:      Wed Jan 29 17:06:59 2025
   Type:         Firmware
   Compression:  uncompressed
   Data Size:    102526 Bytes = 100.12 KiB = 0.10 MiB
   Architecture: AArch64
   OS:           ARM Trusted Firmware
   Load Address: 0x00040000
   Hash algo:    sha256
   Hash value: 
d3eb0776f5e1628eaaa38355992bc8a4cc8b12de565ebd6098897269e70345b3
  Image 2 (atf-2)
   Description:  ARM Trusted Firmware
   Created:      Wed Jan 29 17:06:59 2025
   Type:         Firmware
   Compression:  uncompressed
   Data Size:    112 Bytes = 0.11 KiB = 0.00 MiB
   Architecture: AArch64
   OS:           ARM Trusted Firmware
   Load Address: 0xff020000
   Hash algo:    sha256
   Hash value: 
19968b2d18472c485c02be72c609c2e9cc5dc4ea7993b86f462a788d109977d6
  Image 3 (fdt-1)
   Description:  fdt-rockchip/px30-ringneck-haikou
   Created:      Wed Jan 29 17:06:59 2025
   Type:         Flat Device Tree
   Compression:  uncompressed
   Data Size:    50032 Bytes = 48.86 KiB = 0.05 MiB
   Architecture: Unknown Architecture
   Hash algo:    sha256
   Hash value: 
f8416b75b2c0a16fd4599f47a4b24d763eb1e2dc0fdaac597510f5b907575c4d
  Default Configuration: 'config-1'
  Configuration 0 (config-1)
   Description:  rockchip/px30-ringneck-haikou.dtb
   Kernel:       unavailable
   Firmware:     atf-1
   FDT:          fdt-1
   Loadables:    u-boot
                 atf-2

rk3588:
  Image 1 (atf-1)
   Description:  ARM Trusted Firmware
   Created:      Wed Jan 29 17:08:54 2025
   Type:         Firmware
   Compression:  uncompressed
   Data Size:    204860 Bytes = 200.06 KiB = 0.20 MiB
   Architecture: AArch64
   OS:           ARM Trusted Firmware
   Load Address: 0x00040000
   Hash algo:    sha256
   Hash value: 
7612223b82b911a56f044a2be63befd1e0d47f9579c50e5b59ca62f12361912d
  Image 2 (atf-2)
   Description:  ARM Trusted Firmware
   Created:      Wed Jan 29 17:08:54 2025
   Type:         Firmware
   Compression:  uncompressed
   Data Size:    24576 Bytes = 24.00 KiB = 0.02 MiB
   Architecture: AArch64
   OS:           ARM Trusted Firmware
   Load Address: 0x000f0000
   Hash algo:    sha256
   Hash value: 
b2af21b50499777f862cc9d8d6ca9707248694b739badbe875e3b6834ae77e0d
  Image 3 (atf-3)
   Description:  ARM Trusted Firmware
   Created:      Wed Jan 29 17:08:54 2025
   Type:         Firmware
   Compression:  uncompressed
   Data Size:    36864 Bytes = 36.00 KiB = 0.04 MiB
   Architecture: AArch64
   OS:           ARM Trusted Firmware
   Load Address: 0xff100000
   Hash algo:    sha256
   Hash value: 
70505bb764db81a665c8bba4953d804ed9eab580d5428888a4436121eff11c50
  Image 4 (fdt-1)
   Description:  fdt-rockchip/rk3588-tiger-haikou
   Created:      Wed Jan 29 17:08:54 2025
   Type:         Flat Device Tree
   Compression:  uncompressed
   Data Size:    115080 Bytes = 112.38 KiB = 0.11 MiB
   Architecture: Unknown Architecture
   Hash algo:    sha256
   Hash value: 
c78f6f09dacfaf504d95d8f7d65ab8e0150b9014f033c5aaca85e45448fe177d
  Default Configuration: 'config-1'
  Configuration 0 (config-1)
   Description:  rockchip/rk3588-tiger-haikou.dtb
   Kernel:       unavailable
   Firmware:     atf-1
   FDT:          fdt-1
   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? 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?

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?

Cheers,
Quentin


More information about the U-Boot mailing list