1 介绍
/usr/lib/udev/rules.d/
该目录下的 .rules 文件是 Linux 发行版或软件包(如硬件驱动、虚拟化工具等)预定义的设备管理规则,用于标准化设备初始化流程
2 规则特性
2.1 优先级控制
规则文件按文件名前缀的数字顺序执行(如 50-xxx.rules 优先于 70-xxx.rules);
/usr/lib/udev/rules.d/ 的优先级低于 /etc/udev/rules.d/,后者可覆盖前者同名文件
2.2 匹配条件与操作指令
匹配键:
SUBSYSTEM(设备子系统)
ATTRS{vendor}(厂商ID)
KERNEL(内核设备名)
ACTION:事件(uevent)的行为,例如:add(添加设备)、remove(删除设备)
操作键:
SYMLINK(创建符号链接)
MODE(设置权限)
RUN(执行命令)
2.3 动态设备响应
udev 守护进程(systemd-udevd)监控内核发出的 uevent 事件(如设备插入、移除),实时应用规则
3 案例
3.1 99-static-ethx.rule
ACTION=="add", SUBSYSTEM=="net", KERNELS=="fe190000.pcie", NAME="eth2"
ACTION=="add", SUBSYSTEM=="net", KERNELS=="fe1b0000.ethernet", NAME="eth1"
匹配条件:
ACTION=="add":仅在设备插入或系统检测到新设备时触发。
SUBSYSTEM=="net":限定规则仅作用于网络设备。
KERNELS=="fe190000.pcie":匹配内核设备路径为 fe190000.pcie 的设备(通常对应 PCIe 总线上的网卡)。
操作:
NAME="eth2":将设备的接口名称固定为 eth2
查看网络设备
root@ubuntu:/# ls ./sys/class/net/
EM05-usb0 can0 docker0 dummy0 enx00e04c600172 eth1 eth2 lo wlan0
root@ubuntu:/#
root@ubuntu:/# find -name fe1b0000.ethernet
./sys/devices/platform/fe1b0000.ethernet
./sys/bus/platform/devices/fe1b0000.ethernet
./sys/bus/platform/drivers/rk_gmac-dwmac/fe1b0000.ethernet
root@ubuntu:/#
udevadm info -a /sys/class/net/eth1
root@ubuntu:/# udevadm info -a /sys/class/net/eth1
Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.
looking at device '/devices/platform/fe1b0000.ethernet/net/eth1':
KERNEL=="eth1"
SUBSYSTEM=="net"
DRIVER==""
ATTR{carrier_down_count}=="1"
ATTR{carrier_changes}=="1"
ATTR{addr_assign_type}=="0"
ATTR{gro_flush_timeout}=="0"
ATTR{napi_defer_hard_irqs}=="0"
ATTR{carrier}=="0"
ATTR{dormant}=="0"
ATTR{dev_id}=="0x0"
ATTR{name_assign_type}=="4"
ATTR{duplex}=="unknown"
ATTR{flags}=="0x1003"
ATTR{operstate}=="down"
ATTR{broadcast}=="ff:ff:ff:ff:ff:ff"
ATTR{speed}=="-1"
ATTR{proto_down}=="0"
ATTR{dev_port}=="0"
ATTR{iflink}=="4"
ATTR{mtu}=="1500"
ATTR{type}=="1"
ATTR{ifalias}==""
ATTR{netdev_group}=="0"
ATTR{carrier_up_count}=="0"
ATTR{address}=="5a:b8:40:7e:45:7a"
ATTR{tx_queue_len}=="1000"
ATTR{link_mode}=="0"
ATTR{addr_len}=="6"
ATTR{testing}=="0"
ATTR{ifindex}=="4"
looking at parent device '/devices/platform/fe1b0000.ethernet':
KERNELS=="fe1b0000.ethernet"
SUBSYSTEMS=="platform"
DRIVERS=="rk_gmac-dwmac"
ATTRS{rgmii_delayline}=="tx delayline: 0x39, rx delayline: 0xffffffff"
ATTRS{driver_override}=="(null)"
looking at parent device '/devices/platform':
KERNELS=="platform"
SUBSYSTEMS==""
DRIVERS==""
root@ubuntu:/#
3.2 99-hmdrv.rules
SUBSYSTEM=="pci", ATTRS{vendor}=="0x1ec8", ATTRS{device}=="0x0800", RUN+="/sbin/insmod /etc/hm/hmcl_drv.ko"
匹配条件:
SUBSYSTEM=="pci":仅针对PCI子系统下的设备。
ATTRS{vendor}=="0x1ec8":匹配厂商ID(Vendor ID)为0x1ec8的硬件设备。
ATTRS{device}=="0x0800":匹配设备ID(Device ID)为0x0800的硬件设备。
执行动作:
RUN+="/sbin/insmod /etc/hm/hmcl_drv.ko":调用insmod命令加载位于/etc/hm/目录下的内核模块hmcl_drv.ko
3.3 99-quectel-tty.rules
SUBSYSTEM=="tty", ACTION=="add", KERNEL=="ttyUSB*", ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0900", RUN+="/usr/local/bin/handle_quectel.sh RM500U"
SUBSYSTEM=="tty", ACTION=="add", KERNEL=="ttyUSB*", ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", RUN+="/usr/local/bin/handle_quectel.sh EM05"
匹配条件:
SUBSYSTEM=="tty":仅匹配 TTY 子系统设备(串口设备)。
ACTION=="add":当设备插入(热插拔事件)时触发规则。
KERNEL=="ttyUSB*":匹配内核设备名以 ttyUSB 开头的设备(如 /dev/ttyUSB0)。
ATTRS{idVendor}=="2c7c":厂商 ID 为 0x2c7c(Quectel 的 USB 标识符)。
ATTRS{idProduct}=="0900":产品 ID 为 0x0900(对应 RM500U 模组)。
执行动作:
RUN+="/usr/local/bin/handle_quectel.sh RM500U":调用脚本 handle_quectel.sh,并传递参数 RM500U(用于标识设备型号)
rockchip@ubuntu:~$ ls /sys/class/tty/
console tty10 tty15 tty2 tty24 tty29 tty33 tty38 tty42 tty47 tty51 tty56 tty60 tty8 ttyS7 ttyUSB3
ptmx tty11 tty16 tty20 tty25 tty3 tty34 tty39 tty43 tty48 tty52 tty57 tty61 tty9 ttyS9 ttyXRUSB1
tty tty12 tty17 tty21 tty26 tty30 tty35 tty4 tty44 tty49 tty53 tty58 tty62 ttyFIQ0 ttyUSB0 ttyXRUSB2
tty0 tty13 tty18 tty22 tty27 tty31 tty36 tty40 tty45 tty5 tty54 tty59 tty63 ttyS3 ttyUSB1 ttyXRUSB3
tty1 tty14 tty19 tty23 tty28 tty32 tty37 tty41 tty46 tty50 tty55 tty6 tty7 ttyS4 ttyUSB2 ttyXRUSB4
rockchip@ubuntu:~$
rockchip@ubuntu:~$ ls /sys/class/tty/ttyUSB*
/sys/class/tty/ttyUSB0:
dev device power subsystem uevent
/sys/class/tty/ttyUSB1:
dev device power subsystem uevent
/sys/class/tty/ttyUSB2:
dev device power subsystem uevent
/sys/class/tty/ttyUSB3:
dev device power subsystem uevent
rockchip@ubuntu:/sys/class/tty/ttyUSB0/device$ lsusb
Bus 006 Device 004: ID 0bda:8153 Realtek Semiconductor Corp. RTL8153 Gigabit Ethernet Adapter
Bus 006 Device 003: ID 05e3:0626 Genesys Logic, Inc. USB3.2 Hub
Bus 006 Device 002: ID 05e3:0620 Genesys Logic, Inc. USB3.2 Hub
Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 005 Device 004: ID 2c7c:0125 Quectel Wireless Solutions Co., Ltd. EC25 LTE modem
Bus 005 Device 003: ID 05e3:0610 Genesys Logic, Inc. 4-port hub
Bus 005 Device 002: ID 05e3:0610 Genesys Logic, Inc. 4-port hub
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 003: ID 04e2:1414 Exar Corp.
Bus 001 Device 002: ID 05e3:0610 Genesys Logic, Inc. 4-port hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
rockchip@ubuntu:/sys/class/tty/ttyUSB0/device$
3.4 100-static-usbnet.rules
将 usb 网卡改成特定网络名称
原来的网络名称为enx00e04c600172
enx00e04c600172: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.98.2.57 netmask 255.255.254.0 broadcast 10.98.3.255
inet6 fe80::1092:af5d:d2c3:da45 prefixlen 64 scopeid 0x20<link>
ether 00:e0:4c:60:01:72 txqueuelen 1000 (Ethernet)
RX packets 8039 bytes 641740 (641.7 KB)
RX errors 0 dropped 278 overruns 0 frame 0
TX packets 1536 bytes 327297 (327.2 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@ubuntu:/# ls ./sys/class/net/
EM05-usb0 can0 docker0 dummy0 enx00e04c600172 eth1 eth2 lo wlan0
root@ubuntu:/#
root@ubuntu:/# find -name enx00e04c600172
./sys/class/net/enx00e04c600172
./sys/devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.6.auto/usb6/6-1/6-1.1/6-1.1.1/6-1.1.1:1.0/net/enx00e04c600172
添加规则
ACTION=="add", SUBSYSTEM=="net", KERNELS=="fc400000.usb", NAME="usbnet"
重启,网络设备名称变了
usbnet: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.98.2.57 netmask 255.255.254.0 broadcast 10.98.3.255
inet6 fe80::44a9:bac:b53b:5ff2 prefixlen 64 scopeid 0x20<link>
ether 00:e0:4c:60:01:72 txqueuelen 1000 (Ethernet)
RX packets 133 bytes 17354 (17.3 KB)
RX errors 0 dropped 1 overruns 0 frame 0
TX packets 123 bytes 16297 (16.2 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@ubuntu:/# ls ./sys/class/net/
can0 docker0 dummy0 eth1 eth2 lo usbnet wlan0
root@ubuntu:/#
root@ubuntu:/# find -name usbnet
./sys/class/net/usbnet
./sys/devices/platform/usbdrd3_1/fc400000.usb/xhci-hcd.6.auto/usb6/6-1/6-1.1/6-1.1.1/6-1.1.1:1.0/net/usbnet