Create a Custom Device Tree
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
#includestatement; - 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.