udev 是 Linux 内核的设备管理器。总的来说,它取代了devfs和hotplug,负责管理/dev中的设备节点。同时,udev 也处理所有用户空间发生的硬件添加、删除事件,以及某些特定设备所需的固件加载。

udev是systemd的组成部分,默认已安装,有关信息可查阅systemd-udevd.service的手册页。

udev和devfs比较

1.devfs运行在内核空间(使用devfs_register等API在内核空间注册设备节点);而udev运行在用户空间。

2.当用户访问/dev下的某个节点时,devfs会自动加载对应的驱动;而udev则并不负责自动加载驱动的工作(2.6版本内核,驱动是在设备被插入/移除时被加载/卸载的,而不是设备被访问时就加载驱动)。采用devfs,当一个并不存在的/dev节点被打开时,devfs能自动加载对应的驱动,而udev则不会。这是因为udev的设计者认为linux应该在设备被发现的时候加载驱动模块,而不是当被访问的时候。udev的设计者认为devfs所提供的打开/dev节点时自动加载驱动的功能对于一个配置正确的计算机是多余的。系统中所有的设备都应该产生热插拔事件并加载恰当的驱动,而udev能注意到这点并且为它创建对应的设备节点。

udev完全在用户态工作,利用设备加入或移除时内核所发送的热插拔事件(hotplug event)来工作。在热插拔时,设备的详细信息都会由内核输出到位于/sys的sysfs文件系统。udev的设备命名策略、权限控制和事件处理都是在用户态完成的,它利用sysfs中的信息来进行创建设备文件节点等工作。

由于udev根据系统中硬件设备的状态动态更新设备文件,进行设备文件的创建和删除等,因此,在使用udev后,/dev目录下就会只包含系统中真正存在的设备了。

udev的组成

udev的主页位于https://mirrors.edge.kernel.org/pub/linux/utils/kernel/hotplug/udev/udev.html

udev以3个分割的子计划发展:namedev、libsysfs和udev。namedev为设备命名子系统,libsysfs提供访问sysfs文件系统从中获取信息的标准接口,udev提供/dev设备节点文件的动态创建和删除策略。udev程序承担与namedev和libsysfs库交互的任务,当/sbin/hotplug程序被内核调用时,udev将被运行。

udev的工作过程如下:

1)  当内核检测到在系统中出现了新设备后,内核会在sysfs文件系统中为该新设备生成新的记录并导出一些设备特定的信息及所发生的事件。

2)  udev获取内核导出的信息,它调用namedev决定应该给设备指定的名称,如果是新插入设备,udev将调用libsysfs决定应该为该设备的设备文件指定的主次设备号,并用分析获得的设备名称和主次设备号创建/dev/中的设备文件;如果是设备移除,则将已经创建的/dev文件被删除。

另一种解释:

Udev完全工作在用户空间,当一个设备被插入或者移除时,内核会通过netlink套接字发送设备详细信息到用户空间,udev获取到设备信息,根据信息内容在/dev下创建并命名设备节点。

既然udev创建节点的时机是设备被插入的时候,那么就出现一个问题:

冷插拔的设备怎么办

由于冷插拔的设备开机时就已经存在,在udev启动前已经被插入。针对这种情况,sysfs下的设备都存在uevent文件,向该文件写一个“add”,内核会重新发送netlink,之后udev就可以收到设备的详细信息了,从而创建/dev下对应的设备节点。

udev确定设备名:

udev的配置文件是/etc/udev/udev.conf,可能包含#开头的注释,然后有几行选项:

udev_root="/dev/"

#udev_log="err"

udev_rules="/etc/udev/rules.d/"

第一行配置udev的log级别,可以为err,info和debug。用于控制将哪些消息发送到系统日志。

第二行配置udev规则存储目录,一般采用默认值。

udev规则

udev规则以管理员身份编写并保存在/etc/udev/rules.d/目录,其文件名必须以.rules结尾。各种软件包提供的规则文件位于/lib/udev/rules.d/。如果/lib和/etc这两个目录中有同名文件,则/etc中的文件优先。规则文件的文件名通常是两个数字开头,它表示系统应用该规则的顺序。

udev规则文件以行为单位,以“#”开头的行代表注释行,其余的每一行代表一个规则。规则有一系列的键值对组成,键值对之间用逗号分隔。每个规则分成一个或多个匹配和赋值部分。匹配部分用匹配专用的关键字来表示,赋值部分用赋值专用的关键字来表示。匹配键确定规则是否被应用,而赋值键表示分配某值给该键

1.  udev 规则的所有操作符

“==”  比较键、值,若等于,则该条件满足;

“!=”   比较键、值,若不等于,则该条件满足;

“=”    对一个键赋值;

“+=”  为一个表示多个条目的键赋值。

“:=”  对一个键赋值,并拒绝之后所有对该键的改动。目的是防止后面的规则文件对该键赋值。

2.  udev 规则的匹配键

NAME:     匹配事件设备名。

ACTION  事件 (uevent) 的行为,例如:add( 添加设备 )、remove( 删除设备 )。

KERNEL  内核设备名称,例如:sda, cdrom。

DEVPATH  设备的 devpath 路径。

SUBSYSTEM 设备的子系统名称,例如:sda 的子系统为 block。

BUS    设备在 devpath 里的总线名称,例如:usb。

DRIVER  设备在 devpath 里的设备驱动名称,例如:ide-cdrom。

ATTR{filename}设备的 devpath 路径下,设备的属性文件“filename”里的内容。例如:SYSFS{model}==“ST936701SS”表示:如果设备的型号为 ST936701SS,则该设备匹配该匹配键。在一条规则中,可以设定最多五条ATTRS的匹配键。属性文件在/sys目录下。

ATTRS{filename}:设备的父(向上)的devpath路径下设备属性文件filename里的内容。在一条规则中,可以设定最多五条ATTRS的匹配键。若有多个ATTRS,则多个ATTRS应指向同一个父设备(父设备目录)。属性文件在/sys目录下。

ENV{key} 环境变量,这里指除上述专有系统执行匹配键外uevent输出的键值对中的键,如idVendor设备厂商号,用ATTR(S)则为ATTR{idVendor}或ATTRS{idVendor}(在/sys目录下devpath下有文件idVendor),而应用ENV则应为ENV(ID_VENDOR_ID)(udevadm monitor -k -p -u显示设备插入时显示的uevent)。ENV在一条规则中,可以设定最多五条环境变量的匹配键。

PROGRAM  调用外部命令。

RESULT  外部命令 PROGRAM 的返回结果。

3.  udev 的重要赋值键

NAME在 /dev下产生的设备文件名。只有第一次对某个设备的 NAME 的赋值行为生效。之后匹配的规则再对该设备的 NAME 赋值行为将被忽略。如果没有任何规则对设备的 NAME 赋值,udev 将使用内核设备名称来产生设备文件。一般系统下设备节点name不能被udev改变,只能增加symlinks。

SYMLINK为/dev/下的设备文件产生符号链接。由于udev只能为某个设备产生一个设备文件,所以为了不覆盖系统默认的udev规则所产生的文件,推荐使用符号链接。

OWNER, GROUP, MODE  为设备设定权限。

ATTR{key}值应该写入事件设备的sysfs属性文件中。

ENV{key}设置设备属性值,以“.”开头的属性不会存储到database,也不会导出到events或外部工具。

RUN{type}:增加可执行程序到event设备,当所有规则匹配时。type可取program(默认)或builtin。程序名与参数用空格分隔,可用单引号指定包含空格的参数。

udev仅仅可运行短时间的任务,长时间的任务会阻塞udev后续event,且event处理完后程序会被强制退出(kill)或超时(默认180s)强制退出。

4.  udev 的值和可调用的替换操作符 

Linux 用户可以随意地定制 udev 规则文件的值。例如:my_root_disk, my_printer。同时也可以引用下面的替换操作符:

$kernel, %k:       设备的内核设备名称,例如:sda、cdrom。

$number, %n       设备的内核号码,例如:sda3 的内核号码是 3。

$devpath, %p       设备的 devpath路径。

$id, %b         设备在 devpath里的 ID 号。

$sysfs{file}, %s{file}  设备的 sysfs里 file 的内容。其实就是设备的属性值。$env{key}, %E{key}:    一个环境变量的值。

$major, %M        设备的 major 号。

$minor %m        设备的 minor 号。

$result, %c       PROGRAM 返回的结果。

$parent, %P        父设备的设备文件名。

$root, %r        udev_root的值,默认是 /dev/。

$tempnode, %N      临时设备名。

$name:                         当前设备名。

%%            符号 % 本身。

$$            符号 $ 本身。

SUBSYSTEM=="tty", ACTION=="add", ENV{ID_VENDOR_ID}=="067b", ENV{ID_MODEL_ID}=="", MODE="", GROUP="plugdev", SYMLINK+="zigbee", RUN+="/bin/systemctl restart usb_detect"
SUBSYSTEM=="tty", ACTION=="remove", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="", RUN+="/bin/systemctl stop usb_detect" SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="", ATTRS{idProduct}=="", MODE="", GROUP="plugdev", RUN+="/bin/systemctl restart testusb"
SUBSYSTEM=="usb", ACTION=="remove", ENV{DEVTYPE}=="usb_interface", ENV{PRODUCT}=="403/6010/700", RUN+="/bin/systemctl stop testusb"

udev命令udevadm

udevadm是udev管理工具。udevadm expects a command and command specific options. It controls the runtime behavior of systemd-udevd, requests kernel events, manages the event queue, and provides simple debugging mechanisms. udevadm 后接一个命令和命令指定选项。它控制了udev运行的行为,处理内核事件,控制事件队列,并且提供简单的调试机制。

--debug 打印错误信息

--version 打印版本信息

--help 帮助文档

udevadm info [options] [devpath|file|unit…]

查询udev数据库中的设备信息。也可以从sysfs文件系统中查询到设备的属性以辅助创建udev规则。位置参数应该指定一个设备名(/dev开头),或一个syspath(以/sys/开头),或systemd device单元(以.device结尾)。

--query=type              从数据库中查询指定类型的设备。需要--path和--name来指定设备。合法的查询文件是:设备名,链接,路径,属性

--path=devpath          设备的路径

--name=file                 设备节点或者链接

--attribute-walk           打印指定设备的所有sysfs记录的属性,以用来udev规则匹配特殊的设备。该选项打印链上的所有设备信息,最大可能到sys目录。

--device-id-of-file=file 打印主/从设备号

--export-db                 输出udev数据库中的内容

常用:

udevadm info -a -n /dev/sda ;列出设备属性

udevadm info -a -p /sys/class/backlight/acpi_video0   ;列出某个系统路径的属性

udevadm trigger [options] [devpath|file|unit…]

接收内核发送来的设备事件。主要用于重放(replay)coldplug事件信息。

(内核在启动时已经检测到了系统的硬件设备,并把硬件设备信息通过sysfs内核虚拟文件系统导出。udev扫描sysfs文件系统,根据硬件设备信息生成热插拔(hotplug)事件,udev再读取这些事件,生成对应的硬件设备文件。由于没有实际的硬件插拔动作,所以这一过程被称为coldplug。)

--verbose             输出将要被触发的设备列表。

--dry-run              不真的触发事件

--type=type         触发一个特殊的设备。合法的类型:devices/subsystem/failed.默认是devices

--action=action    被触发的事件,默认是change

--subsystem-match=subsystem       触发匹配子系统的设备事件。这个选项可以被多次指定,并且支持shell模式匹配。

--attr-match=attribute=value   触发匹配sysfs属性的设备事件。如果属性值和属性一起指定,属性的值可以使用shell模式匹配。如果没有指定值,会重新确认现有属性。这个选项可以被多次指定。

--attr-nomatch=attribute=value   不要触发匹配属性的设备事件。如果可以使用模式匹配。也可以多次指定

--property-match=property=value 匹配属性吻合的设备。可以多次指定支持模式匹配

--tag-match=property               匹配标签吻合的设备。可以多次指定。

--sysname-match=name           匹配sys设备名相同的设备。可以多次指定支持模式匹配。

一般systemd-udev-trigger.service中应用udevadm trigger回放coldplug:

ExecStart=/bin/udevadm trigger --type=subsystems --action=add ; /bin/udevadm trigger --type=devices --action=add

udevadm settle [options]

查看udev事件队列,如果所有事件全部处理完就退出。

--timeout=seconds             等待事件队列空的最大时间。默认是180秒。如果是0则立即退出。

--seq-start=seqnum           只等待到给定的顺序号。

--seq-end=seqnum            只等待到给定顺序号之前。

--exit-if-exists=file             如果文件存在就退出

--quiet                  不输出任何信息

udevadm monitor [options]

监听内核事件和udev发送的events事件。打印事件发出的设备。可以通过比较内核或者udev事件的时间戳来分析事件时序。

-k, --kernel         输出内核事件

-u, --udev           输出udev规则执行时的udev事件

-p, --property     输出事件的属性

--subsystem-match=string        通过子系统或者设备类型过滤事件。只有匹配了子系统值的udev设备事件通过。

--tag-match=string            通过属性过滤事件,只有匹配了标签的udev事件通过。

一般常用udevadm monitor -k -p -u监控uevent事件

udevadm control command

修改运行的udev守护进程的内部状态。

udevadm test [options] devpath

模拟一个udev事件,打印出debug信息。

常用:

udevadm test $(udevadm info -q path -n /dev/sda) 2>&1  ;加载前测试设备规则

udevadm test /sys/class/block/sda    ;也可指定设备路径,加载前测试设备规则

udevadm test-builtin [options] [command] devpath

对设备devpath运行内置command并打印debug信息。

参考:

  1. udev archlinux百科
  2. LINUX下 Udev详解
  3. 内核驱动模块如何在/dev文件下自动创建设备
  4. Writing udev rules
  5. udevadm命令详解
  6. Udev: Introduction to Device Management In Modern Linux System
  7. udev规则以及编写  mount.sh 自动挂载U盘

udev简述的更多相关文章

  1. Linux设备管理之权限倾斜——mem、proc、devfs、sysfs、udev(下)

    linux发展第一阶段 01devfs(linux2.6之前) 02udev(用户空间) 03sysfs(linux2.6之后,描述设备属性) linux发展第二阶段 01sysfs+udev(ude ...

  2. Linux自动共享USB设备:udev+Samba

    一.概述 公司最近要我实现USB设备插入Ubuntu后,自动共享到网络上,能像Windows共享一样(如\\192.168.1.10)访问里面的内容,不需要写入权限.当时听完这需求,我这新人表示惊呆了 ...

  3. 简述 OAuth 2.0 的运作流程

    本文将以用户使用 github 登录网站留言为例,简述 OAuth 2.0 的运作流程. 假如我有一个网站,你是我网站上的访客,看了文章想留言表示「朕已阅」,留言时发现有这个网站的帐号才能够留言,此时 ...

  4. JavaScript单线程和浏览器事件循环简述

    JavaScript单线程 在上篇博客<Promise的前世今生和妙用技巧>的开篇中,我们曾简述了JavaScript的单线程机制和浏览器的事件模型.应很多网友的回复,在这篇文章中将继续展 ...

  5. Design Patterns Simplified - Part 3 (Simple Factory)【设计模式简述--第三部分(简单工厂)】

    原文链接:http://www.c-sharpcorner.com/UploadFile/19b1bd/design-patterns-simplified-part3-factory/ Design ...

  6. Android网络定位服务定制简述

    Android 添加高德或百度网络定位服务 Android的网络定位服务以第三方的APK方式提供服务,由于在国内Android原生自带的com.google.android.gms服务几乎处于不可用状 ...

  7. 《Entity Framework 6 Recipes》翻译系列 (1) -----第一章 开始使用实体框架之历史和框架简述

    微软的Entity Framework 受到越来越多人的关注和使用,Entity Framework7.0版本也即将发行.虽然已经开源,可遗憾的是,国内没有关于它的书籍,更不用说好书了,可能是因为EF ...

  8. 简述ASP.NET MVC原理

    1.为什么ASP.NET需要MVC? 因为随着网站的的数量级越来越大,原始的网站方式,这里指的是WebForm,在运行速度和维护性方面,以及代码量上面,越来越难以满足日益庞大的网站维护成本.代码的重构 ...

  9. Design Patterns Simplified - Part 2 (Singleton)【设计模式简述--第二部分(单例模式)】

    原文链接: http://www.c-sharpcorner.com/UploadFile/19b1bd/design-patterns-simplified-part-2-singleton/ De ...

随机推荐

  1. SharePoint 2013怎样创建Wiki库

    们使用Wiki页面来分享知识,增进团队合作.下面我将向大家展示SharePoint 2013 Wiki的使用方法.教程我都将以这张Wiki页面(即当前页)为示例. 编辑页面 如要编辑页面,单击顶部Ed ...

  2. linux中chkconfig 启动程序顺序介绍

    1)redhat的启动方式和执行次序是: 加载内核 执行init程序 /etc/rc.d/rc.sysinit          # 由init执行的第一个脚本 /etc/rc.d/rc $RUNLE ...

  3. Python 文件 close() 方法

    描述 Python 文件 close() 方法用于关闭一个已打开的文件.关闭后的文件不能再进行读写操作, 否则会触发 ValueError 错误. close() 方法允许调用多次. 当 file 对 ...

  4. [转] JDBC中的Statement和PreparedStatement的区别

    以Oracle为例吧 Statement为一条Sql语句生成执行计划,如果要执行两条sql语句select colume from table where colume=1;select colume ...

  5. Python 爬虫 大量数据清洗 ---- sql语句优化

    . 问题描述 在做爬虫的时候,数据量很大,大约有五百百万条数据,假设有个字段是conmany_name(拍卖公司名称),我们现在需要从五百万条数据里面查找出来五十家拍卖公司, 并且要求字段 time( ...

  6. 使用inno setup 制作安装文件-demo1

    ; 脚本由 Inno Setup 脚本向导 生成! ; 有关创建 Inno Setup 脚本文件的详细资料请查阅帮助文档! #define MyAppName "查体管理系统" # ...

  7. Intel CPU命名规则

    intel的几代CPU中,后缀字母主要有以下几种:M:笔记本专用CPU,一般为双核,M前面一位数字是0,意味着是标准电压处理器,如果是7,则是低电压处理器.U:笔记本专用低电压CPU,一般为双核,U前 ...

  8. Vue(七):computed计算属性

    简介 计算属性关键词: computed. 计算属性在处理一些复杂逻辑时是很有用的. 实例1 可以看下以下反转字符串的例子: <div id="app"> {{ mes ...

  9. 谷歌IP地址

    http://www.yuxiaoxi.com/2014-06-11-google-meet-you.html

  10. OC中几种延时操作的比較

    1. sleepForTimeInterval,此函数会卡住当前线程,一般不用 <span style="font-size:18px;">[NSThread slee ...