August 17, 2020

Understanding the Device Tree

The device tree is an aspect of Linux (and U-Boot) on ARM processors. The idea is that one kernel can work for a multitude of different boards if their unique aspects are captured in a device tree.

It is worth noting the following, since I am working with Allwinner chips. "A proprietary configuration file format used for similar purposes, the FEX file format, is a de facto standard among Allwinner SoCs."

I device tree is a tree consisting of nodes and properties. Properties consist of name-value pairs. Nodes can contain both properties and child nodes.

Source files to generate a device tree are xyz.dts and xyz.dtsi. Dtsi files are common information pulled into other files via an include statement. These are compiled to xyz.dtb where "dtb" is "device tree blob". DTS is "device tree source". The tool used to compile the dts files is "dtc" the device tree compiler. It is typically in scripts/dtc It is possible to reverse compile using dtc from a dtb to a dts, but it is far better to have the original dts files.

Once the linux kernel is running, the entire device tree is available at /proc/device-tree. It is even possible to point dtc at this and get back a dts file. This is all by virtue of sysfs mounted on /proc

When a dts file includes a dtsi file, it may override definitions in the dtsi file. It is common to define all peripherals in a processor-specific .dtsi file, with the vast majority having their "status" property set to "disabled", making the kernel ignore those peripherals. The board-level device tree may then include the processor-specific file and assign "status" with "okay" on the peripherals desired, plus possibly set up some board-specific parameters. This is a common practice to keep the board-specific DTS files clean and tidy.

A quick but important side note. The letters "OF" stand for "open firmware", and have a history with the invention of the device tree on SPARC processors. There are many routines that support device tree access from within the kernel that begin with "of_". Also you may encounter the acronym "FDT" which stands for "flattened device tree". This seems to be in use less and less.

The linux kernel and drivers

As I understand it at this time, this is what happens when the Linux kernel boots up. It scans the device tree and tries to locate drivers for the hardware specified by the device tree nodes. It finds the driver for some given hardware by matching up the "compatible" entry in the device tree. As an example the device tree for my Orange Pi PC 2 has this entry:
r_ccu:  clock@1f01400 {
    compatible = "allwinner,sun8i-h3-r-ccu";
    reg = <0x01f01400, 0x100>;
When I grep the entire linux source tree, I find that "drivers/clk/sunxi-ng/ccu-sun8i-r.c" has this string indicating that it is the appropriate driver.

Note that the "allwinner," is just part of the string, not part of a list. This is common practice and serves to keep entries in this namespace unique.


Have any comments? Questions? Drop me a line!

Tom's electronics pages / tom@mmto.org