Linux udev的使用

udev是Linux应用层的工具,用于管理应用层的设备节点及热插拔功能。

udev的使用主要是修改配置文件,下面就从配置文件开始讲起。

udev 配置文件

udev的规则配置文件在/lib/udev/rules.d目录下,有的系统中会创建运行时规则目录/run/udev/rules.d。文件按顺序执行,一般配置文件使用数字作为文件名的前缀,标识文件的执行顺序。(按照man手册中的描述不一定需要是数字,文件名也没有特殊规则,但是一般都以数字开始,后缀为.rules)。序号越小优先级越高。

当多条规则应用于同一设备时,可根据配置的优先级以及指定的规则判断使用优先级高的规则,还是使用当前规则。

99-usb-serial.rules

udev 服务

udev需要后台服务持续运行以监控系统中的设备事件,在ubuntu中使用systemd-udevd服务。在busybox系统中往往是后台执行的守护进程。

设备信息

udev规则中我们需要设置匹配信息,当规则中的所有匹配规则都与设备相匹配时,将会执行规则中对应的操作。

我们可以通过以下命令获取设备信息

# udevadm info -a -n <设备节点名>
udevadm info -a -n /dev/ttyUSB0

获取到的内容如下,截取一段进行展示。(下面一段文本中#号后为标注,其它为原始打印信息)

下面显示的所有信息都可以用于匹配设备

looking at device '/devices/platform/soc/10300000.xhci_0/usb1/1-1/1-1:1.0/ttyUSB0/tty/ttyUSB0':
KERNEL=="ttyUSB0"				# KERNEL 设备节点在内核中的名称
SUBSYSTEM=="tty"				# SUBSYSTEM 设备的子系统
DRIVER==""

# 后续为递归的父节点信息,逐层显示,直到根节点
# 此处仅截取一部分

# 后续的所有配置信息相对于当前节点都加了‘S’
# 例如KERNEL变为KERNELS SUBSYSTEM变为SUBSYSTEMS
looking at parent device '/devices/platform/soc/10300000.xhci_0/usb1/1-1/1-1:1.0/ttyUSB0':
KERNELS=="ttyUSB0"				# 注意此处为KERNELS 而不是 KERNEL
SUBSYSTEMS=="usb-serial"
DRIVERS=="ch341-uart"
ATTRS{port_number}=="0"

looking at parent device '/devices/platform/soc/10300000.xhci_0/usb1/1-1/1-1:1.0':
KERNELS=="1-1:1.0"
SUBSYSTEMS=="usb"
DRIVERS=="ch341"
ATTRS{bInterfaceProtocol}=="02"
ATTRS{bInterfaceSubClass}=="01"
ATTRS{bNumEndpoints}=="03"
ATTRS{bInterfaceNumber}=="00"
ATTRS{supports_autosuspend}=="1"
ATTRS{authorized}=="1"
ATTRS{bAlternateSetting}==" 0"
ATTRS{bInterfaceClass}=="ff"

looking at parent device '/devices/platform/soc/10300000.xhci_0/usb1/1-1':
KERNELS=="1-1"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{removable}=="unknown"
ATTRS{bMaxPower}=="98mA"
ATTRS{busnum}=="1"					# 总线编号
ATTRS{bmAttributes}=="80"
ATTRS{version}==" 1.10"
ATTRS{quirks}=="0x0"
ATTRS{idProduct}=="7523"			# 设备ID
ATTRS{tx_lanes}=="1"
ATTRS{authorized}=="1"
ATTRS{maxchild}=="0"
ATTRS{configuration}==""
ATTRS{bMaxPacketSize0}=="8"
ATTRS{bDeviceClass}=="ff"
ATTRS{rx_lanes}=="1"
ATTRS{bConfigurationValue}=="1"
ATTRS{devspec}=="          (null)"
ATTRS{bNumInterfaces}==" 1"
ATTRS{ltm_capable}=="no"
ATTRS{devpath}=="1"
ATTRS{idVendor}=="1a86"				# 厂商ID
ATTRS{urbnum}=="12"
ATTRS{devnum}=="3"
ATTRS{speed}=="12"
ATTRS{bNumConfigurations}=="1"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{product}=="USB Serial"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bcdDevice}=="0264"
ATTRS{bDeviceProtocol}=="00"

编写配置文件

配置一条规则主要是两个部分,匹配操作。匹配部分用于匹配设备和事件,操作部分是对设备进行具体的操作。

下面简要描述了配置文件的语法规则。

  1. 配置文件中 ‘#’ 号开头的行为注释,其它行为规则
  2. 一条规则包括其操作只能在一行内完成
  3. 一个规则的每一个匹配或操作使用 ‘,’ 隔开
  4. 多个规则或操作没有顺序要求(一般先写规则匹配,再写操作)
  5. 匹配时可使用指定的模糊匹配规则

下面是一些配置的例子

【注】:设置匹配规则时使用以S结尾的父设备属性时,所有的父设备属性必须来自同一个父设备节点。

例如有如下关系:A–>B–>C。A的父设备为B,B的父设备为C

那么对A设备进行匹配的规则中,以S结尾的父属性必须全部来自于B或者C,而不能交叉引用

# 匹配子系统为tty,内核命名为ttyAMA0的设备,创建软连接到ttysWK0
SUBSYSTEM=="tty", KERNEL=="ttyAMA0", SYMLINK+="ttysWK0"
# 匹配所有的USB虚拟串口设备,且在USB总线3上,创建软连接到ttysWK3
SUBSYSTEM=="tty", KERNEL=="ttyUSB*", ATTRS{busnum}=="3", SYMLINK+="ttysWK3"

应用配置

使用以下命令重新从配置文件中加载配置,并重新配置每一个设备

udevadm control --reload-rules && udevadm trigger

可用的配置

1) 可用的匹配

1. 设备匹配

可用的设备匹配都可以通过udevadm info -a -n命令查看

可用的模糊匹配规则:

  • “*”

    匹配零个或多个字符。

  • “?”

    匹配任何单个字符。

  • “[]”

    匹配括号内指定的任何单个字符。例如,模式字符串“tty[SR]”将匹配”ttyS”或”ttyR”。范围也通过”-“字符支持。例如,为了匹配所有数字的范围,可以使用模式”[0-9]”。如果”[“后面的第一个字符是”!”,则匹配所有未括起来的字符

  • “|”

    分隔备选模式。例如,模式字符串“abc|x”将匹配“abc”或“x”。

2. 事件匹配

事件匹配使用ACTION关键字

# 匹配当sd*设备插入时执行操作
ACTION=="add", SUBSYSTEM=="block", KERNEL="sd*",

常见的事件有三种:

事件 功能
add 设备被添加时
remove 设备被删除时
change 设备属性发生变化时。例如设备的电源状态、配置或其他属性发生变化时

3. 自定义匹配

PROGRAM="cmd", 如果命令或脚本的返回值为0,则认为该规则匹配

2) 可执行的操作

操作 功能
赋值[=] =号赋值用于覆盖之前的赋值
赋值[+=] 追加特定的值给已经存在的键
赋值[:=] 分配一个特定的值给该键,后面的规则不可能覆盖它
RUN RUN=”cmd”, 匹配到设备和事件时执行命令
SYMLINK 软链接,可以使用SYMLINK+=”<链接名>”创建一个软连接

3) 执行操作时可使用的特殊值

# 当USB设备被插入时执行脚本,并将插入的设备名作为参数传递给脚本
KERNEL=="ttyUSB*", ACTION=="add", RUN+="/usr/bin/my_script.sh %k"
引用字符 引用目标
%k 设备KERNEL
%n 设备number
%p 设备devpath
%s{file} 设备属性值{}内为指定属性
%E{key} 指定环境变量的值
%M 主设备号
%m 次设备号
%c PROGRAM自定义匹配规则的终端输出
%P 父设备的设备文件名
%r udev_root值,默认是/dev
%N 临时设备名
%% %符号
$$ $符号

参考文档

  1. Linux系统固定USB串口设备名称
  2. linux固定串口别名的两种方法
  3. Linux下udev规则详解 有较详细的规则描述
  4. linux 设备管理机制(udev)
0%