udev 规则udev Rule)是 Linux 用户态设备管理器 udev 使用的匹配和动作配置,用来根据内核设备事件与 sysfs 属性,为设备节点设置权限、所属组、稳定软链接、环境变量或触发脚本。

在 USB 场景中,它常用 VID:PID、序列号、接口号或 USB 物理路径,把“某类刚插入的设备”变成“普通用户可以访问、路径稳定、脚本能识别的设备”。

核心问题

Linux 内核发现设备后,会通过设备模型和 sysfs 暴露属性,并发出 hotplug 事件。问题是:

  • 默认设备节点权限可能只允许 root 访问。
  • /dev/ttyUSB0/dev/video2 这类编号会随插拔顺序变化。
  • 同型号多设备需要稳定区分。
  • 有些设备插入后需要加载权限、创建别名或触发初始化动作。

udev 规则解决的是“根据设备属性把内核发现的设备映射成用户态可管理资源”的问题。

核心对象

对象含义工程关注点
kernel uevent内核设备事件add、remove、change 等动作
sysfs attribute/sys 下的设备属性idVendoridProductserialinterface
match key规则左侧匹配条件SUBSYSTEMATTR{}KERNELENV{}
assignment key规则右侧动作MODEGROUPSYMLINKTAGRUN
device node/dev 下的节点权限和命名常由 udev 处理
rule file/etc/udev/rules.d/*.rules 等文件数字前缀影响规则顺序

核心机制

1. 事件进入 udev

设备在 USB 枚举 或其他总线发现后,内核发出 uevent。udevd 收到事件后,会读取设备属性并按规则文件顺序匹配。

kernel detects device
  -> emits uevent with subsystem/action/devpath
  -> udev loads sysfs attributes
  -> udev evaluates matching rules
  -> udev applies permissions, symlinks, tags, commands

2. 匹配条件来自当前设备或父设备

常见 USB 规则写法是:

SUBSYSTEM=="usb", ATTR{idVendor}=="2207", ATTR{idProduct}=="0001", MODE="0660", GROUP="plugdev"

这里:

  • SUBSYSTEM=="usb" 匹配 USB 子系统设备。
  • ATTR{idVendor} 匹配当前 sysfs 设备节点上的 idVendor 属性。
  • ATTR{idProduct} 匹配当前 sysfs 设备节点上的 idProduct 属性。
  • MODE="0660" 设置权限位。
  • GROUP="plugdev" 设置设备节点所属组。

如果要匹配子设备,例如 /dev/ttyUSB*/dev/video*,可能需要使用 ATTRS{} 匹配父设备链上的 USB 属性,而不是 ATTR{}ATTR{} 看当前设备,ATTRS{} 可以沿父设备查找匹配属性,这是常见调试点。

3. 稳定命名通常需要比 VID/PID 更细

如果只按 VID/PID 创建软链接:

SYMLINK+="my-device"

多台同型号设备同时存在时会冲突。更稳的规则通常还要加入:

  • ATTRS{serial}:设备提供稳定序列号时优先使用。
  • ENV{ID_PATH}:按物理 USB 拓扑定位,例如固定端口。
  • interface number:区分复合设备中的不同接口。

这和 SN 与 Device ID 的边界类似:VID/PID 描述型号,serial、路径或业务 ID 才能进一步区分实例。

工程用途

  • 给烧录器、调试板、串口、HID、USB 设备授予非 root 访问权限。
  • 为不稳定的 /dev/ttyUSB*/dev/video* 建立稳定软链接。
  • 多相机、多串口、多传感器系统中按 USB by-path 固定角色。
  • 在设备接入时打标签,例如 TAG+="uaccess" 让当前桌面用户获得访问权。
  • 调试设备属性:用 udevadm info --attribute-walk --name=/dev/xxx 找可匹配字段。

边界与常见坑

  • udev 不是驱动:它不会让内核支持一个未知协议,只能在设备已被内核发现后处理权限、命名和动作。
  • VID/PID 匹配不够唯一:多台同型号设备会共享 VID/PID,稳定定位要加 serial、interface 或 path。
  • ATTR{}ATTRS{} 容易混用:当前节点没有 idVendor 时,应检查父设备属性链。
  • 规则修改后要重新加载:常用 udevadm control --reload-rules,再重新插拔或触发 udevadm trigger
  • RUN+= 不适合长任务:udev 触发脚本应短小,长期服务应交给 systemd。
  • 权限不是安全认证:给设备节点放权只解决本机访问控制,不证明设备可信。

相关术语