Using Device Tree Overlays¶
Note
This page describes functionality which is not (yet) part of the upstream firmware (U-Boot), and is subject to change. This feature is only present in Ten64 firmware v0.9.1 and later.
Device Tree Overlays allow you to add bindings to the Ten64 device tree without having to modify the Ten64 firmware.
An example device tree overlay¶
This device tree overlay describes a mikroe click temperature sensor board operating over (bit-banged) SPI using an adapter board for the control header.
$ cat mikroe-temp-hub-16-spimode.dts
/dts-v1/;
/plugin/;
/{
fragment@1 {
target-path = "/";
__overlay__ {
spi {
compatible = "spi-gpio";
#address-cells = <0x1>;
#size-cells = <0x0>;
sck-gpios = <&gpio3 4 0>;
miso-gpios = <&gpio3 5 0>;
mosi-gpios = <&gpio3 6 0>;
cs-gpios = <&gpio2 29 0>;
num-chipselects = <1>;
status = "okay";
temp-sensor@0 {
compatible = "we-eisos,wsen-hids";
reg = <0>;
spi-max-frequency = <1000000>;
spi-3wire;
};
};
};
};
};
$ dtc -I dts -O dtb -o mikro-temp-hum-16-spimode.dtbo < mikroe-temp-hub-16-spimode.dts
For EFI boot systems¶
Copy the compiled overlay (dtbo
file) onto the EFI partition on the boot device,
for example, overlay/mikroe-temp-hum-16-spimode.dtbo
Then set the U-Boot environment variable extension_overlays
with each
overlay file you want to apply:
# In U-Boot
setenv extension_overlays "overlay/mikroe-temp-hum-16-spimode.dtbo"
saveenv
Manual boot / FIT images¶
When booting FIT images, you need to include your device tree overlay as a configuration in your FIT file
With the OpenWrt mkits-multiple-config.sh
, you can generate such a
FIT template like so:
target/linux/layerscape/image/mkits-multiple-config.sh \
-o kernel-with-overlay.its -A arm64 \
-v "5.10.92" -k "${VMLINUZ_PATH}" -a 0x80000000 \
-e 0x80000000 \
-C gzip -c 1 -c 2 \
-d "${CUR_DTS_PATH}" \
-D "TEN64" -n "ten64" -a 0x90000000 -c 1 \
-d "my-overlay.dtbo" \
-D "Overlayboard" -n "overlabyboard" -a 0x900c0000 -c 3
PATH=$PATH:"${DTC_DIR}" ./staging_dir/host/bin/mkimage -f kernel-with-overlay.its kernel-with-overlay.dtb
Which will look like (some parameters removed for clarity):
/dts-v1/;
/ {
description = "U-Boot fitImage for 5.10.92 kernel";
#address-cells = <1>;
images {
kernel@0 {
...
};
fdt@0 {
description = "Flattened Device Tree blob TEN64";
/* The base ten64 device tree goes here */
data = /incbin/("fsl-ls1088a-ten64.dtb");
...
};
fdt@1 {
description = "Flattened Device Tree blob LEDboard";
data = /incbin/("my-overlay.dtbo");
type = "flat_dt";
arch = "arm64";
load = <0x900c0000>;
compression = "none";
hash@1 {
algo = "sha1";
};
};
};
configurations {
ten64 {
description = "Boot Linux kernel with FDT blob";
kernel = "kernel@0";
fdt = "fdt@0";
hash@1 {
algo = "sha1";
};
};
overlayboard {
description = "Boot Linux kernel with FDT blob";
fdt = "fdt@1";
};
};
Your boot script in U-Boot needs to call bootm with the overlay configuration as the hash-parameter
bootm $load_addr#overlayboard
Troubleshooting¶
You can use the following U-Boot commands to see the FDT contents before and after applying an overlay
=> fdt move $fdtcontroladdr $fdt_addr_r 0x10000
=> fdt print # Print out the FDT before overlay (warning: long)
=> load nvme 0:1 $fdtoverlay_addr_r overlays/mikroe-temp-hum-16-spimode.dtbo
794 bytes read in 0 ms
=> fdt apply $fdtoverlay_addr_r
=> fdt print # Print out the new FDT after overlay application
You could also dump the applied device tree into a DTB file for analysis later:
fatwrite nvme 0:1 $fdt_addr_r overlay_applied_dtb.dtb 0x10000
After booting into Linux, you can also look at the live device tree via sysfs
in /sys/firmware/devicetree
With the spi-gpio overlay described earlier in this document:
/sys/firmware/devicetree/base/spi/
/sys/firmware/devicetree/base/spi/#address-cells
/sys/firmware/devicetree/base/spi/num-chipselects
/sys/firmware/devicetree/base/spi/#size-cells
/sys/firmware/devicetree/base/spi/sck-gpios
/sys/firmware/devicetree/base/spi/temp-sensor@0
/sys/firmware/devicetree/base/spi/temp-sensor@0/spi-max-frequency
/sys/firmware/devicetree/base/spi/temp-sensor@0/compatible
/sys/firmware/devicetree/base/spi/temp-sensor@0/reg
/sys/firmware/devicetree/base/spi/temp-sensor@0/spi-3wire
/sys/firmware/devicetree/base/spi/temp-sensor@0/name
/sys/firmware/devicetree/base/spi/compatible
/sys/firmware/devicetree/base/spi/mosi-gpios
/sys/firmware/devicetree/base/spi/status
/sys/firmware/devicetree/base/spi/miso-gpios
/sys/firmware/devicetree/base/spi/name
/sys/firmware/devicetree/base/spi/cs-gpios
root@OpenWrt:~# hexdump -C /sys/firmware/devicetree/base/spi/compatible
00000000 73 70 69 2d 67 70 69 6f 00 |spi-gpio.|
00000009
If you have the device tree installer compiled, you can also decompile the device tree blob directly back into a dts:
dtc -I dtb -O dts < /sys/firmware/devicetree/base/ > /tmp/booted-device-tree.dts
Note that the 'decompiled' device tree will differ from the "source" DTS for a few reasons:
-
U-Boot applies "fixups" to the device tree to describe hardware settings (like interrupt and IOMMU allocations) that are only known at boot.
-
The device tree compiler does not know about constants and other keywords that can be included in the source device tree - it can only print the raw values.
-
Other overlays may be applied by the firmware (for example, the Ten64 U-Boot applies a backwards compatibility overlay for the emc2301 fan driver).