完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本文来自:http://www.linuxeden.com/html/front/20091224/69783.html 现代Linux发行版可以在已经运行的系统里面识别一个新加入的硬件。有许多用户友好的发行版,比如Ubuntu,可以在像iPod这样的移动设备插入系统时自动运行指定的应用程序,比如Rhythmbox。 Linux发行版里面的热插拔(这个词用于描述将设备插入已经运行的系统的过程)功能是三个组件的融合:Udev, HAL, and Dbus. Udev为已经连接在系统上面的设备节点提供一个动态设备目录。当设备插入或移出系统的时候,Udev就在 /dev目录下面创建或者删除设备节点文件。Dbus类似于系统总线,主要用于进程间通信。HAL从Udev的服务中获取信息,当一个设备连接到系统时它 就创建关于这个设备的XML描述。然后它会通过Dbus通知相应的桌面应用程序,比如说Nautilus,Nautius则会打开这个新挂载设备上面的文 件。 本文只关注Udev, 是它完成了基本的设备识别。 什么是Udev? Udev是Linux 2.6内核的设备管理器,它在/dev目录下动态地创建/移除设备节点。它是devfs和hotplug的继承者,运行在用户空间,并且用户可以用Udev规则来改变设备的命名。 Udev依赖2.5内核引入的sysfs文件系统。sysfs是的设备在用户空间可见。每当一个设备被加入或移除,就会产生内核事件通知用户空间的Udev。 在早期的发行中常使用一个外部二进制文件/***in/hotplug来将设备状态的改变通知Udev。现在这个工具已经被替换掉,Udev可以通过Netlink直接监听这些事件了。 为什么我们需要它 ? 在早期的内核中/dev目录包括一些静态的设备文件。而使用动态设备创建后,只有那些真正存在于系统中的设备节点才会被创建。让我们来看看静态/dev目录的缺点,正是这些缺点导致了Udev的开发。 在/dev的设备节点中精确辨别一个硬件设备的问题 在系统启动过程中,内核会为一个识别到的硬件设备分配一个主/次设备号对。让我们考虑两个硬盘,连接/校准的的方式是一个连接到主接口,另一个连接 到从接口。Linux系统会称它们为/dev/hda和/dev/hdb。现在,如果我们交换两个磁盘,那么它们的设备名也会改变。这使得将一个可用的动 态设备节点定位到正确的设备发生困难。当有一堆的硬盘连接在系统时,情况会变得更加糟糕。 Udev通过/dev目录提供了一个永久性设备命名系统,使得定位设备变得容易。 下面是一个例子,显示了Udev为接入系统的硬盘创建的永久性符号链接。 $ ls -lR /dev/disk/ /dev/disk/by-id: lrwxrwxrwx 1 root root 9 Jul 4 06:48 scsi-SATA_WDC_WD800JD-75M_WD-WMAM9UT48593 -> ../../sda lrwxrwxrwx 1 root root 10 Jul 4 06:48 scsi-SATA_WDC_WD800JD-75M_WD-WMAM9UT48593-part1 -> ../../sda1 lrwxrwxrwx 1 root root 10 Jul 4 06:48 scsi-SATA_WDC_WD800JD-75M_WD-WMAM9UT48593-part2 -> ../../sda2 lrwxrwxrwx 1 root root 10 Jul 4 06:48 scsi-SATA_WDC_WD800JD-75M_WD-WMAM9UT48593-part3 -> ../../sda3 lrwxrwxrwx 1 root root 10 Jul 4 06:48 scsi-SATA_WDC_WD800JD-75M_WD-WMAM9UT48593-part4 -> ../../sda4 lrwxrwxrwx 1 root root 10 Jul 4 06:48 scsi-SATA_WDC_WD800JD-75M_WD-WMAM9UT48593-part5 -> ../../sda5 lrwxrwxrwx 1 root root 10 Jul 4 06:48 scsi-SATA_WDC_WD800JD-75M_WD-WMAM9UT48593-part6 -> ../../sda6 lrwxrwxrwx 1 root root 10 Jul 4 06:48 scsi-SATA_WDC_WD800JD-75M_WD-WMAM9UT48593-part7 -> ../../sda7 /dev/disk/by-label: lrwxrwxrwx 1 root root 10 Jul 4 06:48 1 -> ../../sda6 lrwxrwxrwx 1 root root 10 Jul 4 06:48 boot1 -> ../../sda2 lrwxrwxrwx 1 root root 10 Jul 4 06:48 project -> ../../sda3 lrwxrwxrwx 1 root root 10 Jul 4 06:48 SWAP-sda7 -> ../../sda7 /dev/disk/by-path: lrwxrwxrwx 1 root root 9 Jul 4 06:48 pci-0000:00:1f.2-scsi-0:0:0:0 -> ../../sda lrwxrwxrwx 1 root root 10 Jul 4 06:48 pci-0000:00:1f.2-scsi-0:0:0:0-part1 -> ../../sda1 lrwxrwxrwx 1 root root 10 Jul 4 06:48 pci-0000:00:1f.2-scsi-0:0:0:0-part2 -> ../../sda2 lrwxrwxrwx 1 root root 10 Jul 4 06:48 pci-0000:00:1f.2-scsi-0:0:0:0-part3 -> ../../sda3 lrwxrwxrwx 1 root root 10 Jul 4 06:48 pci-0000:00:1f.2-scsi-0:0:0:0-part4 -> ../../sda4 lrwxrwxrwx 1 root root 10 Jul 4 06:48 pci-0000:00:1f.2-scsi-0:0:0:0-part5 -> ../../sda5 lrwxrwxrwx 1 root root 10 Jul 4 06:48 pci-0000:00:1f.2-scsi-0:0:0:0-part6 -> ../../sda6 lrwxrwxrwx 1 root root 10 Jul 4 06:48 pci-0000:00:1f.2-scsi-0:0:0:0-part7 -> ../../sda7 /dev/disk/by-uuid: lrwxrwxrwx 1 root root 10 Jul 4 06:48 18283DC6283DA422 -> ../../sda1 lrwxrwxrwx 1 root root 10 Jul 4 06:48 25a4068c-e84a-44ac-85e6-461b064d08cd -> ../../sda6 lrwxrwxrwx 1 root root 10 Jul 4 06:48 3ea7cf15-511b-407a-a56b-c6bfa046fd9f -> ../../sda5 lrwxrwxrwx 1 root root 10 Jul 4 06:48 8878a0a4-604e-4ddf-b62c-637c4fa84d3f -> ../../sda2 lrwxrwxrwx 1 root root 10 Jul 4 06:48 e50bcd6d-61ea-4b05-81a8-3cbe17ad6674 -> ../../sda3 永久性设备命名为识别硬件设备省去了很多麻烦。 /dev中的巨多设备节点 在设备节点的静态创建模型中,没有办法可以分辨出硬件设备是否真的存在于系统之中。因此,所有这会儿被Linux认识的设备都会创建好设备节点。/dev中巨大数目的设备节点使得鉴别一个系统中存在的设备变得困难。 主/次设备号对不够了 近年来需要包含的静态设备节点的数目增加得太多,以至于以前所使用的8位模式用来处理所有的设备变得不够用了。因此主/次设备号对开始用光了。 字符设备和块设备拥有固定分配的主/次设备号对。分配主/次设备号对的官方机构是Linux Assigned Name and Number Authority。但是,一台机器不会使用所有可能的设备,因此一个系统中肯定有未使用的主/次设备号。在这种情况下,那台机器的内核就可以借用那些未使用设备的主/次设备号,给其他一些需要的设备。 有时候这样会产生问题。因为用户空间操作设备的应用程序未必会感知设备号的变化。对于用户空间的程序,LANANA分配的设备号非常重要。因此,主/次设备号的改变必须通知这些应用程序。这被称为主/次设备号的动态分配,Udev完成了这项任务。 Udev的目标
Udev是2.6内核中的缺省设备管理器。几乎所有的现代Linux发行版都会将Udev作为默认安装的一部分。你也可以从http://www.kernel.org/pub/linux/utils/kernel/hotplug/这里获取Udev。最新版本的Udev需要2.6.25的内核,并且开启了sysfs, procfs, signalfd, inotify, Unix domain sockets, networking和 hotplug的支持。 CONFIG_HOTPLUG=y CONFIG_UEVENT_HELPER_PATH=”" CONFIG_NET=y CONFIG_UNIX=y CONFIG_SYSFS=y CONFIG_SYSFS_DEPRECATED*=n CONFIG_PROC_FS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y CONFIG_INOTIFY=y CONFIG_SIGNALFD=y 作为一个更加可靠的操作,内核必须不使用CONFIG_SYSFS_DEPRECATED*选项。 Udev依赖于proc和sys文件系统,并且它们必须挂载在/proc和/sys。 Udev的工作 Udev守护进程监听一个netlink套接字,这个套接字是内核用来与用户空间的应用程序进行通信的。当一个设备被加入或移出系统时,内核可能会 通过这个netlink套接字发送一大堆的数据。Udev守护进程截取所有这些数据并完成剩下的工作,也就是创建设备节点,加载模块,等等。 内核设备事件管理
让我们检查一个Linux设备驱动加载的例子: 我使用一个C程序来从netlink套接字收集数据,并且使用它们来创建设备节点以及加载模块。 [root@arch ~]# ./a.outadd@/devices/pci0000:00/0000:00:02.1/u***1/1-4 ACTION=add DEVPATH=/devices/pci0000:00/0000:00:02.1/u***1/1-4 SUBSYSTEM=u*** MAJOR=189 MINOR=1 DEVTYPE=u***_device DEVICE=/proc/bus/u***/001/002 PRODUCT=1058/1010/105 TYPE=0/0/0 BUSNUM=001 DEVNUM=002 SEQNUM=1163 add@/devices/pci0000:00/0000:00:02.1/u***1/1-4/1-4:1.0 ACTION=add DEVPATH=/devices/pci0000:00/0000:00:02.1/u***1/1-4/1-4:1.0 SUBSYSTEM=u*** DEVTYPE=u***_interface DEVICE=/proc/bus/u***/001/002 PRODUCT=1058/1010/105 ………………………………………… 你可以看到它提供了很多关于这个设备的信息。这其中包括了用来告诉Udev加载某个特定模块的modalias变量。 modalias数据看起来像这样: MODALIAS=pci:v000010ECd00008169sv00001385sd0000311Abc02sc00i00The modalias data contains all the information required to find the corresponding device driver : pci :- 这是一个PCI设备 v :- 设备的厂商ID. 在这里就是 000010EC ( 即 10EC ) d :- 设备的设备ID. 在这里就是 00008169 ( 即 8169 ) sv 和 sd 是厂商和设备的子系统版本号. 依据ID查找一个PCI设备的厂商/产品的最好地方是 http://www.pcidatabase.com. Udev使用modalias数据来从/lib/modules/`uname -r`/modules.alias 查找正确的设备驱动。 $ grep -i 10EC /lib/modules/`uname -r`/modules.alias | grep -i 8169 alias pci:v000010ECd00008129sv*sd*bc*sc*i* r8169 alias pci:v000010ECd00008169sv*sd*bc*sc*i* r8169 你可以看到适合这个设备的模块是r8169. 让我们获取关于这个驱动程序的更多的信息. $ /***in/modinfo r8169filename: /lib/modules/2.6.18-53.el5/kernel/drivers/net/r8169.ko version: 2.2LK-NAPI license: GPL description: RealTek RTL-8169 Gigabit Ethernet driver author: Realtek and the Linux r8169 crew srcversion: D5EDA4980B92CA2CF677B62 alias: pci:v00001737d00001032sv*sd00000024bc*sc*i* alias: pci:v000016ECd00000116sv*sd*bc*sc*i* alias: pci:v00001186d00004300sv*sd*bc*sc*i* alias: pci:v000010ECd00008129sv*sd*bc*sc*i* alias: pci:v000010ECd00008169sv*sd*bc*sc*i* depends: vermagic: 2.6.18-53.el5 SMP mod_unload 686 REGPARM 4KSTACKS gcc-4.1 parm: media:force phy operation. Deprecated by ethtool (8). (array of int) parm: rx_copybreak:Copy breakpoint for copy-only-tiny-frames (int) parm: use_dac:Enable PCI DAC. Unsafe on 32 bit PCI slot. (int) parm: debug:Debug verbosity level (0=none, …, 16=all) (int) 注意查看从"depends”开始的那些行. 它描述了r8169这个模块所依赖的其他一些模块。因此Udev也会加载这些模块。 规则处理和设备节点创建 如前所述,Udev会为内核中每个设备状态的改变解析/etc/udev/rules.d/ 中的规则。Udev规则可以用于在用户空间操作设备节点的名字/权限/符号链接。 让我们看一些示例规则,有利于帮助你更好地理解Udev规则。 内核通过netlink提供的数据可以被Udev用来创建设备节点。这些数据包括主/次设备号对和另外一些设备相关的数据,比如设备/厂商id,设备序列号等。Udev规则可以匹配所有的这些数据,并且用来改变设备节点的名字,创建符号链接,或者注册网络连接。 下面这个例子展示了怎样书写Udev规则来重命名系统中的一个网络设备。 我们需要得到一些用于创建规则的设备信息。 # udevadm info -a -p /sys/class/net/eth0/llooking at device '/devices/pci0000:00/0000:00:04.0/0000:01:06.0/net/eth0': KERNEL==”eth0″ SUBSYSTEM==”net” DRIVER==”" ATTR{addr_len}==”6″ ATTR{dev_id}==”0×0″ ATTR{ifalias}==”" ATTR{iflink}==”3″ ATTR{ifindex}==”3″ ATTR{features}==”0×829″ ATTR{type}==”1″ ATTR{link_mode}==”0″ ATTR{address}==”00:80:48:62:2a:33″ ATTR{broadcast}==”ff:ff:ff:ff:ff:ff” ATTR{carrier}==”1″ ATTR{dormant}==”0″ ATTR{operstate}==”unknown” ATTR{mtu}==”1500″ ATTR{flags}==”0×1003″ ATTR{tx_queue_len}==”1000″ looking at parent device ‘/devices/pci0000:00/0000:00:04.0/0000:01:06.0′: KERNELS==”0000:01:06.0″ SUBSYSTEMS==”pci” DRIVERS==”8139too” ATTRS{vendor}==”0×10ec” ATTRS{device}==”0×8139″ ATTRS{subsystem_vendor}==”0×10ec” ATTRS{subsystem_device}==”0×8139″ ATTRS{class}==”0×020000″ ATTRS{irq}==”19″ ATTRS{local_cpus}==”ff” ATTRS{local_cpulist}==”0-7″ ATTRS{modalias}==”pci:v000010ECd00008139sv000010ECsd00008139bc02sc00i00″ ATTRS{enable}==”1″ ATTRS{broken_parity_status}==”0″ ATTRS{msi_bus}==”" looking at parent device ‘/devices/pci0000:00/0000:00:04.0′: KERNELS==”0000:00:04.0″ SUBSYSTEMS==”pci” DRIVERS==”" ATTRS{vendor}==”0×10de” ATTRS{device}==”0×03f3″ ATTRS{subsystem_vendor}==”0×0000″ ATTRS{subsystem_device}==”0×0000″ ATTRS{class}==”0×060401″ ATTRS{irq}==”0″ ATTRS{local_cpus}==”ff” ATTRS{local_cpulist}==”0-7″ ATTRS{modalias}==”pci:v000010DEd000003F3sv00000000sd00000000bc06sc04i01″ ATTRS{enable}==”1″ ATTRS{broken_parity_status}==”0″ ATTRS{msi_bus}==”1″ looking at parent device ‘/devices/pci0000:00′: KERNELS==”pci0000:00″ SUBSYSTEMS==”" DRIVERS==”" 你可以发现Udev拥有大量关于这个网络设备的信息。让我们深入检查一下: KERNEL=="eth0" :- 该设备的内核名字是eth0DRIVERS==”8139too” :- 加载的驱动程序是8139too ATTR{address}==”00:80:48:62:2a:33″ :- 该设备的硬件地址 ATTRS{vendor}==”0×10ec” :- 厂商 id ATTRS{device}==”0×8139″ :- 设备 id 让我们创建一个规则来将这个网络设备重命名为eth1 (这个名字将是永久性的并且重启系统以后也不会复原). >[root@arch ~]# cat /etc/udev/rules.d/70-persistent-net.rulesSUBSYSTEM==”net”, ACTION==”add”, DRIVERS==”?*”, ATTR{address}==”00:80:48:62:2a:33″, ATTR{type}==”1″, KERNEL==”eth*”, NAME=”eth1″ 这个规则就将这个设备重命名成了eth1. 用这种方式我们可以很容易地管理系统中的网络设备或者其他设备节点。 Udev 实用工具 Udev提供了一些用户空间的实用程序,用于管理系统中的设备和设备节点。在所有最近的Linux发行版中都可以找到的这样的一个命令就是'udevadm',udevadm这个命令在功能上可以实现上面提到的各个命令完成的所有任务。 这个工具可以用来在正在运行的系统里面重新生成设备节点,如下所示: [root@arch ~]# ls -l /dev/ | wc -l150 [root@arch ~]# rm -rf /dev/* rm: cannot remove `/dev/pts/0′: Operation not permitted rm: cannot remove directory `/dev/shm’: Device or resource busy [root@arch ~]# ls -l /dev/ | wc -l 4 [root@arch ~]# udevadm trigger [root@arch ~]# ls -l /dev/ | wc -l 150 有更多的其他有用的操作都可以通过udevadm命令完成。你可以通过udevadm的man手册页来获取更多的信息。 Udev的未来会怎样 ? 预测Linux子系统的将来是不可能的。Linux正在快速开发的过程当中,因此预测Linux的内核的未来是不明智的。DEVfs曾经被当作静态设备节点的一个解决方案被引入,但是在经历一小段时间之后就消失了。而Udev则被证明是现代Linux内核中一个成功的设备管理器,并且有希望在未来的 发布中成为一个更加稳定,多功能的设备管理系统。 关于作者 Unnikrishnan A, 是一个Linux服务器管理的专家。 Linux让他着迷是因为这是一个主要的开源开创性平台,能够让任何人深入学习。他还经常赞赏一个事实,就是Linux有庞大的社区驱动的支持,可以有更多的机会来展示新思想和解决办法。除了Linux,Unnikrishnan还喜爱电子学和天文学。在他的空余时间,Unnikrishnan喜欢在网络设计的世界中探索。本文最初来源于t Bobcares. 原文链接:http://www.linux.com/news/hardware/peripherals/180950-udev
|
|
相关推荐
|
|
udev 是Linux kernel 2.6系列的设备管理器。它主要的功能是管理/dev目录底下的设备节点。它同时也是用来接替devfs及热插拔的功能,这意味着它要在添加/删除硬件时处理/dev目录以及所有用户空间的行为,包括加载固件时Linux 2.6.13内核。udev的最新版本依赖于升级后的的uevent接口的最新版本。使用新版本udev的系统不能在2.6.13以下版本启动,除非使用noudev参数来禁用udev并使用传统的/dev来进行设备读取。
|
|
|
|
|
|
Linux 传统上使用静态设备创建方法,因此大量设备节点在 /dev 下创建(有时上千个),而不管相应的硬件设备是否真正存在。通常这由一个MAKEDEV脚本实现,这个脚本包含了许多通过世界上(有幽默意味,注)每一个可能存在的设备相关的主设备号和次设备号对mknod程序的调用。采用udev的方法,只有被内核检测到的设备才会获取为它们创建的设备节点。因为这些设备节点在每次系统启动时被创建,他们会被贮存在ramfs(一个内存中的文件系统,不占用任何磁盘空间).设备节点不需要大量磁盘空间,因此它使用的内存可以忽略。
|
|
|
|
|
|
在kernel2.4的版本中,一种新文件系统称作devfs被添加了进去。尽管它出现在内核源码中,然而内核开发者对这种动态创建设备的方法从未受到压倒性的支持;
devfs方法主要方式:设备检测,创建,命名。设备节点命名,可能是最重要的。人们普遍认为设备名允许是可配置的,然后设备命名策略应该取决于一个系统管理员,而不是devfs的开发者。文件系统同时还忍受着一个紊乱情况,为它的设计所固有,且不能被修复,因无实质的修改现由于缺乏维护已被丢弃内核。 在2.6版本的内核中,出现了一种叫sysfs的新虚拟文件系统。该文件系统将其搬到用户空间进程。有了这种用户空间可见表示法,使文件系统变得更加现实、且具有用户可更换性。 |
|
|
|
|
|
sysfs怎样知道设备出现在系统应该使用什么设备号??对于被编进内核的驱动,当被内核监测到时,直接注册目标与sysfs。使用模块方式编译的,当模块被负荷时,如前。一旦sysfs文件系统被安装(在/sys),其内置的驱动程序注册sysfs的数据提供给用户空间进程和设备节点创建udev。
udev初始化脚本创建这些设备节点当Linux启动时;这个脚本开始注册/***in/udev/ 作为一个hotplug event管理者。hotplug event不应该发生在这个过程中,然而udev注册以防万一他们发生。然后udevstart程序走通过/sys文件系统和创建符合描述的设备在/发展例如:/系统/班/电传/风投/ dev /包括字符串“7:0”这个字符串被。udevstart使用来创建/ dev 例如,主设备号7和次设备号0。每一个udevstart创建的设备的权限设置来自/etc/udev.d/permission.d/目录。这些编号(有限的)基本相似LFS启动脚本。如果找不到创建的设备权限文件,默认权限600,所有者root:root 目录下创建的节点根据 /etc/udev/rules.d/目录下的文件来配置。 |
|
|
|
|
|
当一个新设备连 接被kernel监测到,kernel会产生一个hotplug event 并查找/proc/sys/kernel/hotplug去找出管理设备连接的用户空间程序。udev初始化脚本注册udev as this hander.当hotplug events发生时,kernel通知udev 去检测/sys 文件系统附属于这个新设备的信息并create 它的/dev/入口。
这带给我们一个问题:exists with udev,and likewise with devfs before it.?就像先有鸡还是先有蛋。大部分linux distrubtions 管 理加载模块通过/etc/modules.conf.access to 设备节点引起相应的kernel模块来加载。然而对于udev,这种方法不能正常工作,因为模块没有加载时,设备节点不存在。为了解决这个问题,模块脚本 加到了lfs-bootscripts包中,和/etc/sysconfig/modules在一起。通过添加module names到module file中,这些模块在计算机启动时被加载。这样,udev就可以去检测设备并创建相应的设备节点。 |
|
|
|
|
|
当 你插入一个设备,比如u*** mp3 player,内核辨认出设备连接同时产生一个热插拔事件。如果驱动已经loaded(不管是编进kernel还是通过s05modules bootscript加载),udev将被调用来创建相关的设备节点,根据sysfs data in /sys.如果刚插入的设备驱动以模块形式然而并未加载,那么刚attach to system 的设备只会引起kernel总线驱动产生一个热插拔事件通知用户空间一个新设备的连接and它不attached to a driver.结果,什么都没有发生,device依然不能使用。
如果建立一个system,that具有大量的以模块形式编译的驱动,使用s05modules并不实际。the hotplug package会显得非常有价值。当此包安装后,它会响应前述的kernel总线驱动hotplug事件。此包将加载相应的模块并为设备创建节点。 |
|
|
|
|
|
自动创建设备节点时常遇到的一些问题
1)A kernel driver may not exports its data to sysfs 当 使用第三方驱动(在kernel source tree 之外)时常遇到这种问题。 这些驱动end up时没有创建设备节点。使用/etc/sysconfig/creatfiles 配置文件to 人工创建设备。参考devices.txt文件(在kernel文档中)或者驱动文档来找出正确的major/minor设备号。 2)无硬件设备 is required.这种很常见with the advanced linux sound architecture(ALSA) project's open sound system(oss) compatibility 模块.这种形式的驱动可以使用以下下面两种方法来管理: *将module names 加到 /etc/sysconfig/modules; * 使用"install"line 在/etc/modprobe.conf中。This tells the modprobe command "when loading this module,also load this other module,at the same time."例如 install snd-pcm modprobe -i snd-pcm;modprobe snd-pcm-oss;true 当系统中有加载snd-pcm驱动的请求时,这会使系统加载both snd-pcm and snd-pcm-oss modules. |
|
|
|
|
|
如果你使用Linux比较长时间了,那你就知道,在对待设备文件这块,Linux改变了几次策略。在Linux早期,设备文件仅仅是是一些带有适当的属性集的普通文件,它由mknod命令创建,文件存放在/dev目录下。后来,采用了devfs, 一个基于内核的动态设备文件系统,他首次出现在2.3.46内核中。Mandrake,Gentoo等Linux分发版本采用了这种方式。devfs创建 的设备文件是动态的。但是devfs有一些严重的限制,从2.6.13版本后移走了。目前取代他的就是udev……一个用户空间程序。
|
|
|
|
|
|
目前很多的Linux分发版本采纳了udev的方式,因为它在Linux设备访问,特别是那些对设备有极端需求的站点(比如需要控制上千个硬盘)和热插拔设备(比如USB摄像头和MP3播放器)上解决了几个问题。下面我我们来看看如何管理udev设备。
实际上,对于那些为磁盘,终端设备等准备的标准配置文件而言,你不需要修改什么。但是,你需要了解udev配置来使用新的或者外来设备,如果不修改配置, 这些设备可能无法访问,或者说Linux可能会采用不恰当的名字,属组或权限来创建这些设备文件。你可能也想知道如何修改RS-232串口,音频设备等文件的属组或者权限。这点在实际的Linux实施中是会遇到的。 |
|
|
|
|
|
为什么使用udev ?
在此之前的设备文件管理方法(静态文件和devfs)有几个缺点: *不确定的设备映射。特别是那些动态设备,比如USB设备,设备文件到实际设备的映射并不可靠和确定。举一个例子:如果你有两个USB打印机。一个可能称 为/dev/u***/lp0,另外一个便是/dev/u***/lp1。但是到底哪个是哪个并不清楚,lp0,lp1和实际的设备没有一一对应的关系,因为 他可能因为发现设备的顺序,打印机本身关闭等原因而导致这种映射并不确定。理想的方式应该是:两个打印机应该采用基于他们的序列号或者其他标识信息的唯一 设备文件来映射。但是静态文件和devfs都无法做到这点。 *没有足够的主/辅设备号。我们知道,每一个设备文件是有两个8位的数字:一个是主设备号 ,另外一个是辅设备号来分配的。这两个8位的数字加上设备类型(块设备或者字符设备)来唯一标识一个设备。不幸的是,关联这些身边的的数字并不足够。 */dev目录下文件太多。一个系统采用静态设备文件关联的方式,那么这个目录下的文件必然是足够多。而同时你又不知道在你的系统上到底有那些设备文件是激活的。 *命名不够灵活。尽管devfs解决了以前的一些问题,但是它自身又带来了一些问题。其中一个就是命名不够灵活;你别想非常简单的就能修改设备文件的名字。缺省的devfs命令机制本身也很奇怪,他需要修改大量的配置文件和程序。 *内核内存使用,devfs特有的另外一个问题是,作为内核驱动模块,devfs需要消耗大量的内存,特别当系统上有大量的设备时(比如上面我们提到的系统一个上有好几千磁盘时) |
|
|
|
|
|
udev的目标是想解决上面提到的这些问题,他通采用用户空间(user-space)工具来管理/dev/目录树,他和文件系统分开。知道如何改变缺省配置能让你之大如何定制自己的系统,比如创建设备字符连接,改变设备文件属组,权限等。
|
|
|
|
|
|
udev配置文件
主要的udev配置文件是/etc/udev/udev.conf。这个文件通常很短,他可能只是包含几行#开头的注释,然后有几行选项: udev_root=“/dev/” udev_rules=“/etc/udev/rules.d/” udev_log=“err“ 上面的第二行非常重要,因为他表示udev规则存储的目录,这个目录存储的是以.rules结束的文件。每一个文件处理一系列规则来帮助udev分配名字给设备文件以保证能被内核识别。 你的/etc/udev/rules.d下面可能有好几个udev规则文件,这些文件一部分是udev包安装的,另外一部分则是可能是别的硬件或者软件包 生成的。比如在Fedora Core 5系统上,sane-backends包就会安装60-libsane.rules文件,另外initscripts包会安装60-net.rules文 件。这些规则文件的文件名通常是两个数字开头,它表示系统应用该规则的顺序。 规则文件里的规则有一系列的键/值对组成,键/值对之间用逗号(,)分割。每一个键或者是用户匹配键,或者是一个赋值键。匹配键确定规则是否被应用,而赋 值键表示分配某值给该键。这些值将影响udev创建的设备文件。赋值键可以处理一个多值列表。匹配键和赋值键操作符解释见下表: |
|
|
|
|
|
udev 键/值对操作符
操作符 匹配或赋值 解释 ---------------------------------------- == 匹配 相等比较 != 匹配 不等比较 = 赋值 分配一个特定的值给该键,他可以覆盖之前的赋值。 += 赋值 追加特定的值给已经存在的键 := 赋值 分配一个特定的值给该键,后面的规则不可能覆盖它。 这有点类似我们常见的编程语言,比如C语言。只是这里的键一次可以处理多个值。有一些键在udev规则文件里经常出现,这些键的值可以使用通配符(*,?,甚至范围,比如[0-9]), |
|
|
|
|
|
常用udev键
键 含义 ACTION 一个时间活动的名字,比如add,当设备增加的时候 KERNEL 在内核里看到的设备名字,比如sd*表示任意SCSI磁盘设备 DEVPATH 内核设备录进,比如/devices/* SUBSYSTEM 子系统名字,比如sound,net BUS 总线的名字,比如IDE,USB DRIVER 设备驱动的名字,比如ide-cdrom ID 独立于内核名字的设备名字 SYSFS{ value} sysfs属性值,他可以表示任意 ENV{ key} 环境变量,可以表示任意 PROGRAM 可执行的外部程序,如果程序返回0值,该键则认为为真(true) RESULT 上一个PROGRAM调用返回的标准输出。 NAME 根据这个规则创建的设备文件的文件名。注意:仅仅第一行的NAME描述是有效的,后面的均忽略。 如果你想使用使用两个以上的名字来访问一个设备的话,可以考虑SYMLINK键。 SYMLINK 根据规则创建的字符连接名 OWNER 设备文件的属组 GROUP 设备文件所在的组。 MODE 设备文件的权限,采用8进制 RUN 为设备而执行的程序列表 LABEL 在配置文件里为内部控制而采用的名字标签(下下面的GOTO服务) GOTO 跳到匹配的规则(通过LABEL来标识),有点类似程序语言中的GOTO IMPORT{ type} 导入一个文件或者一个程序执行后而生成的规则集到当前文件 WAIT_FOR_SYSFS 等待一个特定的设备文件的创建。主要是用作时序和依赖问题。 PTIONS 特定的选项: last_rule 对这类设备终端规则执行; ignore_device 忽略当前规则; ignore_remove 忽略接下来的并移走请求。all_partitions 为所有的磁盘分区创建设备文件。 |
|
|
|
|
|
修改你的udev配置
在修改udev配置之前,我们一定要仔细,通常的考虑是:你最好不要修改系统预置的那些规则,特别不要指定影响非常广泛的配置,比如上面例子中的第一行。不正确的配置可能会导致严重的系统问题或者系统根本就无法这个正确的访问设备。 而我们正确的做法应该是在/etc/udev/rules.d/下创建一个信的规则文件。确定你给出的文件的后缀是rules文件名给出的数字序列应该比 标准配置文件高。比如,你可以创建一个名为99-my-udev.rules的规则文件。在你的规则文件中,你可以指定任何你想修改的配置,比如,假设你 修改修改floppy设备的所在组,还准备创建一个信的符号连接/dev/floppy,那你可以这么写: KERNEL==”fd[0-9]*“, GROUP=“users“, SYMLINK+=“floppy“ 有些发行版本,比如Fedora,采用了外部脚本来修改某些特定设备的属组,组关系和权限。因此上面的改动可能并不见得生效。如果你遇到了这个问题,你就需要跟踪和修改这个脚本来达到你的目的。或者你可以修改PROGRAM或RUN键的值来做到这点。 某些规则的修改可能需要更深的挖掘。比如,你可能想在一个设备上使用sysfs信息来唯一标识一个设备。这些信息最好通过udevinfo命令来获取。 $ udevinfo –a –p $(udevinfo –q path –n /dev/hda)上面的命令两次使用udevinfo:一次是返回sysfs设备路径(他通常和我们看到的Linux设备文件名所在路径--/dev/hda--不同);第 二次才是查询这个设备路径,结果将是非常常的syfs信息汇总。你可以找到最够的信息来唯一标志你的设备,你可以采用适当的替换udev配置文件中的 SYSFS选项。 |
|
|
|
|
|
只有小组成员才能发言,加入小组>>
「含关键代码」基于AM3352/AM3354/AM3359的Linux开发案例分享
4892 浏览 0 评论
87409 浏览 0 评论
【高手问答】如何做到精通linux技术?资深工程师带你突破难点
4723 浏览 2 评论
3617 浏览 2 评论
解读Linux :先从创建一个文件夹用来存放jdk压缩文件开始
2481 浏览 0 评论
1997浏览 3评论
1283浏览 1评论
求解:aarch64交叉编译工具已经安装成功,环境变量已经配置,怎么将系统架构切换为ARM的架构
1341浏览 0评论
电脑和虚拟机可以互ping,电脑和开发板也可以互ping,但是虚拟机和开发板ping不通是什么原因
1233浏览 0评论
1173浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 16:46 , Processed in 1.652260 second(s), Total 106, Slave 89 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号