Load devicetree using systemd-boot on Radxa Rock5T

I’ve had NixOS running on a couple of Radxa Rock5Bs for a while now and they’re really well supported. I recently got a Rock5T which is broadly similar but has an extra ethernet port.

Unfortunately Radxa haven’t got the Rock5T into upstream uboot yet, so in order to get the second ethernet port functional I’ve been trying to get systemd-boot to load the appropriate devicetree which is present in the kernel packages.

I found that setting:

hardware.deviceTree.name = "rockchip/rk3588-rock-5t.dtb";

Sets the bootspec properly. So in the repl I get:

nix-repl> config.boot.bootspec.extensions."org.nixos.systemd-boot"
{
  devicetree = "/nix/store/m7gxdm3dv18n2ib57mrdi9jb0g1fq6a9-linux-7.0.10/dtbs/rockchip/rk3588-rock-5t.dtb";
  sortKey = "nixos";
}

And I can confirm the dtb file exists:

$ file "/nix/store/m7gxdm3dv18n2ib57mrdi9jb0g1fq6a9-linux-7.0.10/dtbs/rockchip/rk3588-rock-5t.dtb"
/nix/store/m7gxdm3dv18n2ib57mrdi9jb0g1fq6a9-linux-7.0.10/dtbs/rockchip/rk3588-rock-5t.dtb: Device Tree Blob version 17, size=188782, boot CPU=0, string block size=15906, DT structure block size=172820

But running nixos-rebuild boot fails with the following error:

Traceback (most recent call last):
  File "/nix/store/l5plx8dycs28pbz388qn7wx6swp875ah-systemd-boot/bin/systemd-boot", line 452, in <module>
    main()
    ~~~~^^
  File "/nix/store/l5plx8dycs28pbz388qn7wx6swp875ah-systemd-boot/bin/systemd-boot", line 435, in main
    install_bootloader(args)
    ~~~~~~~~~~~~~~~~~~^^^^^^
  File "/nix/store/l5plx8dycs28pbz388qn7wx6swp875ah-systemd-boot/bin/systemd-boot", line 400, in install_bootloader
    raise e
  File "/nix/store/l5plx8dycs28pbz388qn7wx6swp875ah-systemd-boot/bin/systemd-boot", line 389, in install_bootloader
    write_entry(*gen, machine_id, bootspec, current=is_default)
    ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/nix/store/l5plx8dycs28pbz388qn7wx6swp875ah-systemd-boot/bin/systemd-boot", line 187, in write_entry
    devicetree = copy_from_file(bootspec.devicetree) if bootspec.devicetree is not None else None
                 ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
  File "/nix/store/l5plx8dycs28pbz388qn7wx6swp875ah-systemd-boot/bin/systemd-boot", line 177, in copy_from_file
    copy_if_not_exists(store_file_path, BOOT_MOUNT_POINT / efi_file_path)
    ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/nix/store/l5plx8dycs28pbz388qn7wx6swp875ah-systemd-boot/bin/systemd-boot", line 69, in copy_if_not_exists
    shutil.copyfile(source, tmppath)
    ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/nix/store/lqn6mbgzzdrqq2qkwddcmxj9z6amdd86-python3-3.13.13/lib/python3.13/shutil.py", line 260, in copyfile
    with open(src, 'rb') as fsrc:
         ~~~~^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '/nix/store/m7gxdm3dv18n2ib57mrdi9jb0g1fq6a9-linux-7.0.10/dtbs/rk3588-rock-5t.dtb'

Note that the systemd-boot-builder.py seems to have stripped the rockchip/ directory from the beginning of the devicetree name. Looking through systemd-boot-builder.py I can’t see where this happens.

I have been able to boot using the correct dtb (and the second ethernet & wireless work) by manually copying the dtb to the EFI partition and manually create a boot loader entry, but that obviously isn’t a proper solution!

Does anyone have any suggestions for a proper solution?

1 Like

I found the problem! :person_facepalming:

nixos-rebuild boot was failing because a previous generation did have the wrong devicetree and subsequent attempts were still trying to install that bad generation. Deleting the old generations (nix-collect-garbage -d) fixed it.