Last edited 2 weeks ago

How to configure TF-A BL2

Applicable for STM32MP13x lines, STM32MP15x lines, STM32MP21x lines, STM32MP23x lines, STM32MP25x lines


1. Article purpose[edit | 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 configure and build BL2 in STM32 MPU context, describes the build process from sources, and shows how to deploy it on your target.

2. Source code access and build process[edit | edit source]

2.1. Cross compilation[edit | edit source]

Cross compilation of TF-A BL2 is only required if it needs to be modified. Two ways are possible:

  • with the OpenSTLinux SDK helper scripts (sdk-infos, README.HOW_TO.txt.<board flavor>): the build environment is set up by the scripts, refer to Cross-compile with OpenSTLinux SDK;
  • directly from the TF-A source tree, with a manual make command: the toolchain must then be selected as described below.

TF-A is bare-metal software: it must be built with a bare-metal toolchain, selected through the CROSS_COMPILE prefix (the trailing "-" is part of the prefix).

Series Architecture Toolchain prefix OpenSTLinux SDK directory
STM32MP1x Armv7-A (AArch32) arm-none-eabi- sysroots/x86_64-ostl_sdk-linux/usr/share/gcc-arm-none-eabi/bin
STM32MP2x Armv8-A (AArch64) aarch64-none-elf- sysroots/x86_64-ostl_sdk-linux/usr/share/gcc-aarch64-none-elf/bin

Example for STM32MP2x with the toolchain delivered in the OpenSTLinux SDK:

 export PATH=<SDK_DIR>/sysroots/x86_64-ostl_sdk-linux/usr/share/gcc-aarch64-none-elf/bin:$PATH
 export CROSS_COMPILE=aarch64-none-elf-
 ${CROSS_COMPILE}gcc -dumpmachine

The last command must report the expected target (aarch64-none-elf or arm-none-eabi).

The OpenSTLinux SDK is not mandatory to build TF-A: the official Arm GNU Toolchain can be used as well, and is the reference toolchain of the TF-A project[1]. Download the x86_64 package matching the target[2] (...-x86_64-arm-none-eabi for STM32MP1x, ...-x86_64-aarch64-none-elf for STM32MP2x), then set the same variables:

 export PATH=<toolchain install dir>/bin:$PATH
 export CROSS_COMPILE=aarch64-none-elf-
Warning
For a direct make invocation, do not use a shell where the SDK script environment-setup-* has been sourced: it selects a Linux toolchain (arm-ostl-linux-gnueabi- / aarch64-ostl-linux-) and exports a Linux sysroot with its CFLAGS and LDFLAGS, which are not suitable for TF-A. Start a new shell, or refer to Troubleshooting.
Information
Perform a clean build after any change of toolchain, architecture or build flags.

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

2.2. Install sources[edit | edit source]

2.2.1. From the Developer package[edit | edit source]

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

2.2.2. Official source tree[edit | 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
The STM32MP1 and STM32MP2 platforms are 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


2.2.3. Distribution Package[edit | edit source]

It is possible to use the distribution package to download and rebuild TF-A BL2

2.3. Build process[edit | edit source]

2.3.1. TF-A Build flags[edit | edit source]

Generic build flags for TF-A are described in the Build Options page of the official TF-A documentation[3].

Generic build flags for STM32 MPU platforms can be found in the build instruction chapter in official TF-A documentation [4].
Specific STM32MP1 series platform flags can be found in the build instruction chapter of the official TF-A documentation [5].
Specific STM32MP2 series platform flags can be found in the build instruction chapter [6].

Other optional flags:

  • STM32MP1_OPTEE_IN_SYSRAM (only for STM32MP15x lines ): To put OP-TEE pager in SYSRAM. Default: 0 (OP-TEE is in DDR)
  • STM32MP_FORCE_MTD_START_OFFSET = <value>: overrides the default start offset to read FIP on MTD devices (need to be aligned with FlashLayout).
Information
Default offsets are STM32MP_NOR_FIP_OFFSET = 0x00080000 and STM32MP_NAND_FIP_OFFSET = 0x00200000

2.4. Build command[edit | edit source]

2.4.1. Build command details[edit | edit source]

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

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)

Then compile the TF-A BL2.
For example, default build command for STM32MP15 is:

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

Example with SDCard:

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

Replace STM32MP_SDMMC with the chosen boot device [4].

  • Available storage medias are:
    • STM32MP_SDMMC
    • STM32MP_EMMC
    • STM32MP_RAW_NAND
    • STM32MP_SPI_NAND
    • STM32MP_SPI_NOR
  • Serial boot devices:
    • STM32MP_UART_PROGRAMMER
    • STM32MP_USB_PROGRAMMER
Warning
TF-A builds configured for serial boot are intended for device programming via STM32CubeProgrammer, not for booting Linux.

To reduce the BL31 size, PSCI support is limited to system reset. Low-power features and secondary Cortex-A35 CPU bring-up are not supported. Booting Linux with this configuration may cause the kernel to hang.

The same flag can be used as well with STM32MP2 series, but an addition DDR type flag must also be specified in order to compile the correct DDR driver. The correct flag depends of the DDR used on the board. The available DDR type flags are described in official TF-A documentation[6].

Example for STM32MP2 series (with SDCard and DDR4 present in STM32MP25 evaluation board):

 make PLAT=stm32mp2 DTB_FILE_NAME=stm32mp257f-ev1.dtb STM32MP_SDMMC=1 \
         SPD=opteed STM32MP_DDR4_TYPE=1

2.4.2. Secure boot support[edit | edit source]

Warning
Some specific libraries (mbedTLS , ...) are required to build tools and enable the TRUSTED_BOARD_BOOT : Prerequisites software library

To enable secure boot, you have to add TRUSTED_BOARD_BOOT=1 flag:
Example with secure boot on stm32mp135f-dk:

 make MBEDTLS_DIR=<path_to_mbedtls_directory> ARM_ARCH_MAJOR=7 \
              ARCH=aarch32 PLAT=stm32mp1 STM32MP_SDMMC=1 TRUSTED_BOARD_BOOT=1  \
              STM32MP13=1 DTB_FILE_NAME=stm32mp135f-dk.dtb

To enable secure boot with encryption support, you have to add DECRYPTION_SUPPORT=aes_gcm with the ENCRYPT_BLx flags to specify the binaries to encrypt. The secret key is provided in hexadecimal thanks to the ENC_KEY flag.
Example with encrypted BL32 on stm32mp135f-dk:

 make MBEDTLS_DIR=<path_to_mbedtls_directory> ARM_ARCH_MAJOR=7 \
        ARCH=aarch32 PLAT=stm32mp1 STM32MP_SDMMC=1 TRUSTED_BOARD_BOOT=1  \
        ENCRYPT_BL32=1 DECRYPTION_SUPPORT=aes_gcm \
        STM32MP13=1 DTB_FILE_NAME=stm32mp135f-dk.dtb ENC_KEY=<secret_key_in_hexadecimal_string>


Example of secure boot with with stm32mp257f-ev1:

 make MBEDTLS_DIR=<path_to_mbedtls_directory> SPD=opteed \
          PLAT=stm32mp2 STM32MP_SDMMC=1 STM32MP_DDR4_TYPE=1 \
          TRUSTED_BOARD_BOOT=1 DTB_FILE_NAME=stm32mp257f-ev1.dtb


2.4.3. OSTL device tree for STM32MP2 series[edit | edit source]

For STM32MP257F-EV1 Evaluation board , ST provides OSTL device tree configurations in a dedicated git repository: stm32mp2/a35-td/tf-a/stm32mp257f-ev1-ca35tdcid-ostl.dts . You can use the git submodule command:

 git submodule add https://github.com/STMicroelectronics/dt-stm32mp.git fdts/external-dt
 make PLAT=stm32mp2 DTB_FILE_NAME=stm32mp257f-ev1-ca35tdcid-ostl.dtb STM32MP_SDMMC=1 \
         SPD=opteed STM32MP_DDR4_TYPE=1

or git clone command with TFA_EXTERNAL_DT:

 git clone https://github.com/STMicroelectronics/dt-stm32mp.git ${DT_PATH}
 make PLAT=stm32mp2 DTB_FILE_NAME=stm32mp257f-ev1-ca35tdcid-ostl.dtb STM32MP_SDMMC=1 \
         SPD=opteed STM32MP_DDR4_TYPE=1 TFA_EXTERNAL_DT=${DT_PATH}/stm32mp2/a35-td/tf-a/

Here DT_PATH can be chosen to whatever you wish, but it must not be a relative path, for example:

 export DT_PATH=`pwd`/../dt-stm32mp

2.4.4. STM32MP2 series M33-TD flavor [edit | edit source]

TF-A need a specific build in order to work with M33-TD flavor . The STM32MP_M33_TDCID flag must be added in the make command. Example for stm32mp257f-ev1:

 make PLAT=stm32mp2 STM32MP_M33_TDCID=1 DTB_FILE_NAME=stm32mp257f-ev1-cm33tdcid-ostl-sdcard.dtb \
         STM32MP_SDMMC=1 SPD=opteed LOG_LEVEL=LOG_LEVEL_INFO \
         TFA_EXTERNAL_DT=${DT_PATH}/stm32mp2/m33-td/tf-a

2.4.5. Troubleshooting[edit | edit source]

If you use developer package SDK, you have to unset these flags:

 unset LDFLAGS CFLAGS AS LD CPPFLAGS CC CPP AR NM

If the build fails while compiling the host tools (fiptool, cert_create, encrypt_fw), the OpenSSL of the host is missing or too old. Point the build to another OpenSSL installation with the generic TF-A flag OPENSSL_DIR, for example the one delivered in the OpenSTLinux SDK:

 make ... OPENSSL_DIR=<SDK_DIR>/sysroots/x86_64-ostl_sdk-linux/usr

${OECORE_NATIVE_SYSROOT}/usr can be used instead when the SDK environment is sourced. The required OpenSSL version and the associated LD_LIBRARY_PATH setting are described in the official TF-A documentation[7].


2.5. Final image[edit | 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/stm32mp1/release/tf-a-stm32mp157c-ev1.stm32

3. Updating the software on board[edit | edit source]

3.1. Partitioning of binaries[edit | edit source]

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

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.

3.2. Updating via SDCard[edit | 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
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 [8] that includes the dd command is available for Windows.

3.3. Updating via USB mass storage on U-boot[edit | edit source]

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

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

3.4. Updating your boot device via STM32CubeProgrammer[edit | edit source]

Refer to the STM32CubeProgrammer documentation to update your target.