Devicetree{:.external} 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.
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 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{:.external}.
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{:.external}, 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.
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.
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.