embedded adventures

DT Overlay woes

I had the bright idea of using Device Tree Overlays to save some some time on physically power cycling the Steam Link every time I changed the .dts. One day later, I'm starting to think the kernel developers do not want you to really use DT overlays.

I toyed with those a few years back but at the time there seemed to be no convenient way to use them. Guess what! There still isn't.

While the kernel provides an API for working with them, it is not really obvious how to use them from userspace. When DT overlays were proposed for merging they offered a configfs interface where you could just write a file to it and had it applied. This seems super easy and convenient so it was not merged. Some distributions such as xillinux use this patch out-of-tree. RaspberryPi has its own tool called dtoverlay, but it also appears to be based around configfs. As I didn't really want to maintain this patch against upstream kernel changes I dug around some more and found dtbocfg which does essentially the same but as a standalone kernel module.

#insmod dtbocfg.ko
#dmesg -t | tail -n1
dtbocfg_module_init: OK


Let's load the DT overlay.

#mkdir /sys/kernel/config/device-tree/overlays/i2c
#cp steamlink-i2c.dtbo /sys/kernel/config/device-tree/overlays/i2c/dtbo
#echo 1 > /sys/kernel/config/device-tree/overlays/i2c/status
#dmesg -t | tail -n3
OF: resolver: no symbols in root of device tree.
OF: resolver: overlay phandle fixup failed: -22
dtbocfg_overlay_item_create: Failed to apply overlay (ret_val=-22)

Now that's a bit of head-scratcher. Apparently the kernel base dtb is built without symbols (you might think there is a CONFIG switch for this but there is not). Shouldn't be a problem, I will just build it myself with dtc.

#dtc -I dts -O dtb --symbols -o steamlink.dtb arch/arm/boot/dts/berlin2cd-valve-steamlink.dts
Error: ../../arch/arm/boot/dts/berlin2cd-valve-steamlink.dts:7.1-9 syntax error
FATAL ERROR: Unable to parse input tree

Right. These files are not quite dts, they need to be pre-processed first to resolve all the #includes etc. Now how does this preprocessing work again? I was starting to get impatient at this point so I just patched the Makefile.lib.

Built the new root .dtb, rebooted and now the overlays work!