11.7. Device Tree Build System and Custom Overlays¶
Important
This developer note is applicable to J722S devices with SDP 8.0.0. The device tree build system allows you to customize hardware initialization by enabling or disabling peripherals using device tree overlays.
11.7.1. Introduction¶
The QNX BSP includes support for building custom startup files that use device tree (DTS) and device tree overlays (DTSO) to configure which peripherals are initialized. This feature allows you to:
Build with the default hardware configuration (all devices enabled)
Build with specific peripherals disabled via overlays
Build with specific peripherals enabled via overlays
Customize the QNX hardware initialization (
hw_init.c) based on your device tree configuration
This guide explains how to use the build system to generate a custom startup file with your chosen device tree configuration. It assumes that the device tree source files already exist in your repository.
11.7.2. Device Tree Files Location¶
For J722S devices, device tree files are located in ${PSDK_QNX_PATH}/qnx/utils/dt/dts/j722s/:
Base Device Tree Files:
Minimal DTS:
j722s-hw-init.dts— Contains only the nodes required by QNX hardware initialization. This is the default base DTS used when building with device tree overlays.Full Preprocessed DTS:
k3-j722s-qnx-preprocessed.dts— The complete device tree with all includes expanded. This file is provided for reference and debugging purposes.
Overlay Files:
Device tree overlays are located in ${PSDK_QNX_PATH}/qnx/utils/dt/dts/j722s/overlay/. Overlay files follow a naming convention:
Enable overlays:
enable_<device>.dtso— Enables the specified device (setsstatus = "okay")Disable overlays:
disable_<device>.dtso— Disables the specified device (setsstatus = "disabled")
For example:
enable_dss0.dtsoanddisable_dss0.dtso— Control the DSS0 display subsystemenable_gpu.dtsoanddisable_gpu.dtso— Control the GPUenable_main_i2c0.dtsoanddisable_main_i2c0.dtso— Control I2C0 controller
There are approximately 28 enable/disable overlay pairs available for J722S devices, covering common peripherals such as display, GPU, USB, SD card, Ethernet, and serial interfaces.
11.7.2.1. Available Devices¶
The following devices can be controlled via overlays for J722S:
Display: dss0, dss1
Compute: gpu
USB: usb0, usb1, usbss0, usbss1
Storage: sdhci0, sdhci1, ospi0
Serial: Main I2C (main_i2c0, main_i2c1, main_i2c2)
Networking: Ethernet (cpsw3g, cpsw3g_mdio)
High-Speed: Serdes (serdes0, serdes_wiz0)
Pin Control: Various peripheral pin configurations
Clocks and PHY: Device clock and PHY configurations
11.7.3. Building Without Device Tree (Default Mode)¶
By default, the BSP builds without device tree infrastructure. In this mode:
All devices are enabled (legacy behavior)
No device tree headers are generated
Device tree overlays are not applied
The build is backward compatible with existing configurations
To build without device tree:
cd ${PSDK_QNX_PATH}
make all SOC=j722s
Alternatively, to build only the BSP:
make bsp SOC=j722s
This generates a startup file with all peripherals initialized in hardware.
11.7.4. Building With Base Device Tree (No Overlays)¶
To build with the minimal device tree configuration without any overlay modifications, use the sentinel value base:
cd ${PSDK_QNX_PATH}
make all SOC=j722s DTS_OVERLAY=base
Alternatively, to build only the BSP:
make bsp SOC=j722s DTS_OVERLAY=base
This builds using the minimal device tree (j722s-hw-init.dts) without any overlay modifications. The special value base enables the device tree infrastructure and defines the USE_DT preprocessor macro, but uses the base DTS directly without applying any overlays.
11.7.5. Building With Device Tree and Overlays¶
To customize the hardware configuration using overlays, specify the overlay files via the DTS_OVERLAY variable:
Single overlay:
cd ${PSDK_QNX_PATH}
make all SOC=j722s DTS_OVERLAY=disable_dss0.dtso
Multiple overlays (comma-separated):
cd ${PSDK_QNX_PATH}
make all SOC=j722s DTS_OVERLAY=disable_dss0.dtso,disable_gpu.dtso
The overlays are applied in order to the base device tree. The resulting combined device tree is used to generate the hardware initialization header, which is then compiled into the startup file. Specifying DTS_OVERLAY with overlay files automatically enables device tree infrastructure and defines the USE_DT preprocessor macro.
11.7.6. Overlay File Selection¶
When selecting which overlays to apply, keep the following in mind:
Enable overlays set a device’s status to
"okay"(initialized and functional)Disable overlays set a device’s status to
"disabled"(not initialized)Use enable overlays to re-enable devices that should be functional
Use disable overlays to exclude devices that your system does not require
For example, if you have a minimal system that only requires Ethernet and serial communication, you might build with:
make all SOC=j722s DTS_OVERLAY=disable_dss0.dtso,disable_gpu.dtso,disable_usb0.dtso,disable_usb1.dtso
This disables the display subsystem, GPU, and USB controllers, reducing power consumption and boot time.
11.7.7. Overlay Constraints and Validation¶
Important Constraint: You cannot mix an enable overlay and a disable overlay for the same device in a single build. For example, the following command is invalid:
# INVALID - do not mix enable and disable for same device:
make all SOC=j722s DTS_OVERLAY=enable_dss0.dtso,disable_dss0.dtso
11.7.7.1. Validating Overlays Before Building¶
Before building, you can validate your overlay list to ensure there are no conflicting enable/disable pairs. Use the validation script:
# Validate a single overlay:
utils/dt/scripts/validate_overlay_conflicts.sh "disable_dss0.dtso"
# Validate multiple overlays:
utils/dt/scripts/validate_overlay_conflicts.sh "disable_dss0.dtso disable_gpu.dtso"
# Using the same format as DTS_OVERLAY (space-separated):
utils/dt/scripts/validate_overlay_conflicts.sh "disable_dss0.dtso disable_gpu.dtso enable_main_i2c0.dtso"
Successful validation (exit code 0):
$ utils/dt/scripts/validate_overlay_conflicts.sh "disable_dss0.dtso enable_main_i2c0.dtso"
# Script exits silently with code 0
$ echo $?
0
Validation failure with conflicting overlays (exit code 1):
$ utils/dt/scripts/validate_overlay_conflicts.sh "enable_dss0.dtso disable_dss0.dtso"
ERROR: Conflicting overlays for node 'dss0':
- enable_dss0.dtso
- disable_dss0.dtso
ERROR: Found 1 conflicting overlay pair(s).
Remove either the enable_ or disable_ overlay for each conflicting node.
$ echo $?
1
If validation fails, revise your overlay list to remove the conflicting pairs and try again.
11.7.8. Make Clean Between Builds¶
Important
When switching between different build modes (legacy → DT, DT → legacy, or changing overlays), you MUST run make clean to delete previously generated device tree headers. Otherwise, the old devicetree_generated.h will be used and your new overlay settings will not take effect.
Example: Switching from overlay mode to legacy mode:
# Build 1: With overlays
make all SOC=j722s DTS_OVERLAY=disable_dss0.dtso,disable_gpu.dtso
# Clean before switching modes
make clean
# Build 2: Back to legacy mode (no DT)
make all SOC=j722s
Example: Switching from legacy to base DT mode:
# Build 1: Legacy mode (no DT)
make all SOC=j722s
# Clean before enabling DT
make clean
# Build 2: With base DT only
make all SOC=j722s DTS_OVERLAY=base
11.7.9. Build Examples¶
Example 1: Disable Display and GPU
Disable the display subsystem and GPU to reduce power consumption:
cd ${PSDK_QNX_PATH}
utils/dt/scripts/validate_overlay_conflicts.sh "disable_dss0.dtso disable_dss1.dtso disable_gpu.dtso"
make all SOC=j722s DTS_OVERLAY=disable_dss0.dtso,disable_dss1.dtso,disable_gpu.dtso
Example 2: Enable Minimal Interfaces
Build with only essential interfaces (Ethernet and UART):
cd ${PSDK_QNX_PATH}
# Build defaults to enabling basic interfaces; disable others as needed
utils/dt/scripts/validate_overlay_conflicts.sh "disable_dss0.dtso disable_gpu.dtso disable_usb0.dtso disable_usb1.dtso"
make all SOC=j722s DTS_OVERLAY=disable_dss0.dtso,disable_gpu.dtso,disable_usb0.dtso,disable_usb1.dtso
Example 3: Enable Additional Interfaces
If the default build doesn’t enable certain required interfaces, use enable overlays:
cd ${PSDK_QNX_PATH}
utils/dt/scripts/validate_overlay_conflicts.sh "enable_main_i2c2.dtso enable_sdhci1.dtso"
make all SOC=j722s DTS_OVERLAY=enable_main_i2c2.dtso,enable_sdhci1.dtso
11.7.10. Configuring Build Files and User Scripts for Disabled Devices¶
When you build a startup with specific devices disabled via overlays, the corresponding resource manager (RM) processes launched in the build file and user script must be synchronized with your device tree configuration. Mismatches between disabled devices and running RMs will cause errors during boot.
11.7.10.1. Overview¶
The device tree overlays define which hardware devices are initialized at the bootloader level. However, QNX processes (resource managers, and display servers) are launched separately:
Build file (
bsp_800_j722s/images/j722s-evm-ti.build) — Defines RMs that run before QNX bootsUser script (
scripts/user_j722s.sh) — Defines resource managers and services that run after QNX boots
If a resource manager tries to access a disabled device, boot will fail or hang. Therefore, when you disable a device via overlays, you must comment out the corresponding launcher in both the build file and user script.
11.7.10.2. Device Launcher Mapping¶
The following table maps each disableable device to its disable overlay and the corresponding launcher lines:
Device Name |
Disable Overlay |
Build File Launcher |
User.sh RM/ |
|---|---|---|---|
I2C 0 (Main) |
disable_main_i2c0.dtso |
|
(none) |
I2C 0 Pins |
disable_main_i2c0_pins |
(part of i2c0 above) |
(none) |
I2C 1 (Main) |
disable_main_i2c1.dtso |
(commented - shared with R5F) |
(none) |
I2C 2 (Main) |
disable_main_i2c2.dtso |
(commented - not enabled) |
(none) |
eMMC |
disable_sdhci0.dtso |
|
(none) |
SD Card |
disable_sdhci1.dtso |
|
(none) |
MMC1 Power |
disable_vdd_mmc1.dtso |
(part of sdhci) |
(none) |
DSS0 Display |
disable_dss0.dtso |
(not launched) |
|
DSS0 VP1 Clock |
disable_dss0_vp1_clk.dtso |
(not launched) |
|
DSS1 Display |
disable_dss1.dtso |
(not launched) |
|
DSS Clock Control |
disable_dss_clk_ctrl.dtso |
(not launched) |
|
GPU |
disable_gpu.dtso |
(not launched) |
|
USB3SS0 (DWC3) |
disable_usbss0.dtso |
|
(none) |
USB0 PHY Control |
disable_usb0_phy_ctrl |
(part of usbss0 above) |
(none) |
USB3SS1 (CDNS3) |
disable_usbss1.dtso |
|
(none) |
USB1 Pins |
disable_main_usb1_pins |
(part of usbss1 above) |
(none) |
OSPI NOR Flash |
disable_ospi0.dtso |
(commented - not enabled) |
(none) |
11.7.10.3. Build File Configuration Examples¶
Example 1: Disable Display and GPU
If you build with DTS_OVERLAY=disable_dss0.dtso,disable_dss1.dtso,disable_gpu.dtso, display devices are disabled at the DT level. No changes are needed in the build file since dss and gpu are not launched there. However, if you launch the screen service in user.sh, it must be disabled:
# user_j722s.sh - comment out the screen service
# screen -c graphics-virtual-dpy.conf
Example 2: Disable I2C0
If you build with DTS_OVERLAY=disable_main_i2c0.dtso, I2C devices will not be initialized. Comment out the i2c RM in the build file:
# j722s-evm-ti.build - comment out i2c0 RM
# i2c-tda4 -p0x20000000 -i193
After disabling I2C0, any I2C bus operations in applications will fail. The i2c device nodes will not be created.
Example 3: Minimal Boot - Disable Most Peripherals
For a minimal system that boots QNX without display, GPUs, or USB:
# Build command
make all SOC=j722s DTS_OVERLAY=disable_dss0.dtso,disable_dss1.dtso,disable_gpu.dtso,disable_usbss0.dtso,disable_usbss1.dtso
# j722s-evm-ti.build - comment out USB RMs
# io-usb-otg dwc3 ioport=0x31000000
# io-usb-otg cdns3 ioport=0x31210000
# user_j722s.sh - comment out display service
# screen -c graphics-virtual-dpy.conf
This configuration keeps only I2C, eMMC, and SD card enabled, suitable for headless embedded systems.
Example 4: Disable SD Card Only
If your system uses only eMMC (no removable SD card), disable SD:
# Build command
make all SOC=j722s DTS_OVERLAY=disable_sdhci1.dtso,disable_vdd_mmc1.dtso
# j722s-evm-ti.build - comment out SD card RM
# devb-sdmmc-am65x addr=0x0fa00000
# Keep eMMC RM enabled
devb-sdmmc-am65x addr=0x0fa10000
11.7.10.4. Device Dependencies and Constraints¶
Some devices have interdependencies that you should be aware of:
eMMC/SD Card: Both controllers use the same power domain (
vdd_mmc1). Disabling MMC1 power affects both. Disablingsdhci1alone (SD card) does not require disablingvdd_mmc1if eMMC is still in use.USB SerDes: Both USB3SS controllers depend on shared SerDes PHY resources (
serdes0,serdes_refclk,serdes_wiz0). Disabling SerDes overlays (disable_serdes0.dtso,disable_serdes_wiz0.dtso) will break USB functionality. Conversely, disabling both USB controllers makes SerDes unused, but SerDes overlays should still be managed explicitly.I2C Constraints: I2C1 and I2C2 are reserved for R5F cores (ARM Cortex-R5F processors) in the default configuration. The code is commented with a TODO note indicating shared access. Do not enable i2c1 or i2c2 unless you have coordinated with R5F firmware to avoid conflicts.
Display/GPU: Display (DSS) and GPU are independent but share the graphics rendering pipeline if both are used. Disabling dss0 without disabling gpu will still consume GPU resources; the opposite is also true.
11.7.10.5. Failure Modes and Troubleshooting¶
Symptom: Resource Manager exits with “Permission denied” or “Device not found”
Cause: A RM in the build file or resource manager in user.sh is trying to access a device that has been disabled via DT overlays.
Resolution:
1. Check which overlay was applied during build
2. Identify the corresponding RM from the mapping table above
3. Comment out that RM line
4. Run make clean (important!)
5. Rebuild: make all SOC=j722s ...
Symptom: QNX boot hangs after device tree initialization
Cause: A launcher is trying to initialize hardware that has been disabled at the DT level. The RM may be waiting indefinitely for a device response.
Resolution:
1. Review the build file and user.sh for any RMs matching disabled devices
2. Ensure all disabled device launchers are commented out
3. Run make clean to remove stale headers
4. Rebuild and reboot
Symptom: I2C devices not responding even though i2c0 RM is running
Cause: I2C0 pins have been disabled via disable_main_i2c0_pins_default.dtso while the i2c RM is still launching.
Resolution: 1. If you disabled i2c0, comment out the i2c RM 2. If you only disabled pins (not the full i2c0 device), the controller exists but pins are not muxed - enable pin configuration overlay or comment out the i2c RM
11.7.10.6. Future Automation Consideration¶
Currently, you must manually synchronize overlay choices with launcher configuration in two separate files. A future enhancement could automate this process:
Note
Conceptual Automation (Not Implemented Yet)
A build system enhancement could:
1. Parse DTS_OVERLAY variable to extract disabled devices
2. Generate a filtered build file (commenting out matching device launchers)
3. Generate a filtered user.sh (commenting out matching resource managers)
4. Log all changes for verification
This would eliminate manual file edits and reduce errors. Implementation would require: - Python script to parse overlay filenames and extract device names - sed/awk-based filtering of build file and user.sh templates - Validation step to ensure all disabled devices have matching commented launchers - Integration into the top-level makefile as a pre-build step
11.7.10.6.1. Refinement: Limiting Disable-able Nodes to hw_init.c Peripherals¶
A key refinement for future automation should be to limit the available disable overlays to only the device nodes that are actually used by QNX hardware initialization (hw_init.c). This ensures users cannot inadvertently disable arbitrary device tree nodes that have no relevance to system boot.
Current State:
- The minimal DTS (j722s-hw-init.dts) was specifically extracted to contain only nodes required by hw_init.c
- However, the full preprocessed DTS contains many additional nodes that could theoretically be disabled
- Users might disable unrelated nodes without realizing they have no effect on boot or functionality
Proposed Refinement: - Generate disable overlays only for nodes that appear in both:
The minimal DTS (
j722s-hw-init.dts)The corresponding
hw_init.cdriver initialization code
Document the 1:1 mapping between each disable overlay and the specific
hw_init.ccode section it affectsOptionally generate a constraint list preventing disabling of critical boot dependencies (e.g., cannot disable main clocks without disabling dependent devices)
Benefit: Users would only see device options relevant to their actual system boot configuration, reducing confusion and preventing accidental misconfiguration. The overlay list would be maintainable and directly traceable to source code.
11.7.11. Troubleshooting¶
Missing overlay file error:
If you receive an error like “Overlay file not found”, verify:
The overlay file exists in
${PSDK_QNX_PATH}/qnx/utils/dt/dts/j722s/overlay/You spelled the overlay filename correctly
You are running the build command from the QNX repository root
Conflicting overlays error:
If the build fails with a conflict error, run the validation script to identify which overlays are conflicting, then remove one of the conflicting pairs.
Device not responding after build:
If a peripheral that you expected to initialize is not responding:
Verify that you did not accidentally disable it with a disable overlay
Check that the device’s pin configuration overlay is enabled (if one exists)
Verify the hardware connections and power supplies
11.7.12. Developer Note: Future Build System Enhancement¶
Note
The validation script (validate_overlay_conflicts.sh) is currently available as a manual step before building. Future versions of the build system should automatically integrate this validation into the build chain to prevent invalid configurations at build time. Users should manually run the validation script before invoking the make bsp command to catch configuration errors early.
11.7.13. Summary¶
QNX BSP Device Tree Build Modes:
Legacy (default):
make all SOC=j722s— All devices enabled, no device treeBase DT only:
make all SOC=j722s DTS_OVERLAY=base— Base device tree, no overlaysDT with overlays:
make all SOC=j722s DTS_OVERLAY=<overlay_list>— Device tree with customization
For overlay builds:
Choose the devices you want to enable or disable
Validate your overlay list:
utils/dt/scripts/validate_overlay_conflicts.sh "<overlay_list>"Build with overlays:
make all SOC=j722s DTS_OVERLAY=<overlay_list>
Important reminders:
Specifying
DTS_OVERLAY(withbaseor overlay filenames) automatically enables the device tree infrastructure and defines theUSE_DTpreprocessor macroRun
make cleanwhen switching between build modes to ensure old headers are removedThe resulting startup file will initialize only the peripherals specified in your device tree configuration
You can build only the BSP with
make bsp SOC=j722s ...instead of the full build withmake all SOC=j722s ...
See also
Device Tree Support — Additional device tree integration details
Understanding bootloaders in Processor SDK J722S (RTOS/Linux/QNX) — Boot loader configuration