Last edited 3 weeks ago

How to compile the device tree with the Developer Package

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

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]

Info white.png Information
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:

  • 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


Warning DB.png Important
The rest of the document is as example for a STM32MP135F-DK More info green.png board.
The supported configuration used is optee boot scheme on sdcard storage. And for the MyDeviceTree_fromCubeMX.tar.xz tarball, the <CortexA> is set to CA7, <soc-machine> to stm32mp135f and <ProjectName> to my_demo, giving tarball file tree as:
MyDeviceTree_fromCubeMX
└── CA7
    └── DeviceTree
        └── MY_DEMO
            ├── kernel                                     Device tree files for Linux kernel
            │   │── stm32mp135f-my_demo-mx.dts
            │   └── [...]
            ├── optee-os                                   Device tree files for OP-TEE
            │   │── stm32mp135f-my_demo-mx.dts
            │   └── [...]
            ├── tf-a                                       Device tree files for TF-A
            │   │── stm32mp135f-my_demo-mx.dts
            │   └── [...]
            └── u-boot                                     Device tree files for U-BOOT
                │── stm32mp135f-my_demo-mx.dts
                └── [...]

However the procedure below is applicable for STM32MP1 series and STM32MP2 series.

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]

Info white.png Information
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:

Example STM32MP1 series STM32MP2 series
STM32MP135F-DK More info green.png STM32MP157F-EV1 More info green.png STM32MP215F-DK Info.png STM32MP257F-DK More info green.png for STM32MP23x lines evaluation Info.png STM32MP257F-EV1 More info green.png
stm32mp135f stm32mp157f stm32mp215f stm32mp235f stm32mp257f
CA7 CA7 CA35
multi_v7_defconfig multi_v7_defconfig defconfig

6. Updating BOOT firmware[edit | edit source]

6.1. Updating the TF-A device tree[edit | edit source]

Info white.png Information
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:

Example STM32MP1 series STM32MP2 series
STM32MP135F-DK More info green.png STM32MP157F-EV1 More info green.png STM32MP215F-DK Info.png STM32MP257F-DK More info green.png for STM32MP23x lines evaluation Info.png STM32MP257F-EV1 More info green.png
stm32mp135f stm32mp157f stm32mp215f stm32mp235f stm32mp257f
CA7 CA7 CA35
stm32mp1 stm32mp1 stm32mp2

6.2. Updating the OP-TEE device tree[edit | edit source]

Info white.png Information
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:

Example STM32MP1 series STM32MP2 series
STM32MP135F-DK More info green.png STM32MP157F-EV1 More info green.png STM32MP215F-DK Info.png STM32MP257F-DK More info green.png for STM32MP23x lines evaluation Info.png STM32MP257F-EV1 More info green.png
stm32mp135f stm32mp157f stm32mp215f stm32mp235f stm32mp257f
CA7 CA7 CA35
stm32mp1 stm32mp1 stm32mp2

6.3. Updating the U-Boot device tree[edit | edit source]

Info white.png Information
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:

Example STM32MP1 series STM32MP2 series
STM32MP135F-DK More info green.png STM32MP157F-EV1 More info green.png STM32MP215F-DK Info.png STM32MP257F-DK More info green.png for STM32MP23x lines evaluation Info.png STM32MP257F-EV1 More info green.png
stm32mp135f stm32mp157f stm32mp215f stm32mp235f stm32mp257f
stm32mp13_defconfig stm32mp15_defconfig stm32mp21_defconfig stm32mp23_defconfig stm32mp25_defconfig
CA7 CA7 CA35
stm32mp1 stm32mp1 stm32mp2

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:

Example STM32MP1 series STM32MP2 series
STM32MP135F-DK More info green.png STM32MP157F-EV1 More info green.png STM32MP215F-DK Info.png STM32MP257F-DK More info green.png for STM32MP23x lines evaluation Info.png STM32MP257F-EV1 More info green.png
stm32mp135f stm32mp157f stm32mp215f stm32mp235f stm32mp257f
stm32mp1 stm32mp1 stm32mp2

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:

Example STM32MP1 series STM32MP2 series
STM32MP135F-DK More info green.png STM32MP157F-EV1 More info green.png STM32MP215F-DK Info.png STM32MP257F-DK More info green.png for STM32MP23x lines evaluation Info.png STM32MP257F-EV1 More info green.png
stm32mp135f stm32mp157f stm32mp215f stm32mp235f stm32mp257f
fsbl1 fsbl1 fsbla1
fsbl2 fsbl2 fsbla2
Info white.png Information
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:

Example STM32MP1 series STM32MP2 series
STM32MP135F-DK More info green.png STM32MP157F-EV1 More info green.png STM32MP215F-DK Info.png STM32MP257F-DK More info green.png for STM32MP23x lines evaluation Info.png STM32MP257F-EV1 More info green.png
stm32mp135f stm32mp157f stm32mp215f stm32mp235f stm32mp257f
Info white.png Information
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:

Example STM32MP1 series STM32MP2 series
STM32MP135F-DK More info green.png STM32MP157F-EV1 More info green.png STM32MP215F-DK Info.png STM32MP257F-DK More info green.png for STM32MP23x lines evaluation Info.png STM32MP257F-EV1 More info green.png
stm32mp135f stm32mp157f stm32mp215f stm32mp235f stm32mp257f
stm32mp1 stm32mp1 stm32mp2

Then use STM32CubeProgrammer to update the bootfs partition on target with the updated ext4 image.