Build Device Tree Overlays from Source Code
Introduction
This article describes how to build Device Tree overlays without using a higher-level build system such as the Yocto Project/OpenEmbedded. The device tree overlays are available on our Git server at git.toradex.com.
This is the third article of a three-part series about building from source code. Check the following articles if you are looking for information about:
Before diving into this article, keep in mind that the System on Modules that are NAND-based do not support device tree overlays. In other words, you are only capable of customize a device tree by modifying the complete hardware device tree source. If you want information on how to update you NAND-based SoM, refer to Updating NAND-based modules from userspace - Updating the Device Tree.
Prerequisites
- Understand the basic concepts of Toradex Embedded Linux offerings, such as release cycles, distributions and images. This content is available at BSP Layers and Reference Images for Yocto Project Software.
- Follow the steps described in the article Build U-Boot from Source Code (optional).
- Follow the steps described on the Kernel Configuration and Kernel Compilation sections in the article Build Linux Kernel from Source Code (Mandatory).
- Follow the steps at the section Install the GNU Toolchain for Hard Float Calling Convention.
- Install the necessary tools and dependencies as explained in the section Install Tools and Dependencies.
Prepare the Host Machine for Cross-Compilation
Use version 9.2 or higher of the Arm releases binary toolchains to cross-compile software for Toradex modules:
- For 32 bit Arm: arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz
- For 64 bit Arm: arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz
You have to choose to download either the 32 bit or 64 bit Arm cross-toolchain, according to the architecture of your System on Module SoC. Select the correct one from the tabs below:
To install the toolchain on your host machine, download and unpack the tar.xz file. From the command-line:
$ cd ~
$ wget -O arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz "https://developer.arm.com/-/media/Files/downloads/gnu/12.3.rel1/binrel/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz?rev=9d73bfdd64a34550b9ec38a5ead7c01a&hash=774AAE1A6D6996CFB89FD7E367C0B59B"
$ tar xvf arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz
$ ln -s arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-linux-gnueabihf gcc-linaro
Or you can download the toolchain from Arm website.
The U-Boot and Linux makefiles use the environment variables ARCH/CROSS_COMPILE to configure and call the compiler correctly. Therefore, these environment variables must be exported in any shell instance that will run configure/compile commands to build U-Boot or Linux for the target module.
$ export ARCH=arm
$ export DTC_FLAGS="-@"
$ export PATH=~/gcc-linaro/bin/:$PATH
$ export CROSS_COMPILE=arm-none-linux-gnueabihf-
You can put those commands into a file and source that file to export it more easily, e.g.:
$ echo "export ARCH=arm" >> ~/export_compiler
$ echo "export DTC_FLAGS='-@'" >> ~/export_compiler
$ echo "export PATH=~/gcc-linaro/bin/:$PATH" >> ~/export_compiler
$ echo "export CROSS_COMPILE=arm-none-linux-gnueabihf-" >> ~/export_compiler
$ source ~/export_compiler
To install the toolchain on your host machine, download and unpack the tar.xz file. From the command-line:
$ cd ~
$ wget -O arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz "https://developer.arm.com/-/media/Files/downloads/gnu/12.3.rel1/binrel/arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz?rev=cf8baa0ef2e54e9286f0409cdda4f66c&hash=4E1BA6BFC2C09EA04DBD36C393C9DD3A"
$ tar xvf arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz
$ ln -s arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu gcc-linaro
Or you can download the toolchain from Arm website.
The U-Boot and Linux makefiles use the environment variables ARCH/CROSS_COMPILE to configure and call the compiler correctly. Therefore, these environment variables must be exported in any shell instance that will run configure/compile commands to build U-Boot or Linux for the target module.
$ export ARCH=arm64
$ export DTC_FLAGS="-@"
$ export PATH=~/gcc-linaro/bin/:$PATH
$ export CROSS_COMPILE=aarch64-none-linux-gnu-
You can put those commands into a file and source that file to export it more easily, E.g.:
$ echo "export ARCH=arm64" >> ~/export_compiler
$ echo "export DTC_FLAGS='-@'" >> ~/export_compiler
$ echo "export PATH=~/gcc-linaro/bin/:$PATH" >> ~/export_compiler
$ echo "export CROSS_COMPILE=aarch64-none-linux-gnu-" >> ~/export_compiler
$ source ~/export_compiler
Install Tools and Dependencies
Build Host
You need some essential build tools to compile the Kernel or DTC. Most are likely part of your distro's standard install.
For Debian/Ubuntu:
$ sudo apt-get install bc build-essential git libncurses5-dev lzop perl libssl-dev bison flex
Device Tree Compiler (DTC) Tool
Device tree overlays compilation needs a device tree compiler (DTC) tool. We recommend DTC version 1.6.0 or higher.
You can build the latest version (DTC 1.6.0 at the time of writing) from the source:
$ git clone git://git.kernel.org/pub/scm/utils/dtc/dtc.git -b v1.6.0 ~/dtc
$ cd ~/dtc
$ make
$ export PATH=$HOME/dtc/:$PATH
on Ubuntu 22.04, there have been reported DTC build errors libfdt/libfdt.h:251:28: warning: array subscript ‘struct fdt_header[0]’ is partly outside array bounds of ‘unsigned char[4]’ [-Warray-bounds]
.
To disable treating errors as warnings, you can remove the flag -Werror
from the CFLAGS
on the Makefile.
We have not evaluated the consequences of doing it, do it at your own risk!
Device Tree Overlays Version Information
The Device Tree Overlays branch matches perfectly with the Kernel branch, which you can find at Kernel Version Information. In other words, for upstream based modules, the branch is master
, and for downstream based modules is toradex_5.15-2.<n>.x-imx
.
Device Tree Overlays Source
Device Tree Overlays (DTO) provide a way to modify the overall device tree without recompiling the complete device tree. See the Device Tree Overlays (Linux) article for more information about how to write a DTO for the Toradex Embedded Linux BSP.
Obtain the device tree overlays source code using Git:
$ cd ~/workdir
$ git clone -b <branch> git://git.toradex.com/device-tree-overlays.git
$ cd device-tree-overlays/
Replace <branch>
by the Device Tree Overlays Git Branch for your specific configuration. As mentioned in the section Device Tree Overlays Version, the branch will match the kernel version. For example, if you are looking for a DTO for a module using a NXP downstream-based kernel, you'll find the right overlays at toradex_5.15-2.1.x-imx
. If looking for DTO for Verdin AM62, you will find at toradex_ti-linux-5.10.y_bringup
.
Should your company firewall/gateway inhibit the git protocol, you may use HTTP or HTTPS instead (e.g. git clone https://git.toradex.com/device-tree-overlays.git
).
Device Tree Overlays Compilation using make
Toradex maintains a Makefile to compile the overlays that is into the overlays
directory. You also need a folder where the Linux Kernel is checked out and configured on the same kernel version. Then the path to this Kernel can be set on the environment variable, and the overlays be built with make.
$ cd overlays/
$ export STAGING_KERNEL_DIR=/home/user/workdir/linux-toradex
$ make
You can also add your own DTBO by simply adding it to the Makefile
located in the overlays
folder:
dtb-y += <my overlay>.dtbo
Manual Device Tree Overlays Compilation
Depending on the module, different device tree overlays are used. Furthermore, device tree overlays require a base device tree to describe the system's hardware (see Device Tree Customization for details). To pre-process a device tree overlay (where ../../linux-toradex/ is the path to your kernel sources and verdin-imx8mm_lt8912_overlay.dts is your device tree overlay:
$ cd overlays/
$ cpp -nostdinc -I ../../linux-toradex/arch/arm64/boot/dts -I ../../linux-toradex/include -undef -x assembler-with-cpp verdin-imx8mm_lt8912_overlay.dts verdin-imx8mm_lt8912_overlay.dts.preprocessed
To compile a device tree overlay from above pre-processed device tree overlay source (where verdin-imx8mm_lt8912_overlay.dtbo
is the final device tree overlay binary):
$ dtc -@ -Hepapr -I dts -O dtb -i ../../linux-toradex/arch/arm64/boot/dts/ -o verdin-imx8mm_lt8912_overlay.dtbo verdin-imx8mm_lt8912_overlay.dts.preprocessed
Device Tree Overlays Update
For instructions of how to deploy a Device Tree Overlay to a target, see the Device Tree Overlays (Linux) article.