Jump to content

Create a Custom Device Tree

From RidgeRun Developer Wiki
Yocto Documentation
Release 2026


Follow us on: YouTube Twitter LinkedIn Email Share this page

Share This Page

Preferred Partner Logo 3 Partner Program Banner



When developing your own embedded system, you will likely need to customize the hardware configuration to meet your product's specific requirements. Unlike a standard NVIDIA Jetson development kit, your product may require additional peripherals, custom drivers, different GPIO assignments, or modifications to existing hardware configurations.

Linux drivers use the device tree to discover hardware and read its configuration. For that reason, a product commonly needs its own device tree instead of modifying the device tree maintained by NVIDIA or meta-tegra.

This guide shows how to create a product-specific device tree in our custom layer, compile it with meta-tegra, select it from our custom machine, and confirm that the board booted with it.

Prerequisites

Before continuing, complete Create a Custom Machine. The BitBake environment must be loaded, meta-myproduct must be enabled, and MACHINE = "myproduct-agx-orin" must be selected.

This guide adds the myproduct-devicetree recipe and tegra234-p3737-0000+p3701-0000-myproduct.dtb to that existing layer and machine.

What you will have by the end of this Wiki

We will add one recipe and one DTS file to meta-myproduct:

meta-myproduct/
├── conf/
│   └── machine/
│       └── myproduct-agx-orin.conf
└── recipes-bsp/
    └── myproduct-devicetree/
        ├── myproduct-devicetree_1.0.bb
        └── myproduct-devicetree/
            └── tegra234-p3737-0000+p3701-0000-myproduct.dts

The new DTS will include the complete NVIDIA AGX Orin development-kit device tree and add one product-specific compatible string. This gives us a small, verifiable change before we begin adding real product hardware.

1. Check the device tree currently selected by the machine

Make sure the BitBake environment is loaded and that local.conf selects the custom machine from the previous guide:

MACHINE = "myproduct-agx-orin"

Inspect the current provider and device-tree file:

bitbake-getvar 'PREFERRED_PROVIDER_virtual/dtb'
bitbake-getvar KERNEL_DEVICETREE

Before adding our recipe, the values inherited from jetson-agx-orin-devkit should resolve to:

PREFERRED_PROVIDER_virtual/dtb="nvidia-kernel-oot-dtb"
KERNEL_DEVICETREE="tegra234-p3737-0000+p3701-0000-nv.dtb"

The existing NVIDIA DTB gives us the base for the product-specific device tree.

2. Create the recipe structure

Create a directory for the device-tree recipe and its source files:

mkdir -p \
    "$YOCTO_WORKSPACE/meta-myproduct/recipes-bsp/myproduct-devicetree/myproduct-devicetree"

The recipe and its source directory intentionally share the myproduct-devicetree name. BitBake automatically searches this directory for files listed with file:// in SRC_URI.

3. Create the custom DTS

Create the DTS:

cat > "$YOCTO_WORKSPACE/meta-myproduct/recipes-bsp/myproduct-devicetree/myproduct-devicetree/tegra234-p3737-0000+p3701-0000-myproduct.dts" <<'EOF'
#include "tegra234-p3737-0000+p3701-0000-nv.dts"

/ {
    compatible = "mycompany,myproduct-agx-orin",
                 "nvidia,p3737-0000+p3701-0000",
                 "nvidia,p3701-0000",
                 "nvidia,tegra234";
};
EOF

The #include statement reuses NVIDIA's complete AGX Orin development-kit device tree. Our DTS can then override properties or add nodes without copying the full upstream source into the product layer.

The product-specific compatible string is listed first because it describes the most specific hardware. The NVIDIA strings are preserved so existing drivers can continue matching the module and SoC.

For this first example, changing compatible is enough to prove that our DTB was compiled, packaged, flashed, and loaded. Product-specific peripherals and properties can be added later to the same file.

4. Create the device-tree recipe

Create the recipe:

cat > "$YOCTO_WORKSPACE/meta-myproduct/recipes-bsp/myproduct-devicetree/myproduct-devicetree_1.0.bb" <<'EOF'
SUMMARY = "Device tree for the MyProduct AGX Orin platform"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

inherit tegra-devicetree

COMPATIBLE_MACHINE = "(myproduct-agx-orin)"

S = "${UNPACKDIR}"

SRC_URI = "file://tegra234-p3737-0000+p3701-0000-myproduct.dts"
EOF

The tegra-devicetree is a meta-tegra class that:

  • makes the recipe a proper device tree provider acceptable for the meta-tegra build;
  • supplies the Tegra234 include paths needed by the #include statement;
  • compiles the DTS into a DTB;
  • installs and deploys the resulting DTB.

Because NVIDIA's sources come from nvidia-kernel-oot, we only need to keep our product-specific wrapper and changes in meta-myproduct.

5. Select the custom provider from the machine

Replace the machine file, keeping the parent machine and adding the provider and DTB selections after the require statement:

cat > "$YOCTO_WORKSPACE/meta-myproduct/conf/machine/myproduct-agx-orin.conf" <<'EOF'
#@TYPE: Machine
#@NAME: MyProduct AGX Orin
#@DESCRIPTION: MyProduct machine based on the NVIDIA AGX Orin devkit

require conf/machine/jetson-agx-orin-devkit.conf

PREFERRED_PROVIDER_virtual/dtb = "myproduct-devicetree"
KERNEL_DEVICETREE = "tegra234-p3737-0000+p3701-0000-myproduct.dtb"
EOF

PREFERRED_PROVIDER_virtual/dtb tells BitBake to use our recipe instead of the default nvidia-kernel-oot-dtb provider.

KERNEL_DEVICETREE selects the DTB used by the boot and flashing flow. The value ends in .dtb, even though the source file ends in .dts.

These assignments belong in the custom machine because they describe the hardware used by that machine.

6. Validate the configuration

Check the effective provider and DTB selection:

bitbake-getvar 'PREFERRED_PROVIDER_virtual/dtb'
bitbake-getvar KERNEL_DEVICETREE

The values should now resolve to:

PREFERRED_PROVIDER_virtual/dtb="myproduct-devicetree"
KERNEL_DEVICETREE="tegra234-p3737-0000+p3701-0000-myproduct.dtb"

Build the device-tree recipe by itself:

bitbake myproduct-devicetree

The deployed DTB should be available at a path similar to:

$YOCTO_WORKSPACE/bitbake-builds/meta-tegra-wrynose/build/tmp/deploy/images/myproduct-agx-orin/devicetree/tegra234-p3737-0000+p3701-0000-myproduct.dtb

This confirms that the custom DTS can include the NVIDIA source and compile successfully.

7. Build and flash the image

Build the product image:

bitbake myproduct-image

The meta-tegra image flow depends on the selected virtual/dtb provider and copies the DTB named by KERNEL_DEVICETREE into the Jetson flashing package. No additional image configuration is required.

The output directory should contain a package similar to:

$YOCTO_WORKSPACE/bitbake-builds/meta-tegra-wrynose/build/tmp/deploy/images/myproduct-agx-orin/myproduct-image-myproduct-agx-orin.rootfs.tegraflash-tar.zst

Flash the image on the AGX Orin development kit by following Flashing the Board.

8. Confirm the device tree on the target

After the board boots, print the active compatible strings:

tr '\0' '\n' < /sys/firmware/devicetree/base/compatible

The output should begin with:

mycompany,myproduct-agx-orin
nvidia,p3737-0000+p3701-0000
nvidia,p3701-0000
nvidia,tegra234

Seeing mycompany,myproduct-agx-orin confirms that the board booted with the product-specific device tree rather than the original development-kit DTB.

From this known baseline, we can add the nodes and properties required by the product's custom drivers and peripherals while continuing to inherit NVIDIA's upstream AGX Orin device-tree definition.

Cookies help us deliver our services. By using our services, you agree to our use of cookies.