
我正在尝试使用 Linux,并试图了解早期的启动过程。至少在我使用过的系统上,udev 是发现设备的“模块”。但是,一旦发现设备,它就会以某种方式“添加”到可用接口列表中,然后您可以执行“ip link set dev up”命令。但在此步骤之前,它不会识别设备名称。
我的问题是这发生在哪里,使用了什么命令?
我知道它发生在“早期用户空间”之后,因为我向我的 initramfs 映像添加了一个钩子并使用“ip link”来转储接口,并且只存在环回接口。
但它肯定发生得很早,当我执行 systemctl 命令时,在我的系统环境中有一个“设备”条目,即 sys-subsystem-net-devices-ens33.device。
目前还不清楚该条目是如何添加到设备列表中的,或者它执行什么命令。
谢谢您的帮助,我一直在寻找,但这个过程的细节并不容易找到。
答案1
没有命令。它首先不是由用户空间完成的 – 它完全由卡的以太网驱动程序完成,该驱动程序使用register_netdev()
内核的“net”子系统来显示新接口。
该过程大致如下:
内核发现 PCI 或 USB 设备,构建描述该设备的“modalias”,并向 udev 发送通告该设备的 uevent。例如:
ACTION=add DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3 DEVTYPE=usb_device SUBSYSTEM=usb ... ACTION=add DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0 DEVTYPE=usb_interface MODALIAS=usb:v0B95p1790d0100dcFFdscFFdp00icFFiscFFip00in00 SUBSYSTEM=usb ...
udev 接收 uevent,根据规则处理它(运行辅助工具、添加各种元数据、创建符号链接)并再次发送它,这次发送给各种使用 libudev 的程序。
udev 规则文件之一
80-drivers.rules
处理包含 的 ueventMODALIAS=
,并使用 libkmod 加载与该别名匹配的任何内核模块。(过去,它用于modprobe
模块加载。不过,您仍然可以将模式别名传递给modprobe
或modinfo
。)$ modinfo usb:v0B95p1790d0100dcFFdscFFdp00icFFiscFFip00in00 filename: /lib/modules/4.7.2-1-ARCH/kernel/drivers/net/usb/ax88179_178a.ko.gz description: ASIX AX88179/178A based USB 3.0/2.0 Gigabit Ethernet Devices alias: usb:v0DF6p0072d*dc*dsc*dp*ic*isc*ip*in* alias: usb:v2001p4A00d*dc*dsc*dp*ic*isc*ip*in* alias: usb:v0B95p178Ad*dc*dsc*dp*ic*isc*ip*in* alias: usb:v0B95p1790d*dc*dsc*dp*ic*isc*ip*in* depends: usbnet,usbcore,mii ...
所以对于这个设备,udev 将加载
ax88179_178a
驱动程序。无论驱动程序是刚刚加载还是之前已经加载,内核都会调用其
.probe
函数将其附加到特定的设备。驱动程序的
probe
功能是执行启动设备、初始化设备、配置设备以及最终调用register_netdev()
来为其自身创建真正的以太网接口所需的所有芯片魔法。(对于 USB 设备,一些驱动程序将探测推迟到
usbnet
模块,模块完成大部分标准 USB 工作并创建实际的以太网接口,并且只调用主驱动程序来执行特定于硬件的魔法。)Sep 04 21:25:11 kernel: ax88179_178a 2-1.3:1.0 eth1: register 'ax88179_178a' ↵ at usb-0000:00:1d.0-1.3, ASIX AX88179 USB 3.0 Gigabit Ethernet, 8c:ae:4c:f4:06:33