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 article Build Linux Kernel from Source Code until you have a compiled kernel.
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 with the command below. Alternatively, you can obtain the toolchain directly from the Arm website.
$ 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-arm
U-Boot and Linux Makefiles use environment variables such as ARCH and CROSS_COMPILE to configure and call the appropriate compiler. Therefore, you must set these variables in the current shell when compiling the Kernel or U-Boot.
To facilitate this process, create an export-compiler-32 setup file with the commands below.
export ARCH=arm
export PATH=${HOME}/gcc-linaro-arm/bin/:${PATH}
export DTC_FLAGS='-@'
export CROSS_COMPILE=arm-none-linux-gnueabihf-
Please note that creating the setup file is not mandatory, it serves only to simplify executing the commands above. You could also run each command individually on every new shell.
Source the setup file. Note that you will also need to source it every time you open a new shell to build the Kernel/U-Boot.
$ source ~/export-compiler-32
To install the toolchain on your host machine, download and unpack the tar.xz file with the command below. Alternatively, you can obtain the toolchain directly from the Arm website.
$ 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-aarch64
U-Boot and Linux Makefiles use environment variables such as ARCH and CROSS_COMPILE to configure and call the appropriate compiler. Therefore, you must set these variables in the current shell when compiling the Kernel or U-Boot.
To facilitate this process, create an export-compiler-64 setup file with the commands below.
export ARCH=arm64
export PATH=${HOME}/gcc-linaro-aarch64/bin/:${PATH}
export DTC_FLAGS='-@'
export CROSS_COMPILE=aarch64-none-linux-gnu-
Please note that creating the setup file is not mandatory, it serves only to simplify executing the commands above. You could also run each command individually on every new shell.
Source the setup file. Note that you will also need to source it every time you open a new shell to build the Kernel/U-Boot.
$ source ~/export-compiler-64
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 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.
Clone the device tree overlays source code repository:
$ cd ~/workdir
$ git clone -b <branch> git://git.toradex.com/device-tree-overlays.git
$ cd device-tree-overlays/
The Device Tree Overlays repository <branch> must match the Kernel branch for which you are building the overlay.
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
Go into the overlays directory and Compile the device tree overlays using make. For this step you need to link the directory where you have compiled the kernel, as instructed in the Prerequisites. Keep in mind that you must be on the same branch/version on both the kernel and the device tree overlays repositories:
$ 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.