Devicetree overview

Devicetree is a data structure for describing hardware. In Fuchsia, the board driver uses devicetree to create nodes in the driver framework and sets configurations needed to initialize the board. Devicetree contains the following two parts that are used by the board driver to construct a devicetree parser:

  • Devicetree manager library: This library is responsible for parsing the devicetree blob (DTB) and creating a runtime node structure which can be accessed by the devicetree visitors.

  • Devicetree visitors: Visitors are objects that the board driver provides to the devicetree manager during the Walk call. Each visitor's interface will get invoked on all nodes of the devicetree when walking the tree. They are responsible for converting the devicetree data into driver-specific metadata and bind rules.

Board driver integration

The board driver initializes the devicetree manager library with the incoming namespace in order to provide connection to the fuchsia_hardware_platform_bus::Service::Firmware protocol. The manager reads the devicetree using the fuchsia_hardware_platform_bus::Service::Firmware protocol. The board driver can invoke the Walk method of the devicetree manager to parse the devicetree blob and collect node properties. During the walk call, several visitors can be provided to parse and transform node properties into Fuchsia driver metadata and bind rules. Once the walk is completed, the board driver invokes the PublishDevices method to publish all the device nodes to the driver framework.

For reference implementation, see the examples directory.

Devicetree bindings and visitors

Devicetree bindings describes the requirements on the content of a devicetree node pertaining to a specific device or a class of device. They are documented using devicetree schema files, which are YAML files that follow a certain meta schema (for example, see smc.yaml). For more information on devicetree schemas, see Devicetree Schema Tools.

Devicetree visitors can be used with the devicetree manager to parse and extract information from all or specific devicetree nodes. The devicetree specification lists a set of standard properties, some of which are parsed by the default visitors in the visitors/default folder. A new visitor will have to be developed for any new bindings that need to be parsed (for more details, see Writing a new visitor).

The default visitors are compiled into a static library that can be built with the board driver. All other visitors (that is, driver visitors) are built as a shared library using the devicetree_visitor GN target. The board driver can include the necessary visitor collection in its package under /pkg/lib/visitors/. At runtime, the board driver can load all these visitors using the load-visitors helper library.

Passing the devicetree blob

Typically, the devicetree blob (DTB) is passed down by the bootloader to the kernel as a ZBI_TYPE_DEVICETREE item and made available to the board driver via fuchsia_hardware_platform_bus::Service::Firmware protocol. In boards where the bootloader is not yet capable of passing the DTB (typically during board bringup), the DTB can be passed in through board configuration's devicetree field, and later it will be appended to the Zircon Boot Image (ZBI) by assembly.

Testing devicetree

A board driver integration test can be added to test that the parsing and creation of nodes by the devicetree libraries and visitors. The board-test-helper library can be used to create a test realm with driver framework, platform bus and the board driver components running in it. The DTB is passed as a test data resource and is provided to the board driver through the fake fuchsia_boot::Items protocol implemented in the board-test-helper library. The test creates a platform bus device with specified VID, PID to which the board driver will bind to. The board driver then invokes the devicetree manager, parses the devicetree, and creates other child nodes. A typical test would be to enumerate the nodes created.