转:http://www.360doc.com/content/11/0415/21/1317564_109922388.shtml
udev 是Linux kernel 2.6系列的设备管理器。它主要的功能是管理/dev目录底下的设备节点。它同时也是用来接替devfs及hotplug的功能,这意味着它要在添加/删 除硬件时处理/dev目录以及所有用户空间的行为,包括加载firmware时。udev的最新版本依赖于升级后的Linux kernel 2.6.13的uevent接口的最新版本。使用新版本udev的系统不能在2.6.13以下版本启动,除非使用noudev参数来禁用udev并使用传 统的/dev来进行设备读取。
简介
Linux 传统上使用静态设备创建方法,因此大量设备节点在 /dev 下创建(有时上千个),而不管相应的硬件设备是否真正存在。通常这由一个MAKEDEV脚本实现,这个脚本包含了许多通过世界上(有幽默意味,注)每一个 可能存在的设备相关的主设备号和次设备号对mknod程序的调用。采用udev的方法,只有被内核检测到的设备才会获取为它们创建的设备节点。因为这些设 备节点在每次系统启动时被创建,他们会被贮存在ramfs(一个内存中的文件系统,不占用任何磁盘空间).设备节点不需要大量磁盘空间,因此它使用的内存 可以忽略。
1:history
在2.4版本的kernel中,一种新文件系统称作devfs被添加了进去。尽管它在kernel源码中出现,然而这种动态创建设备的方法从未收到压倒性的支持from core kernel开发者; devfs 的方法主要问题是 the way:设备检测,创建,命名。设备节点命名,可能是最critical的.It is generally accepted that 设备名允许是可配置的,then设备命名策略应该up to一个系统管理员,not 被欺骗by 特殊的开发者。devfs文件系统同时还忍受着一个紊乱情况,为它的design所固有,且不能被fix,若无实质的修改to kernel.现由于缺乏维护已被丢弃. 在2.6版本的kernel中,出现了一种叫sysfs的新虚拟文件系统。sysfs的 任务是export系统架构 to 用户空间进程。有了这种用户空间visible表示法,the possiblity of seeing a userspace replacement for devfs 变得更加现实。
2:udev 执行
sysfs怎样知道设备出现 在系统?应该使用什么设备号?对于被编进kernel的driver,当被kernel监测到时,直接注册目标with sysfs。使用模块方式编译的,当模块被load时,如前。once sysfs文件系统被mounted (on /sys),the data which the built-in drivers registered with sysfs are available to userspace process and to udev for device node creation. udev初始化脚本创建这些 设备节点当linux boot时;这个脚本starts with 注册/sbin/udev/ 作为一个 hotplug事件管理者。热插拔事件不应该发生在这个过程中,然而udev is registered just in case they do occur.然后udevstart program walk through the /sys filesystem and 创建符合描述的设备在/dev。例如:/sys/class/tty/vcs/dev/包括string "7:0".这个字符串被udevstart使用来创建/dev/vcs,主设备号7and此设备号0。每一个udevstart创建的设备的权限设置来 自/etc/udev.d/permission.d/目录。这些numbered(有限的) 基本相似LFS bootscripts.如果找不到创建的设备权限文件,默认perissions to 600 and ownership to root:root./dev目录下创建的节点根据 /etc/udev/rules.d/目录下的文件来configured. 当一个新设备连 接被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就可以去检测设备并创建相应的设备节点。
3:处理可热插拔/动态设备
当 你插入一个设备,比如usb 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事件。此包将加载相应的模块并为设备创建节点。
4:创建设备的问题
自动创建设备节点时常遇到的一些问题 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.
相关问答
问: udev是什么? 它的目的何在? 答: 看看那篇 OLS 2003 上的有关 udev 的文章吧,可以在 docs 目录里找到,也能在这 里找到:OLS 2003 上还有一个关于 udev 的幻灯片。 问: udev 和 devfs 是什么关系 答: udev 完全在用户态 (userspace) 工作,利用设备加入或移除时内核所发送的 hotplug 事件 (event) 来工作。关于设备的详细信息是由内核输出 (export) 到位 于 /sys 的 sysfs 文件系统的。所有的设备命名策略、权限控制和事件处理都是在 用户态下完成的。与此相反,devfs 是作为内核的一部分工作的。 问: 如果 udev 不能完成所有 devfs 的工作的话,为什么把 devfs 标记为 OBSOLETE/removed? 答: 引用 Al Viro (Linux VFS 内核维护者): - devfs 所做的工作被确信可以在用户态来完成。 - devfs 被加入内核之时,大家寄望它的质量可以迎头赶上。 - devfs 被发现了一些可修复和无法修复的 bug。 - 对于可修复的 bug,几个月前就已经被修复了,其维护者认为一切良好。 - 对于后者,同样是相当常一段时间以来没有改观了。 - devfs 的维护者和作者对它感到失望并且已经停止了对代码的维护工作。 问: 但是当一个并不存在的 /dev 节点被打开的时候,udev 并不能如 devfs 一样自动加 载驱动程序。 答: 的确如此,但 Linux 的设计是在设备被发现的时候加载模块,而不是当它被访问的时 候。 问: 不过等等,我确实希望 udev 可以在不存在的节点被打开的时候自动加载驱动。这是 我使用 devfs 的唯一原因了。给 udev 增加这个功能吧。 答: 不,udev 是用来管理 /dev 的,不是用来加载内核驱动的。 问: 嗨,求你们了。这不难做到的。 答: 这么个功能对于一个配置正确的计算机是多余的。系统中所有的设备都应该产生 hotplug 事件、加载恰当的驱动,而 udev 将会注意到这点并且为它创建对应的 设备节点。如果你不想让所有的设备驱动停留在内存之中,应该使用其它东西来 管理你的模块 (如脚本, modules.conf, 等等) 这不是 udev 的工作。 问: 但是我真的喜欢那个功能,还是加上吧 答: devfs 用的方法导致了大量无用的 modprobe 尝试,以此程序探测设备是否存在。 每个试探性探测都新建一个运行 modprobe 的进程,而几乎所有这些都是无用的。 问: 我喜欢 devfs 的设备文件命名方式,udev 可以这样命名么? 答: 可以,udev 可以使用 /dev 的命名策略来创建节点。通过一个配置文件,可以把内 核缺省的名字映射到 devfs 的名字。可以看看 udev 中带的 udev.rules.devfs 文 件。 注意: devfs 的命名方式是不被建议并且不被官方支持的,因为它所用的简单枚举设 备的方式在设备可能被随时加入或删除的情况下确实是一个比较笨的方法。这些编号 代给你的将只有麻烦,而并不能用来确定设备。看看那个永久性磁盘 (persistent disk) 的规则就知道如何在用户态下正确的做这件事,而不是傻傻地列出设备。 问: udev 可以为哪些设备创建节点? 答: 所有在 sysfs 中显示的设备都可以由 udev 来创建节点。如果内核中增加了其它设 备的支持,udev 也就自动地可以为它们工作了。现在所有的块设备都在被支持之列, 大部分的主字符设备也是被支持的。内核开发者们正致力于让所有的字符设备都被支 持。可以到 linux-kernel 邮件列表上寻找补丁或是查看补丁的状态。 问: udev 是否会去掉匿名设备数量的限制? 答: udev 完全工作于用户态。如果内核支持了更多的匿名设备,udev 就会支持。 问: udev 是否会支持符号链接? 答: udev 现在就支持符号链接,每个设备节点拥有多个符号链接也是被支持的。 问: udev 如何处理 /dev 文件系统? 答: 建议使用一个每次启动系统的时候重新创建的 tmpfs 作为 /dev 的文件系统。不过 实际上 udev 并不关心那种文件系统在被使用。 问: 在 init 运行之前,udev 如何处理设备? 答: udev 可以被放入 initramfs 之中,并在每个设备被发现的时候运行。也可以让 udev 工作在一个真的根分区被加载之后根据 /sys 的内容创建的初始 /dev 目录 之中。 问: 我是否可以利用 udev 在一个 USB 设备被加载的时候自动加载上这个设备? 答: 技术上讲是可以的,但是 udev 不是用于这个工作的。所有的主流发布版 (distro) 都包含了 HAL 用于这个工作,它 也是专门用于监视设备变更的,并且集成进入了桌面软件。 换个角度说,这可以简单的通过 fstab 来实现: /dev/disk/by-label/PENDRIVE /media/PENDRIVE vfat user,noauto 0 0 这样,用户可以用如下命令来访问设备: $mount /media/PENDRIVE 同样不需要管理员权限,但却拥有了设备的全部访问权限。使用永久性磁盘链接 (label, uuid) 将可以指定同一设备,无论其实际上的内核名字是什么。 问: 有什么我需要注意的安全问题么? 答: 当使用动态设备编号的时候,一个给定的主/从设备号可能在不同时间对应不同的设 备,如果一个用户拥有对这个节点的访问权限,并且可以创建一个到这个节点的硬链 接,他就可以如此得到一个这个设备节点的拷贝。当设备被移除之后,udev 删除了 设备节点,但硬链接依然存在。如果这个设备节点之后被重新使用不同的访问权限被 创建的时候,其硬链接仍然可以使用先前的访问权限来访问。 (同样的问题也存在在使用 PAM 改变访问权限的 login 上。) 简单的解决方案就是通过把 /dev 放在 tmpfs 这样的单独的文件系统之上来防止建 立硬链接。[1]