systemd boot:从 U-Boot 环境为 eth0 申请 IP 地址?

systemd boot: Apply IP address for eth0 from U-Boot environment?

我有一个使用 systemd 的基于 yocto 的嵌入式 Linux 系统。 U-Boot/coreboot 用于引导系统。 U-Boot 环境中存储了 IP 地址 ...

=> printenv ipaddr
ipaddr=192.168.0.100

...以及 systemd 的 /lib/systemd/network/wired.network:

[Match]
Name=eth0

[Network]
Address=192.168.0.100/24

.

为了测试多台设备,我需要更改 IP 地址,因为多台设备同时连接到网络。

每次都更改 systemd 网络文件是不行的,因为更新后(使用完整的 rootfs 映像,以及 systemd 配置)它会重置为默认值。 所以我的想法是通过内核命令行向 Linux 内核提供 U-Boot IP 地址,正如我之前在其他设备上看到的那样。 不幸的是,我无法找到有关如何在 systemd 上执行此操作的信息,我找到的所有示例都在 System V 上。

我的方法是增强原始(在本例中为 NFS)启动命令:

# cat /proc/cmdline
console=ttyS4,115200 rootwait rw loglevel=1 macaddress=02:00:00:FF:FF:FF root=/dev/nfs nfsroot=192.168.0.1:/srv/nfs/192.168.0.100,v3 ip=192.168.0.100:192.168.0.1:192.168.0.1:255.255.255.0::eth0:off

通过附加 systemd.setenv=ipaddr=192.168.0.100ipaddr=192.168.0.100 之类的内容,并在 systemd 网络配置中引用它:

[Match]
Name=eth0

[Network]
Address=${ipaddr}/24

.

然而,这并没有显示出预期的结果,我所取得的只是一个系统挂起:

[  OK  ] Started System Logger Daemon.
[  OK  ] Started Network Service.
[  OK  ] Started Login Service.
[  OK  ] Started Resetting boot counter.
[  OK  ] Started Bluetooth service.
[  OK  ] Reached target Bluetooth.
[  OK  ] Started Usermode Init Manager for TI Shared Transport line discipline.
         **Starting Wait for Network to be Configured...**
[  OK  ] Started Thermal Daemon Service.
         Starting Hostname Service...

Systemd 版本是: systemd 234 -PAM -AUDIT -SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP -LIBCRYPTSETUP -GCRYPT -GNUTLS +ACL +XZ -LZ4 -SECCOMP +BLKID -ELFUTILS +KMOD -IDN2 -IDN default-hierarchy=hybrid

谁能告诉我这是否可能?如果,如何对事情进行排序?任何提示都会有所帮助。

可以通过Linux内核命令行中的ip=参数设置网络地址https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/nfs/nfsroot.txt#n82

U-Boot 使用变量 bootargs 设置内核命令行。

所以你只需要使用 U-Boot ip-address 来更新 bootargs。

找到解决方案:

systemd-networkd(8) 所述:

Any links not matched by one of the .network files will be ignored. [...] When systemd-networkd exits, it generally leaves existing network devices and configuration intact. This makes it possible to transition from the initramfs and to restart the service without breaking connectivity.

正如Xypron指出的,内核使用ip=命令行参数来配置我已经提供的网络接口。 这意味着,完全 不通过 systemd 重新配置 接口就足够了!

只需删除网络配置即可。 如果未提供 ip= 参数(在默认的 U-Boot 配置中,同时从 mmc 启动),我们应该为 eth0 接口提供默认值. 我们可以通过 而不是 删除文件,而是设置 KernelCommandLine= 条件来实现:

cat <<"EOF" > /lib/systemd/network/wired.network
[Match]
Name=eth0
KernelCommandLine=!ip

[Network]
Address=192.168.0.100/24
EOF

这就是所有人...