在之前编程首先语音刷抖音的博文里提到过udev,现在回顾一下:
什么是udev?
- udev是一个设备管理工具,udev以守护进程的形式运行,通过侦听内核发出来的uevent来管理/dev目录下的设备文件。udev在用户空间运行,而不在内核空间 运行。它能够根据系统中的硬 件设备的状态动态更新设备文件,包括设备文件的创建,删除等。设备文件通常放在/dev目录下。使用udev后,在/dev目录下就只包含系统中真正存在的设备。
本节就深入学习以下udev相关的知识,以下是一些参考链接:
[Linux 基础] -- udev 和 rules 使用规则_udev rules_BestW2Y的博客-CSDN博客
udev概述
在之前多次提到过:Linux中一切皆文件 。在早期的 Linux 版本中,/dev 目录包含了所有可能出现的设备的设备文件。很难想象 Linux 用户如何在这些大量的设备文件中找到匹配条件的设备文件。现在 udev 只为那些连接到 Linux 操作系统的设备产生设备文件 。并且 udev 能通过定义一个 udev 规则(rule)来产生匹配设备属性的设备文件,这些设备属性可以是内核设备名称、总线路径、厂商名称、型号、序列号或者磁盘大小等等。
udev 添加/删除 设备文件的过程
udev的规则(rule)
规则文件是 udev 里最重要的部分,默认是存放在 /etc/udev/rule.d/ 下。所有的规则文件必须以 ".rules" 为后缀名。
下面是一个简单的规则:(规则就是规则文件里的内容)
cpp
KERNEL=="sda", NAME="my_root_disk", MODE="0660"
其中:KERNEL 是匹配键,NAME 和 MODE 是赋值键。这条规则的意思是:如果有一个设备的内核名称为 sda,则该条件生效,执行后面的赋值:在 /dev 下产生一个名为my_root_disk 的设备文件,并把设备 文件的权限设为 0660。
同时,在语音刷抖音项目中,手机接入香橙派不能识别的解决办法,也是在udev的rules文件夹下创建规则文件" 51-android.rules ",并写入以下规则:
cppSUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0666"
为什么此处的规则要这么写?
首先,插入的手机usb设备对应的设备文件在"/dev/bus/usb/001"下:
可见,这个文件的名字是063(001是系统的)
通过" udevadm info --attribute-walk --name=/dev/bus/usb/001/设备名字 " 可以看到设备的详细信息,此处设备名字就写063:
其中,就可以找到刚刚规则中第一句" SUBSYSTEM=="usb""的由来:
、
- 这也是为什么规则第一句写上" SUBSYSTEM=="usb"",udev就能知道:这条规则是针对手机这个设备。
- 第二句的" ENV{DEVTYPE}=="usb_device" ",和第一句一样,都是匹配键:用来设置环境变量;
- 最后一句的" MODE="0666" "才是赋值键,用来赋予权限
所以其实,想要通过规则来匹配一个设备文件,方法不止一种,我同样可以用其他的属性来进行匹配:
比如,在上图打印的信息中注意到了VID和PID的值,用他们来写规则:
cppSUBSYSTEM=="usb", ATTR{idProduct}=="ff08", ATTR{idVendor}=="2717", MODE="0666"
那么现在这条规则实现的效果 和 "之前那条使用环境变量来匹配的规则实现的效果" 是一样的。
为了验证,我修改 " /etc/udev/rules.d/ " 下的 "51-android.rules":
然后再次插入手机。并查看"/dev/bus/usb/001"路径:
可见,多了一个078
然后调用"adb devices":
可见可以成功脸上,说明用新的规则确实可以成功匹配到手机的设备文件
udev 规则的匹配键
- ACTION:事件(uevent)的行为,例如:add(添加设备)、remove(删除设备)
- KERNEL:内核设备名称,例如:sda,cdrom
- DEVPATH:设备的 devpath 路径
- SUBSYSTEM:设备的子系统名称,例如:sda 的系统为 block
- BUS:设备在 devpath 里的总线名称,例如:usb
- DRIVER:设备在 devpath 的设备驱动名称,例如:ide-cdrom
- ID:设备在 devpath 里的识别号
- SYSFS{filename}:设备的 devpath 路径下,设备的属性文件 "filename" 里的内容
- ENV{key}:环境变量。在一条规则中,可以设定最多五条环境变量的 匹配键
- PROGRAM:调用外部命令
- RESULT:外部命令 PROGRAM 的返回结果
U盘的自动挂载
拿出我的U盘,它同样有一个USB口,将它接入香橙派:
然后执行" dmesg "指令:
可见,内核识别到了这个设备!且显示是sda4
然后执行"sudo mount /dev/sda4 /mnt/ " 再 "cd /mnt" 就可以查看U盘中的内容:
(乱码是因为文件名是中文)
但是这样很麻烦,每次U盘插入后还要执行两个指令,可以用udev来实现U盘的自动挂载:
首先,执行**"** **udevadm info --attribute-walk --name=/dev/sda4 "**来查看U盘的信息:
在里面可以选取用于匹配U盘的udev规则,通常使用KERNAL 或 SUBSYSTEM来匹配U盘
那么话不多说,直接再次 " cd /etc/udev/rules.d/ " 然后 " sudo vim my_storage.rules "
规则具体为:
cpp
ACTION=="add", SUBSYSTEMS=="block", SUBSYSTEM=="block", RUN{program}+="/bin/mkdir
/media/%k" ,RUN{program}+="/usr/bin/systemd-mount --no-block --collect $devnode
/media/%k"
- ACTION:匹配键,匹配添加设备的动作
- SUBSYSTEMS:匹配键,匹配为block(此处也可以是usb)
- SUBSYSTEM:匹配键,匹配为block
通过这三个匹配键,匹配到U盘
- RUN:运行命令,此处执行" /bin/mkdir "指令创建一个名为"media"的文件夹,里面有名为"%k" 的文件,%k是sda/sdb的通配符
- RUN:运行命令,此处执行" /usr/bin/systemd-mount "指令挂载U盘到"%k"文件夹下
实现效果
重新拔插U盘,并"sudo service udev restart"重启udev后,查看media文件夹:
可见此时没有输入任何命令,就可以访问U盘的文件了,成功实现了U盘的自动挂载!
另外,可以安装一个tree指令来查看U盘文件,使用"sudo apt-get install tree"来安装;
安装完成后,进入media文件夹后,直接输入"tree ",就可以清晰的看到文件结构了:
此时拔掉U盘,再次输入"tree":
可见,此时就没有任何文件了!