Last edited 10 months ago

How to configure TF-A BL2

1 Article purpose[edit source]

This section details the TF-A BL2 stage (Trusted Firmware-A Boot Loader stage 2) used as FSBL (First Stage Boot Loader). It explains how to use BL2 in STM32 MPU context, describes the build process from sources, and shows how to deploy it on your target.
The build examples are based on the OpenSTLinux environment:

  • Developer Package
  • Distribution Package

2 Overview[edit source]

TF-A BL2 is the FSBL for ST boot chain. It is loaded by the ROM code in internal SYSRAM.
The main goal of this stage is to configure the DDR to load (and authenticate) other components from a FIP binary.

2.1 STM32 binary file[edit source]

To be properly loaded into SYSRAM by the ROM code, the TF-A BL2 firmware needs to be encapsulated in a binary that starts with an STM32 header. The STM32 header information is mandatory for the ROM code to be able to load, authenticate and start the firmware.
As the ROM code can only load a single binary, the STM32 file must embed in a single image, the header, the device tree and the BL2 firmware.

TF-A BL2 is part of the trusted boot and can be signed to be authenticated by ROM code. See Secure boot process for more details.

2.2 Device tree[edit source]

TF-A BL2 is based on device tree configuration. It uses the same device tree as the kernel but keeping only the mandatory nodes for the boot stage (to reduce binary size) thanks to a dedicated device tree file (such as fdts/stm32mp15-bl2.dtsi ). The device tree is part of the final STM32 file in order to be authenticated by the ROM code and loaded at the same time in the SYSRAM.
It must be configured or updated depending on your platform.

2.3 Storage management[edit source]

TF-A BL2 needs to access storage devices to load the FIP binary. By default, it uses the boot device selected by boot pins or OTP.
The selected device needs to be properly set up:

  • Device tree configuration (all devices)
  • BL2 boot device configuration for Flash memories .

Each device support needs a specific framework in the BL2 firmware.
By default, STMicroelectronics chose to select one single device support per binary. A BL2 with full storage support cannot fit in the SYSRAM size.
Storage build flags allow the BL2 firmware to be configured to support the requested boot storage.

2.4 DDR[edit source]

TF-A BL2 needs to set up the DDR to load the next binaries. DDR settings come from the device tree and must be adapted by the customer depending on DDR type, DDR configuration and boards. This can be done using STM32CubeMX.

2.5 Clock management[edit source]

An initial clock tree must be set up to allow accessing the DDR and the external storage devices.
It also improves the performance by increasing the default CPU speed and the storage transfer speed.

2.6 Binary mapping[edit source]

Below the TF-A BL2 mapping including the STM32 header layout:

Atf.stm32.png

The different sizes can be customized depending on build options and device tree customization. All sizes can be changed in the platform definition file. STM32MP1 platform uses plat/st/stm32mp1/stm32mp1_def.h :

  • STM32MP_BL2_DTB_BASE: device tree base address in SYSRAM with its associated SIZE
  • STM32MP_BL2_RO_BASE: start address from which the code is loaded and executed
  • STM32MP_BL2_RW_BASE: start address of the read and write data used by the code. It depends on the STM32MP_BL2_RO_SIZE, which cannot exceed SYSRAM size.

2.7 BL2 load processing[edit source]

Based on FIP and firmware configuration file, the same BL2 can dynamically manage different secure environments:


The BL2 process is executed as described below:


  1. The ROM Code loads (and authenticates if required) the STM32 TF-A BL2 file together with its device tree.
  2. BL2 loads (and authenticates) FW_CONFIG file from FIP. BL2 parses the firmware configuration file to identify the load binary properties.
  3. BL2 loads (and authenticates) all the binaries listed in FW_CONFIG from FIP.

2.7.1 FW_CONFIG[edit source]

The FW_CONFIG file is based on the device tree. It describes the properties of the binaries to be loaded. This file is mandatory in the FIP binary to dynamically configure BL2 so that it properly loads all images. It depends on the DDR size, defined mapping and selected binaries. More details on FW_CONFIG and its configuration can be found here.

2.7.2 BL2 load in Programmer mode[edit source]

The Programmer mode (USB or UART boot device) requires the complete FIP binary to start the load image process as previously explained. This is achieved by loading the complete FIP binary into DDR before starting the normal boot sequence. The FIP load address is fixed and must not override the next loaded address:
DWL_BUFFER_BASE used in plat/st/common/stm32_io_storage.c

2.7.3 Low-power mode[edit source]

When exiting from low-power mode, BL2 has to wake up the DDR from self-refresh mode and reload only the binaries that have been lost.

Warning white.png Warning
When OP-TEE OS is used in Pager mode (using SYSRAM), it can restore its content by itself thanks to the DDR backup and backup context

.

2.8 Trusted boot support[edit source]

This is a key feature for the secure boot. It completes the STM32 ROM code secure boot process. This feature is enabled by defining the TRUSTED_BOARD_BOOT = 1 build flag (not enabled by default).
As soon as the flag is enabled, all the binaries loaded by the BL2 stage are authenticated. The certificates listed in the CoT are mandatory into the FIP binary.

2.8.1 MBEDTLS[edit source]

When FIP is used, X509.v3 certificates are embedded in the package to authenticate all loaded binaries. The certificate parsing is done using MBEDTLS. The MBEDTLS[1] project is partially used during the trusted boot build process to retrieve part of the library and parse the certificates. The project must be downloaded close to the TF-A sources and the path using the MBEDTLS_DIR variable must be defined.

2.8.2 Disabling dynamic authentication[edit source]

A DYN_DISABLE_AUTH flag can be used to build the full BL2 content (including the disable MDEBTLS files). It allows the authentication to be enabled or disabled using a device tree property:

disable_auth = <0x0>; // To enable authentication
disable_auth = <0x1>; // To bypass authentication

This device tree property is located in the BL2 device tree (trusted boot device tree).

2.8.3 Cryptographic Library[edit source]

The STM32 MPU uses its own cryptographic library (thanks to hardware accelerators or ROM Code services (STM32MP15 Only)) to verify certificate signatures: plat/st/common/stm32mp_crypto_lib.c

2.8.4 Keys[edit source]

The authentication is based on different keys and certificates. By default, the Arm® TBBR CoT is used. The topology is defined in the BL2 device tree fdts/cot_descriptors.dtsi and can be customized using <link here to authentication article>. The STM32 MPU uses the default public root key hash in OTP as main root key for the CoT.
It can be modified by the customer in device tree by redefining pkh_otp.

During the development, the ROTPK hash is not mandatory. If it is not fused in OTP, it is seen as NOT DEPLOYED and the final ROTPK hash control is bypassed. However the entire CoT is verified.

Warning white.png Warning
The ROTPK hash must be in OTP before closing the chip


3 Source code access and build process[edit source]

Cross compilation of TF-A BL2 is only required if it needs to be modified.
By default, the TF-A BL2 images are named tf-a-<board>-<storage>.stm32 in the Starter Package.
If changes have been made, rebuild TF-A and update all the FSBL partitions of your boot device with this new image. A second FSBL image is used by ROM code as a backup image in case of corruption.

The build process creates an STM32 image. This binary is built in a single step during the build process.

4 Developer Package[edit source]

4.1 Install sources[edit source]

The Developer Package contains OpenSTLinux and TF-A sources: TF-A Installation

4.2 Official source tree[edit source]

Download the source code from the official Trusted Firmware-A git repository.

  git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
Warning white.png Warning
The STM32MP1 platform is not yet fully upstreamed. Depending on the version used, some features may not be available.


For a full-featured software, go to STMicroelectronics github:

  git clone https://github.com/STMicroelectronics/arm-trusted-firmware.git


4.3 Build process[edit source]

4.3.1 Initializing the cross compile environment[edit source]

Refer to Setup Cross compile environment.

4.3.2 TF-A Build flags[edit source]

Here is the list of the mandatory flags that need to be specified to complete the TF-A BL2 build:

  • ARM_ARCH_MAJOR = 7: the major version of Arm architecture to target (STM32MP1 is based on an Arm v7 architecture)
  • ARCH = aarch32: specifies aarch32 architecture to be built
  • PLAT = stm32mp1: builds an STM32MP1 platform
  • DTB_FILE_NAME = <fdt file name>.dtb: this flag must be defined to build the proper target and include the correct DTB file into the final file
  • The boot device(s) you use, one (or several) of:
    • STM32MP_EMMC = 1
    • STM32MP_SDMMC = 1
    • STM32MP_RAW_NAND = 1
    • STM32MP_SPI_NAND = 1
    • STM32MP_SPI_NOR = 1
  • or a programming interface:
    • STM32MP_UART_PROGRAMMER = 1
    • STM32MP_USB_PROGRAMMER = 1

Optional flags:

  • BUILD_PLAT = <folder>: custom output folder name (by default build/<debug/release>/)
  • DEBUG = 1: adds debug information in all binaries
  • V = 1: prints verbose compilation traces
  • TRUSTED_BOARD_BOOT = 1: adds MBEDTLS build sources and authentication framework enabled
  • DYN_DISABLE_AUTH = 1: enables/disables authentication using device tree
  • STM32MP_FORCE_MTD_START_OFFSET = <value>: overrides the default start offset to read FIP on MTD devices (need to be aligned with FlashLayout).
Info white.png Information
Default offsets are STM32MP_NOR_FIP_OFFSET = 0x00080000 and STM32MP_NAND_FIP_OFFSET = 0x00200000
  • STM32MP_USE_EXTERNAL_HEAP = 1: can be enabled to define MBEDTLS heap out of BL2 sources (defined in device tree).


4.4 Build command[edit source]

As previously explained, the BL2 generation depends on the selected storage device. By default, only one storage device is supported.

Warning white.png Warning
The DTB_FILE_NAME flag and the selected storage must be set to select the correct board configuration.

The device tree file for the target must be located in fdts folder (<board>.dts)

First add your own environment flags:

  unset LDFLAGS;
  unset CFLAGS;

Then compile the TF-A BL2.

The default build command for STM32MP15 is

  make ARM_ARCH_MAJOR=7 ARCH=aarch32 PLAT=stm32mp1 \
         <Selected storage> DTB_FILE_NAME=<board_name>.dtb

Here are build commands for the stm32mp157c-ev1 board (which supports different storage devices):

  • Flash programming support
  make ARM_ARCH_MAJOR=7 ARCH=aarch32 PLAT=stm32mp1 STM32MP_USB_PROGRAMMER=1 \
         DTB_FILE_NAME=stm32mp157c-ev1.dtb
  make ARM_ARCH_MAJOR=7 ARCH=aarch32 PLAT=stm32mp1 STM32MP_UART_PROGRAMMER=1 \
         DTB_FILE_NAME=stm32mp157c-ev1.dtb
  • Dedicated boot storage
  make ARM_ARCH_MAJOR=7 ARCH=aarch32 PLAT=stm32mp1 STM32MP_SDMMC=1 \
         DTB_FILE_NAME=stm32mp157c-ev1.dtb
  make ARM_ARCH_MAJOR=7 ARCH=aarch32 PLAT=stm32mp1 STM32MP_EMMC=1 \
         DTB_FILE_NAME=stm32mp157c-ev1.dtb
  make ARM_ARCH_MAJOR=7 ARCH=aarch32 PLAT=stm32mp1 STM32MP_RAW_NAND=1 \
         DTB_FILE_NAME=stm32mp157c-ev1.dtb
  make ARM_ARCH_MAJOR=7 ARCH=aarch32 PLAT=stm32mp1 STM32MP_SPI_NOR=1 \
         DTB_FILE_NAME=stm32mp157c-ev1.dtb

Not available on board

  make ARM_ARCH_MAJOR=7 ARCH=aarch32 PLAT=stm32mp1 STM32MP_SPI_NAND=1 \
         DTB_FILE_NAME=stm32mp157c-ev1.dtb


From the Developer Package tarball, a Makefile.sdk is present and must be used to build the target. It automatically sets the proper configuration for the TF-A build.

  make -f Makefile.sdk TF_A_CONFIG=<emmc/sdcard/nand/nor/usb/uart>  TF_A_DEVICETREE=<board>

The latest version of the helper file is also available in GitHub: README_HOWTO.txt .

4.5 Final image[edit source]

The final image is available for Flash memory or SDCard update in the corresponding folder:

<BUILD_PLAT>/tf-a-<board>.stm32
Ex:
build/release/tf-a-stm32mp157c-ev1.stm32

5 Distribution Package[edit source]

For an OpenSTLinux distribution, the TF-A image is built in release mode by default. The yocto recipe can be found in:

meta-st/meta-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_<version>.bb

To modify the TF-A BL2 code source, use the following steps starting from an already downloaded and built OpenSTLinux distribution.

5.1 Accessing the sources[edit source]

You can use devtool to access the source.

  cd <baseline root directory>
  devtool modify tf-a-stm32mp sources/boot/tf-a

By going to the sources/boot/tf-a folder, you can manage and modify the TF-A sources. To rebuild it, go back to the build-<distribution> folder and launch the TF-A recipe:

  bitbake tf-a-stm32mp

The final image is deployed in the image default output folder.

6 Updating the software on board[edit source]

6.1 Partitioning of binaries[edit source]

The TF-A build provides a binary named tf-a-<board>.stm32 (or tf-a-<board>-<storage>.stm32 from Makefile.sdk) that MUST be copied to a dedicated partition named "fsblX" (X depends on the number of needed backups in the Flash).

Warning white.png Warning
TF-A must be located in the first partition of your boot device.

You can just update the first partition for a simple test, but all backup partitions must contain the same image at the end.

6.2 Updating via SDCard[edit source]

If you use an SDCard, simply update TF-A using the dd command on your host.
Plug your SDCard into the computer and copy the binary to the dedicated partition; on an SDCard/USB disk the "fsbl1" partition is partition 1:

 - SDCard: /dev/mmcblkXp1 (where X is the instance number)
 - SDCard via USB reader: /dev/sdX1 (where X is the instance number)
  • Under Linux®
  dd if=<tf-a file>.stm32 of=/dev/<device partition> bs=1M conv=fdatasync
Info white.png Information
To find the partition associated to a specific label, just plug the SDCard/USB disk into your PC and call the following command:
  ls -l /dev/disk/by-partlabel/
 total 0
 lrwxrwxrwx 1 root root 10 Jan 17 17:38 bootfs -> ../../mmcblk0p4
 lrwxrwxrwx 1 root root 10 Jan 17 17:38 fip -> ../../mmcblk0p3
 lrwxrwxrwx 1 root root 10 Jan 17 17:38 fsbl1 -> ../../mmcblk0p1          ? FSBL1 (TF-A)
 lrwxrwxrwx 1 root root 10 Jan 17 17:38 fsbl2 -> ../../mmcblk0p2          ? FSBL2 (TF-A backup ? same content as FSBL)
 lrwxrwxrwx 1 root root 10 Jan 17 17:38 rootfs -> ../../mmcblk0p5
 lrwxrwxrwx 1 root root 10 Jan 17 17:38 userfs -> ../../mmcblk0p6


  • Under Windows®

CoreUtils [2] that includes the dd command is available for Windows.

6.3 Updating via USB mass storage on U-boot[edit source]

See How to use USB mass storage in U-Boot.

Refer to the previous section to put tf-a-<board>-<storage>.stm32 into SDCard/USB disk.

6.4 Updating your boot device via STM32CubeProgrammer[edit source]

Refer to the STM32CubeProgrammer documentation to update your target.

7 Secure secret provisioning (SSP)[edit source]

Warning white.png Warning
This feature is only available for STM32 MPU with cryptographic accelerators

The STM32 MPU supports the SSP feature. Part of this feature is based on TF-A BL2:

  • Exchange with STM32_CubeProgrammer
  • Program OTPs

A specific TF-A BL2 build is required to manage SSP.

Warning white.png Warning
This STM32 output file must be signed to complete the SSP feature.

Dedicated files are delivered in the platform folder that contains the specific Makefile and bl2_plat_setup for the TF-A SSP.
The TF-A SSP is a subset of the standard TF-A BL2 that includes only:

  • BL2 device tree
  • BL2 image with limited support to the serial link device.

7.1 Developer Package[edit source]

7.1.1 Install sources[edit source]

The Developer Package contains OpenSTLinux and TF-A-SSP sources: TF-A-SSP Installation

Warning white.png Warning
The SSP is a specific ST feature and will never be upstreamed.

7.1.2 Additional flags[edit source]

The mandatory flags to build the TF-A SSP are:

  • STM32MP_SSP = 1

For the serial link (exclusive):

  • STM32MP_UART_PROGRAMMER = 1
  • STM32MP_USB_PROGRAMMER = 1

7.1.3 Build command[edit source]

  make ARM_ARCH_MAJOR=7 ARCH=aarch32 PLAT=stm32mp1 \
         STM32MP_SSP=1 STM32MP_USB_PROGRAMMER=1 \
         DTB_FILE_NAME=<board>.dtb

or

  make ARM_ARCH_MAJOR=7 ARCH=aarch32 PLAT=stm32mp1 \
         STM32MP_SSP=1 STM32MP_UART_PROGRAMMER=1 \
         DTB_FILE_NAME=<board>.dtb

7.1.4 Final image[edit source]

The final image is available in the corresponding folder:

tf-a-ssp-<board>.stm32
For example:
tf-a-ssp-stm32mp157c-ev1.stm32

7.2 Distribution Package[edit source]

For an OpenSTLinux distribution, the TF-A SSP image is not built in release mode by default. The yocto recipe can be found in:

meta-st/meta-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp-ssp_<version>.bb

To modify the TF-A SSP code source, use the following steps starting from an already downloaded and built OpenSTLinux distribution.

7.2.1 Accessing the sources[edit source]

You can use devtool to access the source.

  cd <baseline root directory>
  devtool modify tf-a-stm32mp-ssp sources/boot/tf-a_ssp

By going to the sources/boot/tf-a_ssp folder, you can manage and modify the TF-A sources. To rebuild it, go back to the build-<distribution> folder and launch the TF-A recipe:

  bitbake tf-a-stm32mp-ssp

The final image is deployed in the image default output folder.