Use Device Tree Overlays to Patch Your Device Tree

The device tree overlays mechanism in Digi Embedded Yocto 3.0 makes it much easier to fix up your original device tree with small changes. Here are some use cases where you may want this capability:

  • You just need to make a small change on the device tree.
  • You want to test an interface of your Digi embedded development kit that is not enabled on the device tree by default because it is multiplexed with a different device.
  • You want to change a UART to work with four wires instead of two.
  • You need to enable or disable variants of your product with different hardware.

You can make these kinds of changes without defining a complete device tree and without having to modify the original one. The device tree is a data structure that describes the hardware components available on an embedded system. The Linux kernel queries the device tree to find out which drivers to load during boot. But, complex embedded SOMs and carrier boards can populate many different SOM/board variants and feature combinations, which would require multiple device tree blobs.

The Digi Embedded Yocto 3.0 release incorporates a new mechanism for handling device tree files: device tree overlays. Device tree overlays are special device tree blob fragments that allow you to override specific parts of a device tree on-the-fly, before booting the operating system. A 'blob' is the compiled version of a device tree source file. This allows you to combine a base device tree with optional elements without needing to recompile a device tree for just a tiny change.

The custom Digi U-Boot dboot command loads the base device tree, parses the contents of a comma-separated list of device tree overlay filenames, and sequentially loads and applies each overlay over the base device tree.

Note: At this time, this functionality is only available for the Digi ConnectCore 8X and Digi ConnectCore 8M Nano platforms.

This article describes how you can create, build, and deploy a device tree overlay to take advantage of this mechanism.

Device Tree Overlays Format

A device tree overlay contains modifications that can be applied to an existing device tree blob. The format of device tree overlays is slightly different than the typical *.dts and *.dtsi files:

Sample device tree overlay

#include <dt-bindings/gpio/gpio.h>
 
/dts-v1/;
/plugin/;
 
/ {
    fragment@0 {
        target-path = "/";
        __overlay__ {
            foo {
                compatible = "custom,foo";
                status = "okay";
                gpio = <&gpio3 14 GPIO_ACTIVE_HIGH>;
            };
        };
    };
 
    fragment@1 {
        target = <&bar>;
        __overlay__ {
            my-boolean-property;
            status = "okay";
        };
    };
};

Let’s examine the different parts.

Device tree header

#include <dt-bindings/gpio/gpio.h>

/dts-v1/;
/plugin/;

Device tree overlays are built standalone, without any connection to the device tree they will modify. For this reason, they must include headers and specifiers just like a regular device tree file.

Root node and fragments

/ {
    fragment@0 {
        [...]
    };
 
    fragment@1 {
        [...]
    };
 
    ...
};


Device tree overlays must have a root node. Within the root node, you must insert fragments: one fragment for each node of the original device tree that you want to modify.
 

Structure of a fragment

Fragment with absolute path
fragment@0 {
    target-path = "/";
    __overlay__ {
        foo {
            compatible = "custom,foo";
            status = "okay";
            gpio = <&gpio3 14 GPIO_ACTIVE_HIGH>;
        };
    };
};
Fragment with relative path
fragment@1 {
    target = <&bar>;
    __overlay__ {
        my-boolean-property;
        status = "okay";
    };
};

Each fragment has two elements:

  • One of these two properties:
    • target-path with the absolute path to the node that the fragment is going to modify, or
    • target with the relative path to the node alias (prefixed with an ampersand symbol) that the fragment is going to modify.
  • A node __overlay__ with the modifications to apply to the referred node. Such modifications can be:
    • New nodes (they are added)
    • New properties (they are added)
    • Existing properties (they are overridden with the new value)

Note: Overlays can only perform constructive changes such as adding or modifying nodes or properties. They cannot be used to perform destructive changes such as deleting nodes or properties.

In the examples above:

  • fragment@0 is adding the node foo, with several properties, to the root node /.
  • fragment@1 is modifying the node with alias bar, with several properties that can be new or existing ones.

Create the device tree overlay

Create a device tree overlay inside the Linux kernel source tree, where the regular device tree files are located. For Digi ConnectCore® 8X and ConnectCore® 8M Nano this is arch/arm64/boot/dts/digi. In this example, the device tree overlay file name is custom_ov_foo.dts. For Digi device tree overlay naming conventions, see File naming conventions.

Build the device tree overlay

To have the Linux kernel build the device tree overlay, add it to arch/arm64/boot/dts/digi/Makefile with the extension dtbo:

Makefile
dtb-y += custom_ov_foo.dtbo

To have Digi Embedded Yocto consider the overlay as an image artifact worth copying to the deploy directory, add the overlay filename to the KERNEL_DEVICETREE variable in your project’s conf/local.conf file:
 

conf/local.conf
KERNEL_DEVICETREE += " custom_ov_foo.dtbo"

Note: Be sure to include the required white space when appending a value to an array variable. This not only copies the compiled device tree overlay blob to the deploy directory, but it also adds the file to the *.boot.vfat image, together with the rest of device tree files for the platform.

Deploy the device tree overlay

There are two ways to deploy the device tree overlay blob to the target:

  • Copy the file to the linux partition
  • Program the full artifact image to the linux partition

Copy the file to the linux partition

From U-Boot

Put the .dtbo file in your TFTP exposed folder. Then use the updatefile command to copy it to the linux partition:

=> updatefile linux tftp custom_ov_foo.dtbo

From the operating system

  1. On your target, re-mount the linux partition as read-write. (It’s mounted as read-only by default).

    ~# mount -o remount,rw /mnt/linux
  2. Copy the file from the host to the target inside the re-mounted folder.

Program the image artifact to the linux partition

For instructions on updating the full image artifact, see Update firmware from U-Boot.

Enable the device tree overlay

To use the device tree overlay, perform the following steps in U-Boot:

  1. Add the overlay filename to the comma-separated list in U-Boot variable overlays. (It may be initially empty):
     

    => env edit overlays 
    edit: custom_ov_foo.dtbo
  2. Run the dboot command to boot from the eMMC:

    => dboot linux mmc


For more information on the Digi device tree overlays mechanism, see the device tree overlays documentation topic.

Watch Our Recorded Webinar
Learn how to simplify and accelerate embedded development with Digi ConnectCore i.MX8 SOMs