Device Tree Bindings and Their Conversion to JSON-Schema Format

May 28, 2024 •

The devicetree is a tree data structure for describing hardware. It’s like a cheat sheet that tells the OS about the hardware at boot time, instead of the OS needing to know everything itself.

Hardware Description through devicetree

  1. A developer writes a device tree source (*.dts) file (which sometimes inherits *.dtsi files).
  2. The device tree compiler (dtc) converts this file into a device tree blob (or binary) (*.dtb). This conversion is done to make loading the hardware description simpler for the kernel.
  3. The *.dtb files are loaded in memory by the bootloader before the kernel is started.
  4. dtc is also responsible for syntax checking of the *.dtb file, but it cannot perform semantic checks.

In the past, developers relied on plain text files (*.txt) to describe how devices work in the operating system. These files were just for humans to read and couldn’t automatically check for errors in the *.dts files. To improve this, we switched to a more powerful system using JSON-schema. JSON-schema allows for automatic semantic checking of device descriptions.

How to Convert DT Bindings to JSON-Schema

  1. Carefully and fully read writing-bindings.rst and writing-schema.rst located in the Documentation/devicetree/bindings directory of the Linux kernel tree. An example-schema is also present in the same directory for reference.
  2. Krzysztof Kozlowski has done a great presentation which covers all the steps of the conversion.

After carefully reading writing-bindings.rst and writing-schema.rst and watching Krzysztof’s video, you are ready to do your first conversion of txt bindings to JSON-schema. After writing the JSON-schema, it is necessary to run a few checks before submitting your patch.

Testing Your JSON-Schema

Start by setting up your environment according to writing-schema.rst.

Run the following in the root directory of the tree:

make defconfig

Testing all the bindings in the kernel will take a lot of time:

make dt_binding_check

To test your specific binding or a subset of all the bindings, run:

make dt_binding_check DT_SCHEMA_FILES=trivial-devices.yaml
make dt_binding_check DT_SCHEMA_FILES=qcom
make dt_binding_check DT_SCHEMA_FILES=/gpio/

Validate DTS Against the JSON-Schema

Start by cross-compiling for the architecture of the device:

export ARCH=arm64

Check all the *.dts files against all the JSON-bindings:

make dtbs_check

Check all the *.dts files against a specific binding:

make CHECK_DTBS=y DT_SCHEMA_FILES=trivial-devices.yaml

You can also provide a *.dtb target to validate it against all the bindings:

make CHECK_DTBS=y qcom/sm8450-hdk.dtb

Or it can also validate against a specific binding or a subset of all the bindings:

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

If all goes well, congratulations! You have successfully converted a DT binding to JSON-schema. You can now send it to the upstream community. Read submitting-patches.rst and follow this guide.

Things to Keep in Mind

  1. Prioritize newer platforms like arm64 as these are the most active platforms and the conversion of bindings here will be most useful.
  2. Follow this list of undocumented compatibles (ordered by number of occurrences) and warnings and fix them.
  3. Always run the tests before sending patches.
  4. In case you are changing something in the binding which is outside the scope of pure conversion, make sure to mention it briefly in the commit message.