Device Tree Overlays Technical Overview
In this article, you will learn about Device Tree Overlays and how they facilitate modification and customization of the device tree. Device Tree Overlays allow you to add or modify device nodes and properties without the need to recompile the entire device tree. We will explore the concept of Device Tree Overlays in detail, covering their purpose, structure, creation, compilation, and deployment processes.
Device tree overlays are a powerful mechanism that enables customization of the device tree during boot. They provide a flexible and non-intrusive way to modify the device tree at runtime, allowing for on-the-fly customization without the need to rebuild and reboot the system.
Why Using Device Tree Overlays
Determining whether to use a Device Tree Overlay (DTO) or modify the full Device Tree (DT) depends on several factors. While DTOs are typically smaller and easier to understand than complete DT modifications, they have their limitations. Working with DTOs requires familiarity with the general DT syntax, and referencing the base DT is necessary to comprehend the overlay modifications being made. This raises the question of why DTOs are used if the full DT source still needs to be consulted and manipulated.
In many cases, making changes directly in the full DT source is more practical than employing DTOs. However, DTOs offer advantages of their own. They provide a convenient approach for implementing simple modifications, such as altering the
status property of a node. By utilizing DTOs, it is possible to maintain multiple configurations within the same DT. For example, a product that supports different types of displays can use a single base DT combined with different DTOs to customize the display settings accordingly.
At Toradex, DTOs are predominantly used in scenarios involving multiple configurations. DTOs provide a convenient evaluation experience for our customers, as they can easily switch between DTOs without modifying the entire DT. Eventually, customers may need to make modifications to the full DT, but using DTOs facilitates the evaluation process.
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.
Purpose and Benefits
Customization and Adaptability: DTOs enable hardware customization without the need to modify the base device tree. This flexibility is especially valuable when working with hardware platforms that support multiple configurations or when integrating new hardware components into an existing system. DTOs allow for specific modifications and additions to suit the requirements of a particular setup, providing adaptability to diverse hardware environments.
Selective Modification: Rather than managing separate device tree files for different hardware configurations, DTOs allow for selective modifications to be applied on top of a base device tree. This approach streamlines development, reduces code duplication, and enhances the maintainability of the system. Developers can focus on the specific changes they need to make without the complexity of dealing with the entire device tree structure.
Ease of Evaluation: DTOs facilitate the evaluation process by providing a convenient way for users to switch between different configurations without modifying the entire device tree. This capability is particularly valuable during the evaluation phase of a project when multiple configurations are being tested. DTOs offer a seamless way to compare different setups and determine the optimal configuration without extensive modifications to the underlying device tree.
Simplified Development and Maintenance: DTOs simplify the development and maintenance processes by providing a clear and focused approach to hardware configuration. Developers can work with smaller and more manageable DTOs, making it easier to understand and modify specific aspects of the device tree. This approach reduces the complexity of the development cycle, enhances code maintainability, and minimizes the potential for errors and conflicts.
Compatibility and Portability: DTOs are designed to work in conjunction with the base device tree, ensuring compatibility across different hardware configurations. The use of DTOs allows for portable configurations that can be easily transferred and applied to different systems without the need for significant modifications or rebuilding the entire device tree.
Limited Error Handling: DTOs are typically applied without extensive error checking or validation. If an overlay contains errors or conflicts, the application process may fail or lead to unexpected behavior. It is crucial to thoroughly validate overlays to ensure they are error-free and compatible with the target device tree.
Overlay Compatibility: Overlays must be designed and tested specifically for the target device tree. Incompatibilities between the overlay and the base device tree may arise, causing conflicts or unexpected behavior. It is important to ensure that overlays are compatible with the target system to avoid potential issues.
It's essential to differentiate between Device Tree Overlays and Device Trees. While both serve the purpose of describing hardware configurations, they have distinct characteristics and use cases. Device Tree Overlays are applied on top of an existing Device Tree to modify or extend the hardware configuration. Overlays are loaded and applied after the kernel has booted, allowing for runtime changes without recompiling the entire device tree. This flexibility makes overlays particularly useful in scenarios where hardware configurations need to be adapted or customized during system operation.
*.dts): Accordingly to Device Tree Specifications, the device tree overlay is defined using the Device Tree Source (DTS) language, which is a textual representation of a device tree. The file containing structures in this format has the
.dtsextension, but is slowly changing from
.dtso(https://email@example.com/). For further information on the device tree source format, refer to Device Tree Technical Overview.
*.dtbo): Accordingly to Device Tree Specifications, the Device Tree Blob (DTB) format serves as a binary encoding used for exchanging devicetree data between different software programs. When an operating system boots, the firmware passes a DTB to the OS kernel. This DTB, which is a flat binary representation, contains the necessary information about the hardware configuration that the kernel needs to interact with the devices. The overlay binary is loaded by the bootloader and bound to the kernel at boot time. The file containing this binary has the
Device Tree Overlays Basic Syntax
The syntax of a DTO is very similar to that of a full DT, it is a simple tree structure of nodes and properties. Properties are key-value pairs, and node may contain both properties and child nodes. If you want more in-depth information about syntax and advanced topics, refer to Device Tree Technical Overview, https://elinux.org/Device_Tree_Usage.
The following example is a simple DTO:
compatible = "toradex,apalis_imx6q";
status = "okay";
status = "okay";
- There’s your typical
/dts-v1/;header but there’s also a DTO specific header
/plugin/;, which differentiates the file as a DTO rather than a DT.
- There’s a root node (
/) with a property
compatible, which sets the compatibility for the DTO to be applied on top of the correct DT.
&mxcfb4are nodes being referenced by their label, with properties such as
Choosing, Writing and Deploying Device Tree Overlays
The process of choosing, writing and deploying a Device Tree Overlay comprises in some steps:
- Choose an available Device Tree Overlay from source or already compiled.
- Alternatively, write a new one accordingly to your particular needs and your custom hardware.
- Compile the DTO source file, if needed.
- Deploy the compiled DTO to your custom OS image and enable it.
Take a look at this process on the following sections. Don't worry about learning how to perform each steps, as you will be pointed to the right resources by the end.
Choose the Base Device Tree Overlay
You can choose a readily-available overlay if it covers the hardware configuration you need. Toradex offers a set of DTOs (git.toradex.com/device-tree-overlays) that are pre-compiled into our modules and can be used out-of-the-box by just enabling it as necessary.
In some cases, you will have to write, from scratch, your overlay. For this, you can base yourself into one of the provided overlays that corresponds to your hardware platform as a starting point, dive into Toradex documentation and add your customization.
Write the Device Tree Overlay
It is done by modifying the device tree nodes, properties, and values to reflect your desired hardware configuration. There are typical customizations done to a device tree:
- Locate and Disable/Delete Former Function Definitions: The first step is to locate the existing function definition that you wish to modify or remove from the device tree. This could be a particular peripheral, pinmux configuration, or any other hardware-related functionality. Once you have identified the function definition, you can either disable or delete it by changing the
delete-property should be used only on device tree files and not on device tree overlays. On device tree overlays they will not have the expected effect of deleting properties/nodes from the base device tree.
Define a new pinctrl with GPIO pinmux definitions: The next step is to define a new pinctrl (pin control) configuration that includes your desired GPIO pinmux definitions for the selected pins. The pinctrl configuration determines how the pins are configured and assigned their functionalities. Create a new pinctrl node in the device tree, specifying the necessary properties such as the pin names or numbers, pinmux settings, and any other relevant parameters. This new pinctrl configuration will ensure that the selected pins are properly configured according to your requirements.
Add the pinctrl to the iomux group: Finally, you need to add the newly defined pinctrl configuration to the appropriate iomux (input/output multiplexer) group in the device tree. The iomux group represents a logical grouping of pins with similar functionalities. Locate the relevant iomux group node in the device tree and add a reference to the newly defined pinctrl configuration. This association ensures that the pinmux settings from the pinctrl configuration are applied to the pins within the iomux group, effectively assigning the desired functionalities to the pins.
Compile the Device Tree Overlay
After making changes to the device tree, it needs to be compiled into the
*.dtbo file that can be loaded by the bootloader. This can be done using the Device Tree Compiler (DTC) tool, TorizonCore Builder or even Yocto Project:
Compile from source code: Refer to Build Device Tree Overlays from Source Code to configure your build environment and compile the device trees using
make(makefile compilation) or
dtc(single manual compilation). The compiled file with this process can be used booth on Torizon OS or custom Embedded Linux OS images.
Yocto Project: There are currently two recipes that handle device tree overlays: for upstream-based images, the meta-toradex-bsp-common/recipes-kernel/linux/device-tree-overlays-mainline_git.bb and for downstream-based images, the meta-toradex-nxp/recipes-kernel/linux/device-tree-overlays_git.bb. You can, for instance, write your own bbappends to add your device tree overlays repository.
TorizonCore Builder: Refer to Device Tree Overlays on Torizon to understand the TorizonCore Builder and how to compile, add and apply your device tree overlay.
Deploy and Enable the Device Tree Overlays
To deploy a device tree overlay, you can simply copy the binary file (
*.dtbo) to the your device on the
/dtb/overlays/ directory in
/boot, or add it on your image using Yocto or TorizonCore Builder.
Binary file: Refer to Deploying a Device Tree Overlay section for more details. If you want information on how to update you NAND-based SoM, refer to Updating NAND-based modules from userspace - Updating the Device Tree.
TorizonCore Builder: Refer to Device Tree Overlays on Torizon to understand how to deploy and apply your device tree overlay.
Yocto Project: The class meta-toradex-bsp-common/classes/image_type_tezi.bbclass is responsible for adding overlays that will be applied during boot time. It uses the variable
TEZI_EXTERNAL_KERNEL_DEVICETREE_BOOTthat is set by default in our machine configuration files, either
machine.inc. Then you need to either append to or override the variable. One possibility is to use a
<machine>-extra.conffile. You can, for instance, write your own bbappends to add your device tree overlays repository instead of ours.
It is important to know that you can deploy Device Tree Overlays to your device and having it disable/enabled in different scenarios. Some overlays are pre-enabled by default, refer to the Pre-enabled Device Tree Overlays section for this.
Now that you understand the basics about Device Tree Overlays and how to use it, you are ready to your First Steps With Device Tree Overlays, where you will put in practice what you learnt here.