DTO syntax

Device tree source (DTS) format is a textual representation of a device tree (DT). The device tree compiler (DTC) processes this format into a binary DT, which is the form expected by the Linux kernel.

Use references

The DTC (device Tree compiler + overlay patches) project describes the DTS format in dtc-format.txt and manual.txt. DTO format and rules are described in dt-object-internal.txt. These documents describe how to update the main DT using node fragment@x and syntax __overlay__ in overlay DT. For example:

/ {
  fragment@0 {
    target = <&some_node>;
      __overlay__ {
        some_prop = "okay";
        ...
      };
  };
};

However, Google strongly recommends you do not use fragment@x and syntax __overlay__, and instead use the reference syntax. For example:

&some_node {
  some_prop = "okay";
  ...
};

Reference syntax is compiled by dtc into the same object as the above using syntax __overlay__. This syntax doesn't force you to number the fragments, enabling you to read and write overlay DTS easily. If your dtc doesn't support this syntactic sugar, use the dtc in AOSP.

Use labels

To allow undefined references to nodes not present at compilation time, the overlay DT .dts file must have a tag /plugin/ in its header. For example:

/dts-v1/;
/plugin/;

From here you can target the nodes to be overlaid using a reference, which is an absolute node path prefixed with an ampersand (&). For example, for node@0 in the main DT:

Define labels in the main DT ... ... then use the labels.
[my_main_dt.dts]

/dts-v1/;

/ {
  my_node: node@0 {
    status = "disabled";

    my_child: child@0 {
      value = <0xffffffff>;
    };
  };
};
[my_overlay_dt.dts]

/dts-v1/;
/plugin/;

&my_node {
  status = "okay";
};

&my_child {
  value = <0x1>;
};

Override

If the reference target property exists in the main DT, it is overridden after DTO; otherwise, it is appended. For example:

main.dts overlay.dts Merged Result
[my_main_dt.dts]

/dts-v1/;

/ {
  compatible = "corp,foo";

  my_node: node@0 {
    status = "disabled";
  };
};
[my_overlay_dt.dts]

/dts-v1/;
/plugin/;

&my_node {
  status = "okay";
};
/dts-v1/;

/ {
  compatible = "corp,foo";

  ...

  node@0 {
    linux,phandle = <0x1>;
    phandle = <0x1>;
    status = "okay";
  };
};

Append

If the reference target property doesn't exist in the main DT, it is appended after DTO. For example:

main.dts overlay.dts Merged Result
[my_main_dt.dts]

/dts-v1/;

/ {
  compatible = "corp,foo";

  my_node: node@0 {
    status = "okay";
  };
};
[my_overlay_dt.dts]

/dts-v1/;
/plugin/;

&my_node {
  new_prop = "bar";
};
/dts-v1/;

/ {
  compatible = "corp,foo";

  ...

  node@0 {
    linux,phandle = <0x1>;
    phandle = <0x1>;
    status = "okay";
    new_prop = "bar";
  };
};

Child nodes

Examples of child node syntax:

main.dts overlay.dts Merged Result
[my_main_dt.dts]

/dts-v1/;

/ {
  compatible = "corp,foo";

  my_nodes: nodes {
    compatible = "corp,bar";

    node@0 {
      status = "disabled";
    };
  };
};
[my_overlay_dt.dts]

/dts-v1/;
/plugin/;

&my_nodes {
  new_prop1 = "abc";

  node@0 {
    status = "okay";
    new_prop2 = "xyz";
  };
};
/dts-v1/;

/ {
  compatible = "corp,foo";

  ...

  nodes {
    linux,phandle = <0x1>;
    phandle = <0x1>;
    compatible = "corp,bar";
    new_prop1 = "abc";

    node@0 {
      linux,phandle = <0x2>;
      phandle = <0x2>;
      status = "okay";
      new_prop2 = "xyz";
    };
  };
};