Showing results for 
Show  only  | Search instead for 
Did you mean: 

PetaLinux Image Debug Series: Debugging the Device Tree Generator

9 1 2,026

The Device Tree Generator (DTG) is a Tcl based utility that uses the HSI API to extract the hardware information from the XSA file to construct a custom device tree. The DTG utility is used in PetaLinux and Yocto. However, debugging DTG issues in PetaLinux can be cumbersome.

In this blog entry we will discuss how we can isolate the DTG from PetaLinux, how to build the DTS files, how to navigate the DTG source files and how to debug a typical DTG issue.

This Blog is part of a Series discussing how to debug various components in the Petalinux Images. 

You can find the other entries at the links below:


The DTG can be obtained from GitHub below:

The xilinx-v2020.1 branch is used for the demonstration and the target board is a ZCU102 Evaluation Board.

Building the Device Tree:

To generate the .dts/.dtsi from the DTG, follow the below steps.

1) Clone the device-tree-xlnx repository and check out the version you want to work with:

git clone
cd device-tree-xlnx  
git checkout xilinx-v2020.1

2) Open the xsct shell and run the commands below:

xsct% hsi::open_hw_design <path_to.xsa>
xsct% hsi::set_repo_path <device-tree-xlnx directory path>
xsct% hsi::create_sw_design device-tree -os device_tree -proc psu_cortexa53_0
xsct% hsi::generate_target -dir <destination directory>


The generated device tree files will be present in the “destination” folder. It then has to be pre-compiled using gcc and compiled using the Device Tree Compiler (DTC) to be used in the target.

The following is the block diagram of the example design used in this blog. The design_1_wrapper.xsa file can be found in the attachment. 


This is the build output of the attached .xsa file. I have copied the .xsa file to the device-tree-xlnx folder before executing the commands.



Debugging The Device Tree Generator:

For each processor in the system, the tool finds the list of addressable peripherals. For each processor, a unique list of drivers and libraries are built. A driver or library has two associated data files. 

Data Definition File (MDD or MLD file): this file defines the configurable parameters for the driver, OS, or library. The Microprocessor Driver Definition (MDD) file for each driver specifies the definitions that must be customized for each peripheral that uses the driver.

Data Generation File (Tcl): this file uses the parameters configured in the MSS file for a driver, OS, or library to generate data.

generate and post_generate procedures from Tcl files are called by the tool when generating the device-tree.

The generate {} procedure in the device_tree.tcl is the entry point for the device tree generator.

The common_proc.tcl has helper functions that are used in device_tree.tcl


Once the hardware design is loaded using steps from section 1, you could verify the IP configurations using hsi and common commands.

Let’s go through the generate {} function in device_tree.tcl


For each driver instances, the generate {} procedure calls the following functions.

  • gen_peripheral_nodes creates peripheral nodes for all of the listed drivers. It creates the nodes with name, label, and unit address.
  • gen_reg_property gets the memory range associated with the cell and assigns it to reg property.
  • gen_compatible_property gets the node name from the properties and assigns it to compatible property
  • get_drv_prop_from_ip adds all CONFIG.* property from the IP to the respective peripheral node.
  • gen_interrupt_property generates interrupts and interrupt-parent properties for the IP.
  • gen_clk_property adds the clock related properties of the IP to the device-tree.

I will add a few examples of the procedures mentioned above and the output of a few frequently used hsi commands.

The get_cells command gets a list of IP instance objects in the current design.


common:report_property reports the properties of an object.


get_drivers() gets and displays the list of software driver instances in the current design. The foreach loop goes through all of the IP instances listed here and creates nodes for them in the device-tree.


The following screenshot shows the memory ranges in the gpio node and the value in the final pl.dtsi file.

BASE_VALUE and HIGH_VALUE parameters give both the address and size of the memory assigned to the specific cell and are added as "reg" properties in the Device Tree.

Here, the base address of the gpio module is 0x80000000 and size is 0x10000.


This example shows how the clock values are read from IP parameters and assigned to the respective node in the device tree.

The AXI GPIO clock (s_axi_clock) in the example design is connected to pl_clk_0(zynqmp_clk 71). 



As we can see the HSI is a very powerful utility. This is used in other areas such as the standalone BSP, in setting up the auto config in PetaLinux, and in the Vitis Acceleration flow. Users can also use this for their own automation flows. See (UG1138) for more details about available commands.

Analyzing the Error log:

To introduce an error in the example design, apply the 0001_insert_typo.patch from the file and build the device tree again. Most of the DTG errors are introduced by hardware design. In this demo, we are creating an error by inserting a typo. Analyzing the error log will be the same for most errors.

In the following error log:

  • The last lines in the error log tell you the first function in the call stack that caused the error and the line number in that function where another procedure is called or where the error is introduced.
  • In this example, the call stack goes like this, generate -> foreach -> gen_interrupt_property.
  • The line number in each call tells you which line number inside that function caused the error or invoked another function.
  • In this example, line 26 in the gen_interrupt_property caused the error and it is the top of the stack.
  • Once you find the line number that caused the error in the script, it can be fixed based on the type of error.
  • For syntax errors, it is straight-forward. For design errors, the user could run the same line from the Tcl script in the xsct console using the hsi command and find out the actual issue in the design.


Generating the DTG patch against a PetaLinux version:

If users have noticed an error in the DTG and want to patch the current version, then they can create a patch in device-tree-xlnx.

For example, here I will create a patch against the 2020.1 version:

Creating the Patch:

cd repo/my_dtg/device-tree-xlnx
git diff xilinx-v2020.1 > 0001_your_patch_here.patch


Adding the Patch to the PetaLinux device tree recipe:

Copy the patch to project-spec/meta-user/recipes-bsp/device-tree/files and update the device-tree.bbappend as follows:

FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
SRC_URI += "file://system-user.dtsi" 
SRC_URI_append += " file://your_patch_here.patch"

Compiling the Device Tree:

You may have noticed that the devicetree files delivered by the DTG are a mixture of DTS and DTSI files. The DTSI are include files that need to be precompiled similar to a C/C++ application. Firstly, users will also need to download and build the Device Tree Compiler (DTC):

git clone
cd dtc
export PATH=$PATH:<path to dtc>

Next, user can precompile:

gcc -I <destination directory> -E -nostdinc -undef -D__DTS__ -x assembler-with-cpp -o <destination directory>/system-top.dts.tmp <destination directory>/system-top.dts

Finally, we are ready to compile:

dtc -I dts -O dtb -o my_dts/system-top.dtb my_dts/system-top.dts.tmp
1 Comment

Sorry, there is no problem at the moment