1. Purpose[edit | edit source]
This article explains how to update the boot chain (OP-TEE with FIP) for a "custom" device tree.
This article concentrates in particular on generating a "custom" device tree based on the STM32CubeMX.
This article describes how to update the device tree compiled (DTB) part of the boot binaries.
2. Rational[edit | edit source]
There are various reasons for using a custom device tree, such as:
- the description of a new and private board
- the swapping of some internal peripherals from Cortex®-M side to Cortex®-A side (and vice versa)
3. Prerequisites[edit | edit source]
![]() |
Even if STMicroelectronics strongly recommends to use a Linux® environment, the steps described in this article can be executed in a WSL2 (Windows Sub-system Linux 2) environment. |
Compiling a new device tree means updating three software components belonging to the complete boot chain, Trusted Firmware-A (TF-A), U-Boot, and Linux kernel.
The material required to update the above software components is the following:
- Starter Package:
- For STM32MP1 series: en.FLASH-stm32mp1-openstlinux-6.6-yocto-scarthgap-mpu-v25.06.11.tar.gz
- For STM32MP2 series: en.FLASH-stm32mp2-openstlinux-6.6-yocto-scarthgap-mpu-v25.06.11.tar.gz
- Developer package:
- the component sources and patches: en.SOURCES-stm32mp-openstlinux-6.6-yocto-scarthgap-mpu-v25.06.11.tar.gz
- the SDK toolchain:
- For STM32MP1 series: en.SDK-x86_64-stm32mp1-openstlinux-6.6-yocto-scarthgap-mpu-v25.06.11.tar.gz
- For STM32MP2 series: en.SDK-x86_64-stm32mp2-openstlinux-6.6-yocto-scarthgap-mpu-v25.06.11.tar.gz
- the STM32CubeProgrammer, which is the tool used to flash the images and binaries into the target.
- Custom device tree sources:
- In the rest of this document, we assume that the custom device tree is generated by STM32CubeMX and stored in a MyDeviceTree_fromCubeMX.tar.xz tarball with following file tree:
MyDeviceTree_fromCubeMX ├── <CortexA> │ └── DeviceTree │ └── <ProjectName> │ ├── kernel Device tree files for Linux kernel │ │ │── <soc-machine>-<ProjectName>-mx.dts │ │ └── [...] │ ├── optee-os Device tree files for OP-TEE │ │ │── <soc-machine>-<ProjectName>-mx.dts │ │ └── [...] │ ├── tf-a Device tree files for TF-A │ │ │── <soc-machine>-<ProjectName>-mx.dts │ │ └── [...] │ └── u-boot Device tree files for U-BOOT │ │── <soc-machine>-<ProjectName>-mx.dts │ └── [...] ├── CM33 (Availability depending of configuration used with STM32CubeMX tool) │ └── DeviceTree │ └── <ProjectName> │ ├── mcuboot Device tree files for MCUBOOT │ │ │── <soc-machine>-<ProjectName>-mx.dts │ │ └── [...] │ └── tf-m Device tree files for TF-M │ │── <soc-machine>-<ProjectName>-mx.dts │ └── [...] └── ExtMemLoader (Availability depending of configuration used with STM32CubeMX tool) └── <ProjectName> ├── optee-os Specific device tree files to generate FIP programmer binary │ │── <soc-machine>-<ProjectName>-mx.dts │ └── [...] ├── tf-a Specific device tree files to generate TF-A and FIP programmer binaries │ │── <soc-machine>-<ProjectName>-mx.dts │ └── [...] └── u-boot Specific device tree files to generate FIP programmer binary │── <soc-machine>-<ProjectName>-mx.dts └── [...]
Description:
<CortexA>: CA7 or CA35 depending of configuration selected with STM32CubeMX tool <soc-machine>: the soc name without '-dkX' or '-evX' extension (e.g. stm32mp135f, stm32mp157f, stm32mp257f, etc) <ProjectName>: the STM32CubeMX user project name
- Make sure the hardware configuration described in the PC prerequisites article has been executed (even with a WSL2 setup)
4. Preparing your environment[edit | edit source]
It is recommended to organize the numerous inputs described in prerequisites in your environment.
First create a dedicated WORKDIR under your HOME folder and copy there all the inputs listed in prerequisites:
cd $HOME
mkdir WORKDIR
cd WORKDIR
export WORKDIR="$PWD"
tar --strip-components=1 -xf en.FLASH-stm32mp1-openstlinux-6.6-yocto-scarthgap-mpu-v25.06.11.tar.gz -C $WORKDIR/
tar --strip-components=1 -xf en.SOURCES-stm32mp-openstlinux-6.6-yocto-scarthgap-mpu-v25.06.11.tar.gz -C $WORKDIR/
tar --strip-components=1 -xf en.SDK-x86_64-stm32mp1-openstlinux-6.6-yocto-scarthgap-mpu-v25.06.11.tar.gz -C $WORKDIR/
tar xf MyDeviceTree_fromCubeMX.tar.xz -C $WORKDIR/
Set-up a dedicated EXTDT_DIR variable to access the device tree source file
pushd $WORKDIR/MyDeviceTree_fromCubeMX export EXTDT_DIR="$PWD" popd
Set-up a dedicated FWDDR_DIR variable to access the DDR firmware source file
pushd $WORKDIR/sources/ostl-linux/stm32mp-ddr-phy-* export FWDDR_DIR="$PWD" popd
Set-up a dedicated FIP_DEPLOYDIR_ROOT variable to store all build output artifacts to generate FIP binaries.
mkdir -p $WORKDIR/FIP_artifacts pushd $WORKDIR/FIP_artifacts export FIP_DEPLOYDIR_ROOT=$PWD popd
Then proceed with the STM32MPU_Developer_Package#Installing_the_SDK chapter.
The commands described in the rest of the document must be run in an SDK environment context: (STM32MPU_Developer_Package#Starting_up_the_SDK).
5. Updating the kernel device tree[edit | edit source]
![]() |
The procedure below is an extract of the README.HOW_TO.txt.stm32mp1 file which is available in $WORKDIR/sources/ostl-linux/linux-stm32mp-*. Note: the "README.HOW_TO.txt.<board flavor>" file contains some useful grep "$> commands that are needed to build the artifact of kernel. |
- unpack and patch sources
pushd $WORKDIR mkdir -p kernel tar xf sources/ostl-linux/linux-stm32mp-*/linux-*.tar.xz -C kernel mv kernel/linux-* kernel/kernel-sources/ pushd kernel/kernel-sources/ for p in $(ls -1 ../../sources/ostl-linux/linux-stm32mp-*/*.patch); do patch -p1 < $p; done popd popd
- regenerate the kernel DTB
For our example:
pushd $WORKDIR/kernel/kernel-sources export OUTPUT_BUILD_DIR=$PWD/../build mkdir -p ${OUTPUT_BUILD_DIR} make O="${OUTPUT_BUILD_DIR}" multi_v7_defconfig fragment*.config for f in `ls -1 ../../sources/ostl-linux/linux-stm32mp-*/fragment*.config`; do scripts/kconfig/merge_config.sh -m -r -O ${OUTPUT_BUILD_DIR} ${OUTPUT_BUILD_DIR}/.config $f; done (yes "" || true ) | make oldconfig O="${OUTPUT_BUILD_DIR}" make O="${OUTPUT_BUILD_DIR}" KBUILD_EXTDTS="${EXTDT_DIR}/CA7/DeviceTree/MY_DEMO/linux" stm32mp135f-my_demo-mx.dtb popd ls -l ${OUTPUT_BUILD_DIR}/arch/${ARCH}/boot/dts/stm32mp135f-my_demo-mx.dtb
For other examples (STM32MP1 series or STM32MP2 series):
Please replace green words with cell content:
6. Updating BOOT firmware[edit | edit source]
6.1. Updating the TF-A device tree[edit | edit source]
![]() |
The procedure below is an extract of the README.HOW_TO.txt.stm32mp1 file which is available in $WORKDIR/sources/ostl-linux/tf-a-stm32mp-*. Note: the "README.HOW_TO.txt.<board flavor>" file contains some useful grep "$> commands that are needed to build the artifact of tf-a. |
- unpack and patch sources
pushd $WORKDIR pushd sources/ostl-linux/tf-a-stm32mp-v[0-9]* mkdir -p tf-a-sources tar xf tf-a-stm32mp-v[0-9]*.tar.* --one-top-level=tf-a-sources --strip-components=1 pushd tf-a-sources for p in `ls -1 ../*.patch`; do patch -p1 < $p; done popd popd
- regenerate TF-A
For our example:
pushd $WORKDIR/sources/ostl-linux/tf-a-stm32mp-v[0-9]*/tf-a-sources export EXTDT_DIR_TF_A=CA7/DeviceTree/MY_DEMO/tf-a export EXTDT_DIR_TF_A_SERIAL=CA7/DeviceTree/MY_DEMO/tf-a make -f ../Makefile.sdk.stm32mp1 DEPLOYDIR=${FIP_DEPLOYDIR_ROOT}/arm-trusted-firmware TF_A_DEVICETREE=stm32mp135f-my_demo-mx TF_A_CONFIG="optee-sdcard optee-programmer-usb" stm32 popd
For other examples (STM32MP1 series or STM32MP2 series):
Please replace green words with cell content:
6.2. Updating the OP-TEE device tree[edit | edit source]
![]() |
The procedure below is an extract of the README.HOW_TO.txt.stm32mp1 file which is available in $WORKDIR/sources/ostl-linux/optee-os-stm32mp-*. Note: the "README.HOW_TO.txt.<board flavor>" file contains some useful grep "$> commands that are needed to build the artifact of OP-TEE. |
- unpack and patch sources
pushd $WORKDIR pushd sources/ostl-linux/optee-os-stm32mp-[0-9]* tar xf optee-os-stm32mp-[0-9]*.tar.* --one-top-level=optee-os-sources --strip-components=1 pushd optee-os-sources tar xfz ../fonts.tar.gz for p in `ls -1 ../*.patch`; do patch -p1 < $p; done popd popd
- regenerate OP-TEE binaries
For our example:
pushd $WORKDIR/sources/ostl-linux/optee-os-stm32mp-[0-9]*/optee-os-sources export EXTDT_DIR_OPTEE=CA7/DeviceTree/MY_DEMO/optee-os export EXTDT_DIR_OPTEE_SERIAL=CA7/DeviceTree/MY_DEMO/optee-os make -f ../Makefile.sdk.stm32mp1 DEPLOYDIR=${FIP_DEPLOYDIR_ROOT}/optee CFG_EMBED_DTB_SOURCE_FILE=stm32mp135f-my_demo-mx.dtb OPTEE_CONFIG="optee-sdcard optee-programmer-usb" optee popd
For other examples (STM32MP1 series or STM32MP2 series):
Please replace green words with cell content:
6.3. Updating the U-Boot device tree[edit | edit source]
![]() |
The procedure below is an extract of the README.HOW_TO.txt.stm32mp1 file which is available in $WORKDIR/sources/ostl-linux/u-boot-stm32mp-*. Note: the "README.HOW_TO.txt.<board flavor>" file contains some useful grep "$> commands that are needed to build the artifact of U-Boot. |
- unpack and patch sources
pushd $WORKDIR pushd sources/ostl-linux/u-boot-stm32mp-v[0-9]* tar xf u-boot-stm32mp-v[0-9]*.tar.* --one-top-level=u-boot-sources --strip-components=1 pushd u-boot-sources for p in `ls -1 ../*.patch`; do patch -p1 < $p; done popd popd
- regenerate U-Boot binaries
For our example:
pushd $WORKDIR/sources/ostl-linux/u-boot-stm32mp-v[0-9]*/u-boot-sources export EXTDT_DIR_UBOOT=CA7/DeviceTree/MY_DEMO/u-boot export EXTDT_DIR_UBOOT_SERIAL=CA7/DeviceTree/MY_DEMO/u-boot make -f ../Makefile.sdk.stm32mp1 DEPLOYDIR=${FIP_DEPLOYDIR_ROOT}/u-boot UBOOT_DEFCONFIG_default=stm32mp13_defconfig UBOOT_DEFCONFIG_programmer=stm32mp13_defconfig DEVICE_TREE=stm32mp135f-my_demo-mx uboot popd
For other examples (STM32MP1 series or STM32MP2 series):
Please replace green words with cell content:
6.4. Updating the FIP image[edit | edit source]
Once all BOOT binaries have been generated, the FIP image can be generated using the fiptool wrapper script available from any of the BOOT source code location:
- - $WORKDIR/sources/ostl-linux/tf-a-stm32mp-v[0-9]*/tf-a-sources
- or
- - $WORKDIR/sources/ostl-linux/optee-os-stm32mp-[0-9]*/optee-os-sources
- or
- - $WORKDIR/sources/ostl-linux/u-boot-stm32mp-v[0-9]*/u-boot-sources
For our example:
pushd $WORKDIR/sources/ostl-linux/u-boot-stm32mp-v[0-9]*/u-boot-sources export FIP_CONFIG="optee-sdcard optee-programmer-usb" export FIP_DEVICETREE=stm32mp135f-my_demo-mx ../fiptool-stm32mp.stm32mp1 popd
For other examples (STM32MP1 series or STM32MP2 series):
Please replace green words with cell content:
7. Update target board[edit | edit source]
7.1. Copy new boot chain firmware into the target[edit | edit source]
The STM32CubeProgrammer is used to populate the new boot chain firmware to the target storage.
For our example:
The binaries needed to program the microSD card from target board with STM32CubeProgrammer are:
- ${FIP_DEPLOYDIR_ROOT}/arm-trusted-firmware/tf-a-stm32mp135f-my_demo-mx-optee-programmer-usb.stm32 (fsbl-boot partition) - ${FIP_DEPLOYDIR_ROOT}/fip/fip-stm32mp135f-my_demo-mx-optee-programmer-usb.bin (fip-boot partition)
The binaries to use to populate microSD card partitions are:
- ${FIP_DEPLOYDIR_ROOT}/arm-trusted-firmware/tf-a-stm32mp135f-my_demo-mx-optee-sdcard.stm32 (fsbl1 and fsbl2 partitions) - ${FIP_DEPLOYDIR_ROOT}/fip/fip-stm32mp135f-my_demo-mx-optee-sdcard.bin (fip-a partition)
For other examples (STM32MP1 series or STM32MP2 series):
Please replace green words with cell content:
![]() |
Note according to what have been modified in device tree files, it might be needed to reset the u-boot-env partition. |
7.2. Copy the new DTB into bootfs partition[edit | edit source]
There are two methods to update the bootfs partition with new kernel DTB on target.
7.2.1. Option 1: On an up and running target[edit | edit source]
For this method, the board IP address (<Target_IP>) is needed
For our example:
scp ${OUTPUT_BUILD_DIR}/arch/${ARCH}/boot/dts/stm32mp135f-my_demo-mx.dtb root@<Target_IP>:/boot/
For other examples (STM32MP1 series or STM32MP2 series):
Please replace green words with cell content:
![]() |
The new DTB will be taken into account on the next reboot of the target. |
7.2.2. Option 2: Directly into bootfs image[edit | edit source]
With this method, the original bootfs partition image file is updated through a loopback mount on local host. This utility is available within any Linux Distribution (even through WSL2)/
For our example:
mkdir -p $WORKDIR/bootfs mount -o loop st-image-bootfs-openstlinux-weston-stm32mp1.ext4 $WORKDIR/bootfs cp -f ${OUTPUT_BUILD_DIR}/arch/${ARCH}/boot/dts/stm32mp135f-my_demo-mx.dtb $WORKDIR/bootfs umount $WORKDIR/bootfs sync
For other examples (STM32MP1 series or STM32MP2 series):
Please replace green words with cell content:
Then use STM32CubeProgrammer to update the bootfs partition on target with the updated ext4 image.