Device Tree

From krtkl wiki
Jump to: navigation, search

The device tree is a hierarchical data structure containing a set of hardware descriptions. Data is organized into units of nodes and properties, each describing an element of the hardware such as a peripheral or on-board IC.

Device Tree Compiler

$ git clone -b overlay https://github.com/dgibson/dtc.git

Device Tree Source

$ git clone https://github.com/krtkl/snickerdoodle-dts.git

Building Device Tree Blob

$ dtc -I dts -O dtb -o devicetree.dtb devicetree.dts

Overlay Compatible Device Tree Blob

The -@ or --symbols options should be used to build the system device tree blob in preparation for

$ dtc -@ -I dts -O dtb -o devicetree.dtb devicetree.dts

Building From Repo

The snickerdoodle-dts repository contains dts include files that can be used as a starting point for custom configurations. Standard configuration dts wrappers are also at the root level of the repository. The makefile is configured to build these base configurations with __symbols__ node generations for overlay compatibility.

/dts-v1/;
/include/ "snickerdoodle-black.dtsi"

/ {
        model = "snickerdoodle black";
};

Adding Custom Source

The makefile at the root level of the repository can be edited to include custom device tree source files.

dtb-y += snickerdoodle.dtb
dtb-y += snickerdoodle-one.dtb
dtb-y += snickerdoodle-black.dtb
dtb-y += snickerdoodle-prime.dtb
dtb-y += snickerdoodle-prime-le.dtb
dtb-y += snickerdoodle-myProject.dtb

The makefile in the baseboard directory can be similarly edited to include custom baseboard source files.

dtb-y += snickerdoodle-piSmasher.dtb
dtb-y += snickerdoodle-black-piSmasher.dtb
dtb-y += snickerdoodle-prime-piSmasher.dtb
dtb-y += snickerdoodle-myBaseboard.dtb

Build Repository

$ make
  snickerdoodle.dts --> snickerdoodle.dtb
  snickerdoodle-one.dts --> snickerdoodle-one.dtb
  snickerdoodle-black.dts --> snickerdoodle-black.dtb
  snickerdoodle-prime.dts --> snickerdoodle-prime.dtb
  snickerdoodle-prime-le.dts --> snickerdoodle-prime-le.dtb
  snickerdoodle-myProject.dts --> snickerdoodle-myProject.dtb
-- Building overlays
make -C dtso/
make[1]: Entering directory '/home/krtkl/GitHub/snickerdoodle-dts/dtso'
  gpio.dts --> gpio.dtbo
Warning (unit_address_vs_reg): Node /fragment@0 has a unit name, but no reg property
Warning (unit_address_vs_reg): Node /fragment@1 has a unit name, but no reg property
  pwm.dts --> pwm.dtbo
Warning (unit_address_vs_reg): Node /fragment@0 has a unit name, but no reg property
Warning (unit_address_vs_reg): Node /fragment@1 has a unit name, but no reg property
  uio.dts --> uio.dtbo
Warning (unit_address_vs_reg): Node /fragment@0 has a unit name, but no reg property
Warning (unit_address_vs_reg): Node /fragment@1 has a unit name, but no reg property
  myOverlay.dts --> myOverlay.dtbo
Warning (unit_address_vs_reg): Node /fragment@0 has a unit name, but no reg property
Warning (unit_address_vs_reg): Node /fragment@1 has a unit name, but no reg property
make[1]: Leaving directory '/home/krtkl/GitHub/snickerdoodle-dts/dtso'
-- Building baseboard device trees
make -C baseboard/
make[1]: Entering directory '/home/krtkl/GitHub/snickerdoodle-dts/baseboard'
  snickerdoodle-piSmasher.dts --> snickerdoodle-piSmasher.dtb
  snickerdoodle-black-piSmasher.dts --> snickerdoodle-black-piSmasher.dtb
  snickerdoodle-prime-piSmasher.dts --> snickerdoodle-prime-piSmasher.dtb
  snickerdoodle-myBaseboard.dts --> snickerdoodle-myBaseboard.dtb
make[1]: Leaving directory '/home/krtkl/GitHub/snickerdoodle-dts/baseboard'
# cp snickerdoodle-myProject.dtb /media/krtkl/BOOT/devicetree.dtb

Device Tree Overlays

Device tree overlays can be used to modify the running system device tree. Resolution of the running device tree and any overlays that are added during or after the boot process occurs by updating values of existing nodes and properties and creating new nodes and properties. This can be useful for enabling processing system peripherals that have been set as disabled (status = "disabled" in the standard device tree).

/dts-v1/;
/plugin/;

/ {
        compatible = "xlnx,zynq-snickerdoodle", "xlnx,zynq-7000";

        fragment@0 {
                target = <&gem0>;
                __overlay__ {

                        status = "okay";
                        phy-handle = <&ethernet_phy0>;
                        phy-mode = "rgmii-id";

                        ethernet_phy0: ethernet-phy@0 {
                                device_type = "ethernet-phy";
                                reg = <0>;
                        };
                };
        };

        fragment@1 {
                target-path = "\__symbols__";
                __overlay__ {
                        ethernet_phy0 = &ethernet_phy0;
                };
        };

};

Programmable Logic Devices

/dts-v1/;
/plugin/;

/ {
        compatible = "xlnx,zynq-snickerdoodle", "xlnx,zynq-7000";

        fragment@0 {
                target-path = "/";
                __overlay__ {

                        #address-cells = <1>;
                        #size-cells = <1>;

                        axi_gpio0: gpio@41200000 {
                                compatible = "xlnx,xps-gpio-1.00.a";
                                gpio-controller;
                                #gpio-cells = <2>;
                                #address-cells = <2>;
                                #size-cells = <1>;
                                interrupt-parent = <&intc>;
                                reg = <0x41200000 0x10000>;
                                xlnx,is-dual = <0>;
                                xlnx,all-inputs = <0>;
                                xlnx,tri-default = <0xffffffff>;
                                xlnx,gpio-width = <25>;
                        };
                };
        };

        fragment@1 {
                target-path = "\__symbols__";
                __overlay__ {
                        axi_gpio0 = &axi_gpio0;
                };
        };
};

The __symbols__ Node

When compiled with the -@ or --symbols option, a .dtb will contain a __symbols__ node that can be used by the system to resolve references to device nodes by any device tree overlays. Just like any other node, the __symbols__ node can be modified by any applied overlays allowing subsequent overlays to access newly created nodes.

Building Overlay in Repository

dtbo-y := gpio.dtbo
dtbo-y += pwm.dtbo
dtbo-y += uio.dtbo
dtbo-y += myOverlay.dtbo

Apply Device Tree Overlay

Device tree overlays can be applied to a running system using the configfs interface.

configfs

configfs is a virtual filesystem that provides the converse of sysfs's functionality. Where sysfs is a filesystem-based view of kernel objects, configfs is a filesystem-based manager of kernel objects. Access to configfs is enabled by mounting the filesystem. This can be done from the command line.

# mount -t configfs none /config

or by adding an entry to /etc/fstab (default configuration found in snickerdoodle SD card image)

##### Default snickerdoodle File System Table
# <file system>         <mount>         <type>          <options>       <dump>  <pass>
/dev/mmcblk0p1          /boot           vfat            defaults        0       0
/dev/mmcblk0p2          /               ext4            defaults        0       0
configfs                /config         configfs        defaults        0       0

Creating and applying a device tree overlay requires first creating a directory in the configfs.

# mkdir /config/device-tree/overlays/myOverlay

A series of files are generated by the configfs system when the overlay directory is created. Applying the overlay can be done by writing the overlay file data to the generated dtbo file.

# cat /boot/overlay/myOverlay.dtbo > /configfs/device-tree/overlays/myOverlay/dtbo