Last edited 2 years ago

How to compile the device tree with the Developer Package

1. Purpose[edit source]

This article explains how to update the boot chain (trusted mode) for a "custom" device tree.
In particular, STM32CubeMX can generate a "custom" device tree.

This article describes how to update the device tree compiled (DTB) part of the boot binaries.

2. Rationale[edit source]

There are various rationale 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 (or the opposite)

3. Prerequisites[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 mode), Trusted Firmware A (TF-A), u-boot, and Linux kernel.


The material required to update the above software components is the following:

  • Starter package:
    • the flashlayout as well as the images to flash, provided within the en.FLASH-stm32mp1-openstlinux<YY>-<MM>-<DD>.tar.xz file (download it from st.com)
  • Developer package:
    • the component sources and patches, provided within the en.SOURCES-stm32mp1-openstlinux-<YY>-<MM>-<DD>.tar.xz file (download it from st.com)
    • the SDK toolchain, provided within the en.SDK-x86_64-stm32mp1-openstlinux-<YY>-<MM>-<DD>.tar.xz file (download it from st.com)
  • 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
|-- kernel
|   |-- stm32mp157f-mydevicetree-mx.dts
|-- tf-a
|  |-- stm32mp157f-mydevicetree-mx.dts
|  |-- stm32mp157f-mydevicetree-mx-fw-config.dts
|  |-- stm32mp15-mx.dtsi
|-- u-boot
|  |-- stm32mp157f-mydevicetree-mx.dts
|  |-- stm32mp157f-mydevicetree-mx-u-boot.dtsi
|  |-- stm32mp15-mx.dtsi


4. Preparing your environment[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 <FLASH-st-image-weston-openstlinux-weston-stm32mp1.tar.xz> -C $WORKDIR/
tar --strip-components=1 -xf <SOURCES-st-image-weston-openstlinux-weston-stm32mp1.tar.xz> -C $WORKDIR/
tar --strip-components=1 -xf <SDK-st-image-weston-openstlinux-weston-stm32mp1.tar.xz> -C $WORKDIR/
tar xf <MyDeviceTree_fromCubeMX.tar.xz> -C $WORKDIR/

Then proceed with the SDK installation.


The commands described in the rest of the document must be run in an SDK environment context: (Starting_up_the_SDK).

5. Updating the kernel device tree[edit source]

Since 'extlinux.conf' explicitly points to the DTB, just update the kernel device tree by replacing the DTB file of the '/boot' partition. The path used must be something like '/boot/<devicetree>.dtb'.

The following chapters describe the procedure to generate and copy the new DTB into the target.

5.1. Kernel : unpack and patch sources[edit source]

Info white.png Information
The procedure below is an extract of the README.HOW_TO.txt file which is available in $WORKDIR/sources/arm-ostl-linux-gnueabi/linux-stm32mp-*. Please notice a grep "$>" README.HOW_TO.txt describes the few commands needed to build the artifact of kernel

Run the following command into a shell:

pushd $WORKDIR
mkdir -p kernel
tar xf sources/arm-ostl-linux-gnueabi/linux-stm32mp-*/linux-*.tar.xz -C kernel
mv kernel/linux-* kernel/kernel-sources/
pushd kernel/kernel-sources/
for p in $(ls -1 ../../sources/arm-ostl-linux-gnueabi/linux-stm32mp-*/*.patch); do patch -p1 < $p; done
popd
popd

5.2. Kernel : copy the DTS into the source code[edit source]

pushd $WORKDIR
cp -r MyDeviceTree_fromCubeMX/kernel/* kernel/kernel-sources/arch/arm/boot/dts/
popd

5.3. Kernel : regenerate the kernel DTB[edit source]

Info white.png Information
The procedure below is an extract of the README.HOW_TO.txt file which is available in $WORKDIR/sources/arm-ostl-linux-gnueabi/linux-stm32mp-*. Please notice a grep "$>" README.HOW_TO.txt describes the few commands needed to build the artifact of kernel
pushd $WORKDIR/kernel/kernel-sources
make ARCH=arm O="$PWD/../build" multi_v7_defconfig fragment*.config
for f in `ls -1 ../../sources/arm-ostl-linux-gnueabi/linux-stm32mp-*/fragment*.config`; do scripts/kconfig/merge_config.sh -m -r -O $PWD/../build $PWD/../build/.config $f; done
yes "" | make ARCH=arm oldconfig O="$PWD/../build"
make stm32mp157f-mydevicetree-mx.dtb LOADADDR=0xC2000040 O="$PWD/../build"
popd
ls -l $WORKDIR/kernel/build/arch/arm/boot/dts/stm32mp157f-mydevicetree-mx.dtb

5.4. Kernel : copy the DTB into bootfs[edit source]

First of all #Updating bootfs with the new DTB so that it is taken it into account at the next boot of the target.

Then, if needed, #Updating extlinux for the target according to this new DTB filename. This is only required if the filename of the generated DTB is different from the one used by extlinux to boot.

6. Updating BOOT firmwares[edit source]

BOOT firmwares are TF-A and U-BOOT and should be updated together (CubeMX provides devicetree for TF-A and U-BOOT).

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

To update the TF-A device tree, replace the DTB part of the TF-A binary.
The TF-A binary allocates a 'fixed' area for the DTB, just after the 'mkimage" headers. If the DTB is smaller than the reserved area, the remaining memory is padded with zero.

Below the procedure to generate TF-A with a new DTB and then flash it on the target:

6.1.1. TF-A : unpack and patch sources[edit source]

Info white.png Information
The procedure below is an extract of the README.HOW_TO.txt file which is available in $WORKDIR/sources/arm-ostl-linux-gnueabi/tf-a-stm32mp-*. Please notice a grep "$>" README.HOW_TO.txt describes the few commands needed to build the artifact of tf-a
pushd $WORKDIR
pushd sources/arm-ostl-linux-gnueabi/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

6.1.2. TF-A : copy the DTS into the source code[edit source]

pushd $WORKDIR
cp -r MyDeviceTree_fromCubeMX/tf-a/* sources/arm-ostl-linux-gnueabi/tf-a-stm32mp-v[0-9]*/tf-a-sources/fdts/
popd

6.1.3. TF-A : regenerate TF-A[edit source]

Info white.png Information
The procedure below is an extract of the README.HOW_TO.txt file which is available in $WORKDIR/sources/arm-ostl-linux-gnueabi/tf-a-stm32mp-*. Please notice a grep "$>" README.HOW_TO.txt describes the few commands needed to build the artifact of tf-a

First only the TF-A "intermediates" artifacts are generated, the FIP image will be generated at final step (u-boot compilation).


pushd $WORKDIR/sources/arm-ostl-linux-gnueabi/tf-a-stm32mp-v[0-9]*/tf-a-sources
export FIP_DEPLOYDIR_ROOT=$PWD/../../FIP_artifacts
make -f ../Makefile.sdk TF_A_DEVICETREE=<devicetree_name> FIP_CONFIG=" trusted" FIP_BL32_CONF="tfa," TF_A_CONFIG="trusted emmc nand nor sdcard uart usb" DEPLOYDIR=$FIP_DEPLOYDIR_ROOT/arm-trusted-firmware stm32
<devicetree_name> : is the device tree just copied, i.e.: stm32mp157f-mydevicetree-mx
DEPLOYDIR is the path where intermediate binaries of tf-a should be deployed (requiered by fip-tools to generate fip image)
popd

6.2. Updating the u-boot device tree[edit source]

To update the u-boot device tree, replace the DTB part of the u-boot binary.
Adding a new device tree to the u-boot source code forces the Makefile to regenerate a new u-boot.stm32 containing the new DTS.
The following chapters describe the procedure to update the u-boot device tree.

6.2.1. U-boot : unpack and patch sources[edit source]

Info white.png Information
The procedure below is an extract of the README.HOW_TO.txt file which is available in $WORKDIR/sources/arm-ostl-linux-gnueabi/u-boot-stm32mp-*. Please notice a grep "$>" README.HOW_TO.txt describes the few commands needed to build the artifact of u-boot
pushd $WORKDIR
pushd sources/arm-ostl-linux-gnueabi/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

6.2.2. U-boot : copy the DTS in the u-boot source code[edit source]

pushd $WORKDIR
cp MyDeviceTree_fromCubeMX/u-boot/* sources/arm-ostl-linux-gnueabi/u-boot-stm32mp-v[0-9]*/u-boot-sources/arch/arm/dts/
popd

6.2.3. U-boot : regenerate fip image within new u-boot[edit source]

Info white.png Information
The procedure below is an extract of the README.HOW_TO.txt file which is available in $WORKDIR/sources/arm-ostl-linux-gnueabi/u-boot-stm32mp-*. Please notice a grep "$>" README.HOW_TO.txt describes the few commands needed to build the artifact of u-boot
pushd $WORKDIR/sources/arm-ostl-linux-gnueabi/u-boot-stm32mp-v[0-9]*/u-boot-sources
make stm32mp15_<config>_defconfig
<config> : could be trusted or basic according the boot type
make -f ../Makefile.sdk all UBOOT_CONFIG=trusted UBOOT_DEFCONFIG=stm32mp15_trusted_defconfig UBOOT_BINARY=u-boot.dtb FIP_CONFIG="trusted" FIP_BL32_CONF="tfa," DEVICETREE=<device tree>
<device tree> : is the device tree just copied, i.e.: stm32mp157f-mydevicetree-mx
popd

6.2.4. U-boot : copy the u-boot into the target[edit source]

  • Because of 'extlinux' and before flashing the new fip image, make sure #Updating extlinux is compliant with the 'compatible' value in the DTS file.
  • Then flash the tf-a-xxxx.stm32 file (generated at tf-a step) into the 'ssbl' partition of the target using STM32CubeProgrammer.

7. Update methods[edit source]

7.1. Updating extlinux[edit source]

7.1.1. extlinux basics[edit source]

extlinux describes how u-boot boots. Updating extlinux consists in updating the extlinux.conf:

  • In case of an DK-2 board booting from the sdcard. A stm32mp157f-dk2_extlinux.conf file is located in /boot/mmc0_extlinux/,
  • otherwise if there is no specific extlinux.conf for your board then the extlinux.conf is taking into account.

extlinux.conf is the description of a boot menu with one or several entries; 'DEFAULT' selects the default entry.
Below an example of extlinux.conf:

menu title Select the boot mode
MENU BACKGROUND ../splash.bmp
TIMEOUT 5
DEFAULT stm32mp157f-mydevicetree-mx
LABEL stm32mp157f-dk2-sdcard
        KERNEL /uImage
        FDTDIR /
        APPEND root=PARTUUID=e91c4e10-16e6-4c0e-bd0e-77becf4a3582 rootwait rw console=ttySTM0,115200
LABEL stm32mp157f-dk2-a7-examples-sdcard
        KERNEL /uImage
        FDT /stm32mp157f-dk2-a7-examples.dtb
        APPEND root=PARTUUID=e91c4e10-16e6-4c0e-bd0e-77becf4a3582 rootwait rw console=ttySTM0,115200
LABEL stm32mp157f-dk2-m4-examples-sdcard
        KERNEL /uImage
        FDT /stm32mp157f-dk2-m4-examples.dtb
        APPEND root=PARTUUID=e91c4e10-16e6-4c0e-bd0e-77becf4a3582 rootwait rw console=ttySTM0,115200
LABEL stm32mp157f-mydevicetree-mx
       KERNEL /uImage
       FDT /stm32mp157f-mydevicetree-mx.dtb
       APPEND root=PARTUUID=e91c4e10-16e6-4c0e-bd0e-77becf4a3582 rootwait rw console=ttySTM0,115200

Please update/add the highlighted lines according to what have been compiled in chapter 5, 6 and/or 7:

  • DEFAULT: This is the default 'LABEL' to boot
  • LABEL : The entry 'LABEL' is the value of 'compatible' of the DTS file compiled with u-boot.
    The 'compatible' value is at head of the DTS file and looks like : "st,stm32mp157f-mydevicetree-mx"
  • FDT : The path from /boot of the kernel DTB to use

7.2. Updating bootfs[edit source]

There are two methods to update bootfs

  • On an up and running target
scp stm32mp157f-mydevicetree-mx.dtb root@<Target_IP>:/boot/
  • Directly into 'bootfs' image

You do not need to have a target up and running. Only the "st-image-bootfs-openstlinux-weston-stm32mp1.ext4" file is required. To modify an 'ext4' file, a loopback mount, avaible within any Linux Distribution (even through WSL2), is required:

mkdir -p $WORKDIR/bootfs
mount -o loop <st-image-bootfs-openstlinux-weston-stm32mp1.ext4> $WORKDIR/bootfs
##Then copy the new dtb file at the root of $WORKDIR/bootfs
umount $WORKDIR/bootfs
sync

Then use STM32CubeProgrammer to update the bootfs partiton

7.2.1. Updating extlinux[edit source]

Updating 'extlinux' consists in modifying the extlinux.conf. There are two ways to do this:

  • On an up and running target

Open an ssh connection to the target or use a direct connection with a tty terminal. Then use an vi editor to modify the extlinux.conf file.

Do not forget to synchronize the file system before rebooting the target:
sync
  • Into 'bootfs' image directly

You do not need to have a target up and running. Only the "st-image-bootfs-openstlinux-weston-stm32mp1.ext4" file is required. To modify an 'ext4' file, a loopback mount tool, avaible in any Linux Distribution (even through WSL2), is needed:

mkdir -p $WORKDIR/bootfs
sudo mount -o loop <st-image-bootfs-openstlinux-weston-stm32mp1.ext4> $WORKDIR/bootfs
##Then edit the extlinux.conf file (for WSL2 use a 'Linux' type editor; vi, ...)
##Once extlinux.conf up-to-date, umount loopback and flash the bootfs into sdcard with STM32CubeProgrammer