Ubuntu设备管理udev

Ubuntu设备管理udev

参考资料:

@Ubuntu manuals udev

@CLEARPATH UDEV RULES

udev: Linux dynamic device management

udev的主要作用是完成设备的动态管理

udev提供了与硬件外设之间的系统软件, 负责管理各设备的权限以及将设备通过symlink挂载到/dev/目录下, 为设备赋予别名.

通常情况下, linux的内核会基于发现顺序(先插进去不一定会优先读取)随机为连接的设备分配一个设备名(device name), 因此如果想要可靠的调用某一个设备, 就需要为该设备配置一个规则, 根据别名来进行设备的调用.

symlink的作用就是根据设备的属性(properties)或者当前的配置为设备取别名, 之后可以通过symlink来唯一标识该设备

udev 守护进程(udev daemon)

该守护进程通过systemd-udevd.service配置, 直接从内核中读取设备的添加与移除或者状态的改变. 当udev被硬件设备的事件(uevent)触发, 会根据之前配置好的规则(通常位于/etc/udev/rules.d/*)与设备的各种属性进行匹配, 根据这些属性来识别设备.

属性包括: 设备类型 制造商ID(idVendor), 产品ID(idProduct), 序列号(serial)等

udev rules

udev规则文件可以位于不同的目录中,通常是/etc/udev/rules.d/一般用来存放用户自定义的规则, 和/lib/udev/rules.d/这里存放的是系统默认的以及包管理器管理的规则. 所有的规则文件, 必须.rules结尾, 其他的后缀名会被忽略

所有的udev规则文件中, 每一行至少需要包含一组键值对, 空行与注释行(以#开头)除外.

键值对分为两类, 匹配型(match)以及配置型(assignment), 如果匹配型键值对完全吻合, 则后面的配置型键值对会对该设备进行配置, 应用用户定义的规则

在udev规则中,键值对用于匹配设备属性或指定规则应该执行的动作。每个键(key)后面可以跟随一个操作符(operator),用来定义键和值之间的关系或者操作的类型。不同的操作符有不同的含义,根据操作符的不同,规则可以用来匹配设备、设置属性或执行某些操作。以下是一些有效的操作符及其含义:

== (比较操作符)

  • 用于匹配。如果设备的属性与指定的值相等,则匹配成功。
  • 例如:ATTRS{idVendor}=="0483"匹配制造商ID为0483的设备。

!= (不等操作符)

  • 用于匹配。如果设备的属性与指定的值不相等,则匹配成功。
  • 例如:ATTRS{idVendor}!="0483"匹配所有制造商ID不是0483的设备。

= (赋值操作符)

  • 用于设置属性值。
  • 例如:NAME="my_device"将匹配的设备的名称设置为my_device

+= (追加操作符)

  • 用于向属性追加一个值,或者向列表中添加一个元素。
  • 例如:ENV{ID_USB_DRIVER}+="my_driver"my_driver添加到ID_USB_DRIVER环境变量中。

-= (移除操作符)

  • 用于从列表中移除一个元素。
  • 此操作符较少使用,且应用场景受限。

:= (赋值一次操作符)

  • 用于永久设置属性值。一旦设置,其他规则不能更改此属性。
  • 例如:NAME:="fixed_name"将设备名称永久设置为fixed_name,之后的规则无法更改。

?= (条件赋值操作符)

  • 仅当变量未被设置时,才对其赋值。
  • 例如:ENV{ID_FS_TYPE}?="unknown"如果ID_FS_TYPE环境变量未设置,则将其设置为unknown

udev规则文件的排序规则为字典顺序(lexical order), 即数字小的优先执行, 数字执行完以后执行字母开头的规则, 后执行的会覆盖掉前面的规则

下面是一个编写rules的例子

shell 复制代码
# /etc/udev/rules.d/99-usb-serial.rules

# 规则1: 对于特定制造商ID和产品ID的USB设备,设置SYMLINK和权限
SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", MODE="0666", SYMLINK+="my_usb_device"

# 规则2: 对于具有特定序列号的设备,执行一个脚本
SUBSYSTEM=="usb", ATTRS{serial}=="123456789", RUN+="/path/to/your/script.sh"

# 规则3: 对于特定制造商ID和产品ID的tty设备,改变所有者和组
SUBSYSTEM=="tty", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", OWNER="username", GROUP="dialout", MODE="0660"

# 注意: 
# - SUBSYSTEM 指明了设备的子系统。
# - ATTRS{idVendor} 和 ATTRS{idProduct} 分别指定了USB设备的制造商ID和产品ID。
# - ATTRS{serial} 指定了设备的序列号。
# - MODE 设置了设备文件的权限(例如,0666 表示所有用户都可以读写设备)。
# - SYMLINK+= 为设备创建了一个符号链接,使其更容易被访问。
# - RUN+= 指定了当规则匹配时要执行的命令或脚本。
# - OWNER 和 GROUP 分别指定了设备文件的所有者和所属组。

当新建了一个rules之后, 需要重新加载udev规则

shell 复制代码
sudo udevadm control --reload-rules
sudo udevadm trigger

附录1: 匹配规则键及其作用

键名 描述
ACTION 匹配事件动作的名称。
DEVPATH 匹配事件设备的devpath。
KERNEL 匹配事件设备的名称。
NAME 用于网络接口的名称。一旦在前面的规则中设置了NAME键,就可以使用它。网络设备节点的名称不能通过udev更改,只能创建额外的符号链接。
SYMLINK 匹配指向节点的符号链接的名称。一旦在前面的规则中设置了SYMLINK键,就可以使用它。每个匹配的规则都将此值添加到要创建的符号链接列表中。
SUBSYSTEM 匹配事件设备的子系统。
DRIVER 匹配事件设备的驱动程序名称。仅在事件生成时设备已绑定到驱动程序的情况下设置此键。
ATTR{filename} 匹配事件设备的sysfs属性值。尾随空格在属性值中被忽略,除非指定的匹配值本身包含尾随空格。
KERNELS 向上搜索devpath以匹配设备名称。
SUBSYSTEMS 向上搜索devpath以匹配设备子系统名称。
DRIVERS 向上搜索devpath以匹配设备驱动程序名称。
ATTRS{filename} 向上搜索devpath以匹配具有相应sysfs属性值的设备。如果指定了多个ATTRS匹配项,则所有这些项必须在同一个设备上匹配。尾随空格的处理同ATTR{filename}
TAGS 向上搜索devpath以匹配具有相应标签的设备。
ENV{key} 匹配设备属性值。
TAG 匹配设备标签。
TEST{octal mode mask} 测试文件的存在。如果需要,可以指定一个八进制模式掩码。
PROGRAM 执行一个程序以确定是否匹配;如果程序成功返回,则此键为真。设备属性在执行的程序环境中可用。程序的stdout在RESULT键中可用。仅适用于非常短暂的前台任务。详见RUN
RESULT 匹配最后一次PROGRAM调用返回的字符串。这个键可以在相同的或任何后续规则中使用。

附录2: 配置规则键及其作用

说明
NAME 用于网络接口的名称。设备节点的名称不能通过udev改变,只能创建额外的符号链接。
SYMLINK 指向节点的符号链接的名称。每个匹配规则都会将此值添加到要创建的符号链接列表中。允许的命名字符包括[0-9A-Za-z#+-.:=@_/]、有效的utf8字符序列和"\x00"十六进制编码,所有其他字符都被替换为'_'。可以通过用空格分隔名称来指定多个符号链接。符号链接名称绝不能与内核的默认设备节点名称冲突,以避免不可预测的行为。
OWNER, GROUP, MODE 设备节点的权限。指定的值会覆盖默认值。
ATTR{key} 将指定的值写入事件设备的sysfs属性。
ENV{key} 设置设备属性值。以'.'开头的属性名称既不存储在数据库中,也不导出给事件或外部工具。
TAG 为设备附加一个标签。这用于过滤事件,供libudev的监视功能使用,或用于枚举一组标签设备。仅意味在具有特定设备过滤要求的上下文中使用,并不作为通用标志。过度使用可能导致事件处理效率低下。
RUN{type} 在处理特定事件的所有规则后,添加一个要执行的程序列表,取决于类型:program(执行指定的外部程序)或builtin(使用内置程序而非外部程序)。此项仅适用于非常短暂的前台任务。对于udev事件,启动守护进程或其他长时间运行的进程是不合适的;分叉的进程,无论是否分离,都会在事件处理完成后无条件被杀死。
LABEL 一个命名的标签,GOTO可跳转至此。
GOTO 跳转到下一个匹配的LABEL。
IMPORT{type} 根据类型从不同来源导入一组变量作为设备属性,包括外部程序(program)、内置程序(builtin)、文本文件(file)、当前设备数据库(db)、内核命令行(cmdline)或父设备属性(parent)。
WAIT_FOR 等待文件变得可用,或直到10秒的超时过期。路径相对于sysfs设备;如果未指定路径,则等待属性出现。
OPTIONS 设置规则和设备选项,如link_priority(创建符号链接的优先级)、event_timeout(事件等待操作完成的秒数)、string_escape(字符串转义模式)、static_node(静态设备节点权限)、watch(使用inotify监视设备节点)和nowatch(禁用inotify监视)。
替换 支持使用$kernel, $number, $devpath, $id, $driver, $attr{file}, $env{key}, $major, $minor, $result, $parent, $name, $links, $root, $sys, $devnode, %%, 和 $$ 等替换符,用于NAME, SYMLINK, PROGRAM, OWNER, GROUP, MODE和RUN字段中。替换允许基于设备属性、环境变量等动态值。
相关推荐
Lary_Rock2 小时前
RK3576 LINUX RKNN SDK 测试
linux·运维·服务器
云飞云共享云桌面4 小时前
8位机械工程师如何共享一台图形工作站算力?
linux·服务器·网络
Peter_chq4 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
一坨阿亮5 小时前
Linux 使用中的问题
linux·运维
dsywws6 小时前
Linux学习笔记之vim入门
linux·笔记·学习
幺零九零零7 小时前
【C++】socket套接字编程
linux·服务器·网络·c++
wclass-zhengge7 小时前
Docker篇(Docker Compose)
运维·docker·容器
李启柱7 小时前
项目开发流程规范文档
运维·软件构建·个人开发·设计规范
小林熬夜学编程8 小时前
【Linux系统编程】第四十一弹---线程深度解析:从地址空间到多线程实践
linux·c语言·开发语言·c++·算法
力姆泰克9 小时前
看电动缸是如何提高农机的自动化水平
大数据·运维·服务器·数据库·人工智能·自动化·1024程序员节