Devicetree

From Mainlining Wiki
Revision as of 19:46, 19 February 2025 by Knuxify (talk | contribs)
Jump to navigation Jump to search

The devicetree (device tree, DT) is a data structure which holds information about all components present on a device. This data is structured in nested nodes with key/value property pairs for configuration.

In simpler terms - a devicetree tells the kernel (or another DT-compatible piece of software/firmware like a bootloader) where each component is in register space/on an I2C or similar bus, and what settings to use to set it up. It is the basic mechanism for discovering components on embedded platforms, including ARM.

Devicetrees are written in a plaintext format known as the Device Tree Source (DTS) format. The DTS is later compiled into a Device Tree Blob (DTB); in this form, it can be loaded by software/firmware.

Devicetrees are validated using devicetree schema, which is described by bindings; see /Bindings for more information.

History

The initial version of the devicetree standard was developed as part of the OpenFirmware initiative; from this standard, the Flattened Device Tree (FDT) emerged and was adopted by the Linux kernel for PowerPC platforms. Around 2009, discussions began to include FDT support for ARM[1]. It was eventually added and first device trees began to appear in 2011[2], although the format didn't see wider usage (especially in vendor kernels) until around 2013/2014.

Nowadays, the devicetree standard is managed by devicetree.org; they maintain the latest version of the Devicetree Specification and the related set of core DT schema.

Before the introduction of devicetrees, ARM kernels used board files. These were C files stored in arch/arm/mach-* which served a similar purpose to devicetrees - they contained structures for defining component configuration ("platform data"). Unlike device trees however, they could also define C functions, since they were regular C sources compiled into the kernel. Board files technically still exist (citation needed?), but are no longer in wide use.

Device Tree Source (DTS) basics

The following is a simple DTS file to demonstrate the DTS syntax. For a more in-depth syntax guide, see Devicetree/DTS syntax.

foo.dts
/dts-v1/;

/ {
	#address-cells = <1>;
	#size-cells = <1>;
	
	my_node: node1@1000 {
		compatible = "vendor,foo";
		reg = <0x1000 0x54>;
		vendor,bar-factor = <0x2a>;
	};

	node2@2000 {
		compatible = "vendor,bar";
		reg = <0x2000 0xa4>;
		vendor,baz-companion = <&my_node>;
	};

	i2c-controller@3000 {
		compatible = "vendor,foobar-i2c";
		reg = <0x3000 0x800>;
		
		#address-cells = <1>;
		#size-cells = <0>;
		
		sensor@10 {
			compatible = "vendor,baz-sensor";
			reg = <0x10>;
		};
	};
};

Verifying DTS files

The Linux kernel has tools for making sure that device tree sources (DTS) use the bindings correctly. These are useful when writing device sources; getting the DT checks to pass is also mandatory for upstream inclusion of a DTS.

To verify all DTS files built with the selected defconfig options, run:

$ make dtbs_check

To verify a specific DTS, build the DTB target directly and provide the CHECK_DTBS=y option:

$ make CHECK_DTBS=y qcom/sm8450-hdk.dtb

You can also test a DTS against a specific subset of bindings by providing the DT_SCHEMA_FILES variable as mentioned in the previous section:

$ make CHECK_DTBS=y DT_SCHEMA_FILES=trivial-devices.yaml qcom/sm8450-hdk.dtb

Working with DTC

The dtc tool handles compiling DTS files into DTBs, as well as decompiling DTBs back into DTS. (TODO: add instructions)

See also

References

todo enable refs extension

[1] https://www.mail-archive.com/[email protected]/msg01721.html [2] https://github.com/torvalds/linux/commit/b85a3ef4ac65169b65fd2fe9bec7912bbf475ba4