
博主简介:byte轻骑兵,现就职于国内知名科技企业,专注于嵌入式系统研发。深耕 Android、Linux、RTOS、通信协议、AIoT、物联网及 C/C++ 等领域,乐于技术交流与分享。欢迎技术交流。 主页地址:byte轻骑兵-CSDN博客 微信公众号:「嵌入式硬核研究所」 邮箱:byteqqb@163.com 声明:本文为「byte轻骑兵」原创文章,未经授权禁止任何形式转载。商业合作请联系作者授权。
在 Linux 系统的世界里,设备管理是一个重要的环节。而 udev 作为 Linux 用户空间的设备管理器,在其中扮演着关键角色。今天,我们就来深入了解一下 udev 规则文件,看看它是如何工作的,以及我们该如何运用它来更好地管理设备。
小伙伴们,你们知道在 Linux 系统里,设备是怎么被管理的吗?其实有个叫 udev 的家伙在帮忙呢。它就像一个设备管家,能动态地处理设备的连接和断开,还能给设备起名字,是不是很厉害?
udev 运行在用户空间,它可以根据系统内核发出的 uevent 事件来动态管理 /dev 目录下的设备节点。意味着当你插入一个 USB 设备、连接一个外部硬盘或者其他硬件时,udev 会迅速做出反应,创建相应的设备节点,让系统能够识别和使用这些设备。
与传统的设备管理方式相比,udev 有很多优势。传统方式下,设备节点是静态创建的,不管设备是否连接,对应的节点都存在,这不仅浪费资源,还可能导致一些混淆。而 udev 是动态创建设备节点的,只有当设备连接到系统时,才会创建相应的节点,设备断开后,节点也会被移除,非常高效和整洁。
udev 的强大功能很大程度上依赖于其规则文件。udev 规则文件就像是给 udev 制定的操作手册,告诉 udev 当特定设备出现时该如何处理。通过编写规则文件,我们可以自定义设备的命名、设置设备的权限、指定设备的符号链接等等。
比如说,你有多个 USB 设备,每次插入时系统给它们分配的设备名可能不一样,这会给我们使用带来麻烦。但有了 udev 规则文件,我们就可以为每个 USB 设备设置固定的设备名,这样不管你什么时候插入,它的名字都是固定的,是不是很方便?
udev 规则文件通常存放在两个主要的目录下,不同的 Linux 发行版基本都遵循这个规范。
一个是/lib/udev/rules.d/,这个目录下的规则文件是系统默认的,由系统或软件包安装时自动创建。这些规则文件负责处理系统中大部分常见设备的管理,一般情况下我们不要去修改它们,以免影响系统的正常运行。
另一个是/etc/udev/rules.d/,这个目录是给用户自定义规则文件用的。我们自己编写的规则文件就放在这里,而且用户自定义的规则文件优先级比/lib/udev/rules.d/目录下的要高,当两者有冲突时,会以用户自定义的为准。
udev 规则文件的命名是有讲究的,通常的格式是 “数字 + 文件名 +.rules”。这里的数字决定了规则文件的执行顺序,数字越小,执行越早。
比如说,10-udev-test.rules会比20-udev-test.rules先执行。这样的命名规则可以让我们控制规则的执行顺序,避免不同规则之间出现冲突。
我们在命名自己的规则文件时,要根据规则的重要性和依赖关系来选择合适的数字。如果你的规则需要在系统默认规则之前执行,就可以选择一个较小的数字;如果需要在之后执行,就选择一个较大的数字。
udev 规则文件由一系列规则组成,每条规则由多个键值对构成,键值对之间用逗号分隔。这些键分为匹配键和赋值键,匹配键用于匹配特定的设备,赋值键则用于对匹配到的设备进行设置。
常见的匹配键有很多,下面给大家介绍几个常用的:
赋值键用于对匹配到的设备进行各种设置,常用的有:
下面来看一个简单的规则示例:
SUBSYSTEM=="usb", ATTR{idVendor}=="1234", ATTR{idProduct}=="5678", SYMLINK+="myusbdevice"这条规则的意思是:当子系统为 usb,且设备的 idVendor 为 1234,idProduct 为 5678 时,为该设备创建一个名为 myusbdevice 的符号链接。
在 udev 规则文件中,还可以使用通配符和特殊字符来增强规则的灵活性。
例如,SYMLINK+="usb/%k"会创建一个指向该设备节点的符号链接,路径为 /dev/usb/ 内核设备名。
编写 udev 规则并不是一件难事,按照以下步骤来做,就能轻松搞定。
1. 确定设备属性
首先,我们需要获取要匹配设备的属性信息,这可以通过udevadm info命令来实现。
比如,我们要获取一个 USB 设备的信息,可以先插入设备,然后执行以下命令:
udevadm info -a -p /sys/class/usb_device/设备路径其中,设备路径可以通过ls /sys/class/usb_device/来查看。
执行命令后,会输出该设备的详细属性信息,包括 KERNEL、SUBSYSTEM、ATTR 等,这些信息将作为我们编写规则的依据。
2. 编写规则
根据获取到的设备属性,结合我们的需求,编写相应的规则。在编写过程中,要注意使用正确的匹配键和赋值键,以及通配符和特殊变量。
3. 测试规则
规则编写完成后,我们需要测试一下规则是否有效。可以使用udevadm test命令来测试:
udevadm test /sys/class/设备类/设备名如果测试过程中没有报错,并且达到了我们预期的效果,说明规则编写成功。
4. 重新加载规则
当我们修改了规则文件后,需要重新加载规则才能生效,可以使用以下命令:
udevadm control --reload-rules然后可以拔插设备,看看规则是否起作用。
1. 为 USB 设备设置固定的设备名
假设我们有一个 USB 设备,其 idVendor 为 0483,idProduct 为 5750,我们想给它设置一个固定的设备名myusb。
首先,通过udevadm info获取设备属性,确认其 SUBSYSTEM 为usb,idVendor 和 idProduct 分别为 0483 和 5750。
然后,在/etc/udev/rules.d/目录下创建一个规则文件,比如99-usb-naming.rules,在文件中写入以下内容:
SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="5750", SYMLINK+="myusb"保存文件后,执行udevadm control --reload-rules重新加载规则,然后拔插 USB 设备,在 /dev 目录下就会看到myusb这个符号链接了。
2. 根据设备属性设置权限
如果我们想让某个串口设备(比如ttyUSB0)允许所有用户读写,可以编写如下规则:
创建99-serial-permissions.rules文件,内容为:
KERNEL=="ttyUSB0", MODE="0666"重新加载规则后,该串口设备的权限就会被设置为 0666。
3. 自动挂载 USB 设备
虽然 udev 本身不直接负责挂载文件系统,但它可以配合 mount 命令来实现自动挂载。
比如,我们想在插入一个特定的 USB 硬盘(假设其 UUID 为 1234-5678)时,自动将其挂载到/mnt/usbdisk目录。
首先,创建挂载点:
mkdir /mnt/usbdisk然后创建规则文件99-usb-mount.rules,内容为:
SUBSYSTEM=="block", ENV{ID_FS_UUID}=="1234-5678", ACTION=="add", RUN+="/bin/mount /dev/%k /mnt/usbdisk"
SUBSYSTEM=="block", ENV{ID_FS_UUID}=="1234-5678", ACTION=="remove", RUN+="/bin/umount /mnt/usbdisk"这里,SUBSYSTEM=="block"表示匹配块设备,ENV{ID_FS_UUID}=="1234-5678"通过 UUID 来匹配设备,ACTION=="add"表示设备添加时执行挂载命令,ACTION=="remove"表示设备移除时执行卸载命令。
不过需要注意的是,使用 RUN 执行命令时要确保命令的路径正确,并且尽量使用绝对路径。另外,对于复杂的挂载需求,可能还需要考虑文件系统类型等因素。
1. 查看已有的规则
我们可以使用ls命令查看/lib/udev/rules.d/和/etc/udev/rules.d/目录下的规则文件,了解系统中已有的规则。
2. 调试规则
如果规则没有按照预期工作,可以通过查看 udev 的日志来进行调试。udev 的日志通常保存在/var/log/udev或通过journalctl -u systemd-udevd命令查看。
在日志中,我们可以看到 udev 处理设备事件的过程,以及规则的执行情况,从而找出规则存在的问题。
3. 禁用不需要的规则
如果某些系统默认的规则我们不需要,可以在/etc/udev/rules.d/目录下创建一个同名的规则文件(但数字更大),在文件中写入ENV{UDevRuleOverride}="1"来覆盖原规则,或者直接删除原规则文件(不推荐,可能会影响系统更新)。

通过以上的介绍,相信大家对 udev 规则文件有了更深入的了解。udev 规则文件为我们管理 Linux 设备提供了强大的灵活性,只要我们掌握了它的基本用法,就能够根据自己的需求自定义设备的管理方式,让 Linux 系统更好地为我们服务。希望这篇文章能对你有所帮助,快去动手试试编写自己的 udev 规则吧!