Last edited 3 weeks ago

How to compile the device tree with the Developer Package


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]

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


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]

  • 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]

  • 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]

  • 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]

  • 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

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

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.