Problem
I am trying to add a Linux device tree alias for a network adapter, so U-Boot can assign a static MAC address to it. However, when compiling the kernel, it fails at the adjusted device tree with this error message:
ERROR (path_references): /aliases: Reference to non-existent node or label "r8125_u40" It is about a device tree for the FriendlyELEC NanoPi R6S, based on mainline Linux 6.12:
- https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts?h=linux-6.12.y
- Relevant include: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi?h=linux-6.12.y
What I am adding to/merging into rk3588s-nanopi-r6s.dts is the following:
aliases { ethernet1 = &r8125_u25; ethernet2 = &r8125_u40; }; &pcie2x1l1 { pcie@0,0 { reg = <0x00300000 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; r8125_u25: pcie@30,0 { reg = <0 0 0 0 0>; local-mac-address = [ 00 00 00 00 00 00 ]; }; }; }; &pcie2x1l2 { pcie@0,0 { reg = <0x00400000 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; r8125_u40: pcie@40,0 { reg = <0 0 0 0 0>; local-mac-address = [ 00 00 00 00 00 00 ]; }; }; }; Those are two PCIe network adapters. U-Boot assigns static MAC addresses to ethernet* aliases, so I add the needed PCIe sub devices, give them labels r8125_u25 and r8125_u40 and add the aliases with those labels. This works pretty well for all other SBCs I applied a similar change for PCIe Ethernet adapters, and it works well for r8125_u25 and ethernet1. However, for the very similar second adapter, the compiler refuses to find the node.
What does work
It works perfectly fine to do the same change with a device tree overlay, the alias then is valid, and the Ethernet adapter (all three) get its static MAC address. But I would like to achieve this without overlay.
In Linux 6.13, most of the device tree for this SBC has been moved into another include:
- https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts?h=linux-6.15.y
- New include: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi?h=linux-6.15.y
There, (tested with Linux 6.15) patching above aliases and child nodes into rk3588s-nanopi-r6s.dts works fine. However, I would like to achieve this work current LTS as well.
Solution attempts
To get some quick ideas, I queried an LLM, and tried the following without success:
- Move PCIe device nodes to the top of the device tree source: same error
- Assign the full device path to the alias, instead of the label:
The compiler then complains that this path does not exist.ethernet2 = ${/pcie@fe190000/pcie@0,0/pcie@40,0}; - Assign a
label = "r8125_u40";to the node: same error - Assign a
phandle = <0x1234>;to the node: I did not find a way to assign a phandle to an alias so that it refers to the actual node, instead of just being resolved as number. - Set
status = "okay";explicitly for the node, same error
Apart of this, I could not find any structural difference or invalid dependency or anything that could be a relevant difference and reason why r8125_u40 fails to be resolved, while r8125_u25 works perfectly fine.
I did not try to define the child nodes in a parent/include device tree source. The same kernel will be used for a lot of different SBCs, and I do not want to cause problems by defining a possibly conflicting, at least obsolete node for an SBC which does not have a network adapter attached to the same PCIe bus.
Questions
- Why is the compiler chocking on
&r8125_u40? What are the general rules or limitations in how the device tree compiler is able to resolve symbol labels, or even see nodes defined in the same source file at all? From what I found, it is supposed to parse everything first, and resolve symbols/labels last. Obviously a false assumption in this case. - Is there any workaround to force the parsing/recognition of the child node or its label, before the alias is tried to be assigned, which does not involve a device tree overlay?
ethernet2 = <0x1234>;, which cannot work, as this assigns a hex value only, no reference. And it kept alternating between explaining why this cannot work, and suggesting the very same as solution attempt, showing the limitations of LLMs in general. But e.g. trying${/path}was a good idea, IMO.