Skip to main content

Modifying the Device Tree for Tachyon

The Device Tree is essentially a hardware description file that informs the Linux kernel (and bootloader) about the hardware components, their addresses, and how they are connected. For Tachyon, many of the currently non-working features can be enabled or fixed by updating the Device Tree Source (DTS) to match the actual hardware wiring. If you want to enable a peripheral or adjust a hardware parameter, editing the DTS is often required.

Why Modify the Device Tree?

Editing the Device Tree is useful for two main cases:

  1. Enabling already supported hardware:
    Many features (such as displays, I2C devices, or GPIOs) are already defined in the base Device Tree but disabled by default. You can enable these by editing the existing DTS or using overlays.

  2. Adding or porting new hardware:
    If you’re connecting new hardware (such as sensors, LEDs, or expansion boards) that the current Device Tree does not describe, you can add new device nodes or overlays to inform the kernel about them. This allows Linux to load the correct drivers and expose new interfaces automatically.

Where is the Device Tree?

On Tachyon’s Ubuntu 24.04 build, the primary Device Tree is provided by U-Boot (which loads a compiled DTB during boot). The file is:

dts/upstream/src/arm64/qcom/qcm6490-tachyon.dts

Editing the Device Tree Source

  1. Open the DTS file: Use a text editor to open the Tachyon board DTS. You’ll see a hierarchical structure of nodes representing devices. For instance:

    • Clocks, regulators, pinctrl settings.
    • Serial ports (serial@ nodes).
    • I2C buses with attached devices (like perhaps a fuel gauge or the SYSCON microcontroller interface).
    • GPIO controllers (e.g., the SoC’s TLMM for onboard pins, or an I/O expander chip if one exists).
    • USB, PCIe, etc., with their status (often status = "okay" to enable, or "disabled" to disable).
    • Display and camera connectors (might be present but disabled).
    • LEDs (an LED might be defined as a GPIO-controlled device).
  2. Make the desired changes: Some common modifications:

    • Enable a device: Many nodes might be present but marked status = "disabled". To enable, change it to "okay". For example, if there is a gpio node or i2c1 bus that’s disabled, enabling it might allow the kernel to load a driver.
    • Add a new node: If a piece of hardware is missing in the DTS, you can add it. For instance, if Tachyon has a specific IMU sensor not listed, add an I2C device node under the appropriate bus with its compatible string and interrupt line.
    • Adjust properties: Update addresses, GPIO assignments, etc., if they are incorrect. For example, if the activity LED is connected to GPIO X but the DTS currently points to a wrong GPIO, fix the number and the controller.
    • Pin configuration: You might need to configure pin multiplexing for certain features (like turning on UART or SPI on certain pins). This is usually done with pinmux settings in the DTS. Tachyon’s DTS may include a pin control section; ensure the pins for the feature you want are properly configured and that the corresponding device node references that pin config.
  3. Example – Enabling GPIO/I2C expander: Suppose Tachyon uses a PCA9536 I/O expander for extra GPIO pins on the header (just hypothetical). If it’s connected to I²C, the DTS might need a node like:

/dts-v1/;
/* Some I2C controller node */
i2c2: i2c@78b6000 {
status = "okay";
io_expander: gpioexp@20 {
compatible = "nxp,pca9536";
reg = <0x20>;
gpio-controller;
#gpio-cells = <2>;
};
};

And perhaps also ensure pinctrl for that I2C bus is enabled. This would expose those expander GPIOs to Linux.

  1. Example – Fixing the LED: If the LED is on a certain GPIO, ensure there’s an leds section:
leds {
compatible = "gpio-leds";
status_led: tachyon-status {
label = "tachyon:status";
gpios = <&tlmm 42 GPIO_ACTIVE_HIGH>; /* &tlmm controller, line 42, active high (example) */
default-state = "off";
};
};

And make sure GPIO 42 (example) is not used elsewhere and that it corresponds to the actual wiring.

  1. Documenting your changes: It’s helpful to document in comments or commit messages what you changed and why (e.g., Enable SPI1 bus for external sensor on header pin X or Fix LED GPIO index).

Compiling the Device Tree

If you have the U-Boot build environment set up (from the previous “Modify U-Boot” page), simply re-run the U-Boot build after saving DTS changes:

make qcm6490_defconfig  # if not already configured
make -j$(nproc)

It will compile the DTS into a DTB as part of U-Boot. The U-Boot binary will then contain the updated DTB.

Alternatively, you can compile the device tree in isolation using the Device Tree Compiler:

sudo apt install device-tree-compiler  # if not installed
dtc -I dts -O dtb -o qcm6490-tachyon.dtb qcm6490-tachyon.dts

Replace with actual filenames. This produces a .dtb you could potentially test by overlaying in Linux (not persistent across boot) or by instructing U-Boot to load it.

However, typically, you’ll want to integrate it into U-Boot and flash the updated U-Boot, as described before.


Adding DTBO or Device Tree Overlays from User Space

Tachyon’s U-Boot supports loading Device Tree Overlays (DTBO) from the userdata partition, allowing you to modify or extend the hardware description without rebuilding U-Boot or the base DTS. This makes it possible to add peripherals, enable optional hardware, or test changes directly from user space.

Mounting the userdata partition (to access /mnt/userdata/boot)

Identify the userdata partition (examples below)

lsblk 
ls -l /dev/disk/by-partlabel

(Or by partition label if available)

Create the mount point and mount

sudo mkdir -p /mnt/userdata
sudo mount /dev/disk/by-partlabel/userdata /mnt/userdata

The overlays live under /mnt/userdata/boot

ls -la /mnt/userdata/boot

If this doesn't exist, make it:

mkdir -p /mnt/userdata/boot

By default this directory will be empty (especially if it was just created with the above command!). You need to add in the overlay file and the dtbo files to make it work.

How the Overlay System Works

During boot, U-Boot reads a configuration file called overlays.txt from /boot in the userdata partition. That file lists one or more .dtbo overlay files to apply on top of the base Device Tree (DTB) before handing it off to the Linux kernel.

Where do the dtbo files come from?

Essentially the u-boot source tree. They are also compiled from the u-boot source code. Example files are:

./dts/upstream/qcom/qcm6490-tachyon-rpi-touch-v2-7inch.dtbo
./dts/upstream/qcom/qcm6490-tachyon-rpi-touch-v2-5inch.dtbo
./dts/upstream/qcom/qcm6490-tachyon-vc4-kms-dsi-waveshare-panel-v2.dtbo

To generate these, follow the instructions in this link to download u-boot and build it:

Building u-boot

After compilation, these files are output as follows:

builder@7151b06cb48b:/project$ make -j8
...
DTCO dts/upstream/qcom/qcm6490-tachyon-rpi-touch-v2-5inch.dtbo
DTCO dts/upstream/qcom/qcm6490-tachyon-rpi-touch-v2-7inch.dtbo
DTCO dts/upstream/qcom/qcm6490-tachyon-vc4-kms-dsi-waveshare-panel-v2.dtbo
DTC dts/upstream/src/arm64/qcom/qcm6490-tachyon.dtb
SHIPPED dts/dt.dtb
COPY u-boot.dtb
CAT u-boot-dtb.bin
COPY u-boot.bin
LD u-boot.elf
OFCHK .config

You can push them to the device (if you build u-boot on a host) via adb:

adb push ./dts/upstream/qcom/qcm6490-tachyon-rpi-touch-v2-7inch.dtbo /mnt/userdata/boot

Or you can copy locally into the /mnt/userdata/boot directory if running on the device.

Lastly, and probably the most easy, you can just get some of the files from these docs and install them!

qcm6490-tachyon-rpi-touch-v2-5inch.dtbo

qcm6490-tachyon-rpi-touch-v2-7inch.dtbo

qcm6490-tachyon-vc4-kms-dsi-waveshare-panel-v2.dtbo

These files are themselves adapted from the files in the Rasberry Pi tree - you can fairly easily adapt other files from this tree in the same way. Feel free to ping us in the community if you want some help!

Example layout:

/mnt/userdata/boot/overlays.txt
/mnt/userdata/boot/*.dtbo << the files that are applied

Contents of overlays.txt for one of the displays:

overlays=qcm6490-tachyon-rpi-touch-v2-7inch.dtbo

And then this file has to be put into the directory as well.

Each overlay listed here will be applied sequentially at boot. U-Boot automatically locates the overlay files in /boot and merges them with the primary device tree using fdt_overlay_apply().

Example – Enabling the Raspberry Pi DisplayTouch v2

Suppose you want to use a Raspberry Pi Touch Display (v2) with Tachyon.

You can apply its corresponding overlay file qcm6490-tachyon-rpi-touch-v2-7inch.dtbo like so:

  1. Place the file:

Copy the .dtbo file to /boot on the userdata partition.

sudo cp qcm6490-tachyon-rpi-touch-v2-7inch.dtbo /mnt/userdata/boot/
  1. Add it to overlays.txt:
echo "overlays=qcm6490-tachyon-rpi-touch-v2-7inch.dtbo" | sudo tee /mnt/userdata/boot/overlays.txt
  1. Reboot the device.

On next boot, U-Boot will automatically apply this overlay, updating the live device tree before Linux starts.

  1. Verify the overlay:

Once booted, confirm the overlay was applied.

sudo fdtdump /sys/firmware/fdt | grep -i touch
dmesg | grep -i touch

Listing and Managing Overlay Files

All overlay files and the overlays.txt configuration are located under:

/mnt/userdata/boot/
├── overlays.txt
├── qcm6490-tachyon-rpi-touch-v2-7inch.dtbo
└── (any other overlays)

You can view or edit this directory freely from user space.

To apply multiple overlays, separate them with spaces in overlays.txt:

overlays=overlay1.dtbo overlay2.dtbo overlay3.dtbo

Creating Custom Overlays

If you need to make changes not already covered by an existing overlay (for example, enabling a GPIO expander or custom sensor), you can:

  1. Create a new DTS overlay:
/dts-v1/;
/plugin/;

/ {
fragment@0 {
target-path = "/";
__overlay__ {
tachyon-custom-led {
compatible = "gpio-leds";
led@1 {
label = "tachyon:extra";
gpios = <&tlmm 55 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
};
};
};
};
  1. Compile it into a DTBO:
dtc -I dts -O dtb -o my-overlay.dtbo my-overlay.dts
  1. Copy and list it in overlays.txt:
sudo cp my-overlay.dtbo /mnt/userdata/boot/
echo "overlays=my-overlay.dtbo" | sudo tee /mnt/userdata/boot/overlays.txt

If your modification cannot be achieved through overlays (for example, fundamental SoC-level changes or pinctrl remapping), you’ll need to modify and rebuild the base Device Tree as described in the earlier sections.

Unmounting the userdata partition

Flush writes and unmount cleanly:

sync
sudo umount /mnt/userdata

Testing Device Tree Changes

After installing your new U-Boot (with updated DT):

  • Boot into Ubuntu 24.04 on Tachyon.
  • Check the effects of your changes:
  • For new devices: see if they appear. For example, if you enabled an I2C device driver, does dmesg show it probed? Does ls /dev show a new device (like /dev/i2c-… or a new gpiochip for an expander)?
  • For GPIO/LED: does /sys/class/leds/ now contain “tachyon:status”? Can you control it by writing to the brightness file?
  • For interfaces like SPI/UART: can you open the device or see it with ls -l /dev (e.g., /dev/spidev* or /dev/ttyXYZ).
  • If enabling display or camera, you might see different behavior (though those often require driver code too).
  • If something crashes or doesn’t behave right, you might need to revise the DTS. Check dmesg for errors. The kernel will often log warnings if a device tree node is malformed or a driver can’t bind (for example, Failed to probe…).

Device Tree and Kernel Modules

Remember, enabling a device in DTS is one side of the coin; the other is having a driver in the kernel for that device. For example, adding a node for a device that has no driver built will do nothing visible. Make sure the kernel has the corresponding driver built (either as a module or built-in). If not, use the Kernel modification steps to enable that driver.

Submitting Device Tree Changes

If you have gotten a new part of Tachyon’s hardware working by updating the DTS, that’s great news for everyone:

  • Ensure your DTS changes are clean (no unrelated whitespace or debug changes).
  • Push the changes to your fork of tachyon-u-boot (or kernel, if relevant).
  • Open a Pull Request explaining what the change does (e.g., Enable GPIO expander and user LED on Tachyon).
  • We will review the DTS change. Sometimes, we might request confirmation of certain hardware details or testing results.
  • Once merged, these improvements will be in the next builds for all users.

Device Tree contributions are among the most impactful, because they often unlock hardware functionality without requiring deep kernel hacking.