A Device Tree (DT) is a data structure that (normally) contains a hierarchical representation of the available hardware, but also runtime configuration information. The DT is always written in the Device Tree Source (DTS) format and looks something like this:
We notice that the DT is structured as multiple nested nodes. Each node can be referenced by a path comprised of the names of all of its ancestors. In fact, nodes that represent hardware devices are usually assigned an alias based on this path:
Each node is comprised of properties and other node. A property can be a:
device_type = “cpu”;
regulator-boot-on;
reg = <0x30860000 0x10000>;
Additionally, there are special properties that start with a #
symbol. These properties are used by the FDT parser as hints on how to interpret the packed array of integers. Normally, each element in the array is a uint32_t. However, certain properties (reg
especially) usually contain one or more (address, size)
tuples. In the example above, the reg
property located in the serial@30890000
node informs the kernel that the serial (UART) device is mapped in memory starting at 0x30890000
has a size of 0x10000
. Note that in this case we have one tuple where each element consists of precisely one uint32_t element. This may not always be the case! Hence, the following properties:
#address-cells
: Number of uint32_t cells that comprise the address element in each tuple.#size-cells
: Number of uint32_t cells that comprise the size element in each tuple.
Knowing these values is the only way to determine the number of tuples in a packed array property. Note, however, that the #*-cells
properties do not apply to the node where they are encountered, but only to its children. For example, if bus@30800000
overrides these properties (whose default value was inherited from soc@0
), only the reg
of serial@30890000
would adhere to these changes. The ranges
property of bus@30800000
would still use the values inherited from soc@0
.