udev和devfs的区别

devfs(设备文件系统)是由Linux2.4内核引入的,它的出现主要使得设备驱动程序能够自主管理自己的设备文件。具体来说,devfs具有如下优点:

可以通过程序在设备初始化时在/dev目录下创建设备文件,卸载设备时将它删除。

设备驱动程序可以指定设备名、所有者和权限位,用户空间程序仍可以修改所有者和权限位。

不再需要为设备驱动程序分配主设备号以及处理次设备号,在程序中可以直接给register_chrdev()传递0主设备号以动态获得可用的主设备号,并在devfs_register()中指定次设备号。

创建设备目录、设备文件以及删除函数如下:

devfs_handle_t devfs_mk_dir(devfs_handle_t dir, const char *name, void *info);
devfs_handle_t devfs_register(devfs_handle_t dir, const char *name, unsigned int flags, unsigned int major, unsigned int minor, umode_t mode
void devfs_unregister(devfs_handle_t de);

使用devfs的例子如下:

static devfs_handle_t devfs_handle;
static int __init xxx_init(void)
{
int ret;
int I;
/*在内核中注册设备*/
ret = register_chrdev(XXX_major, DEVICE_NAME, &xxx_fops);
if( ret < 0)
{
   printk(DEVICE_NAME “ can’t register major number\n”);
   return ret;
}
/*创建设备文件*/
devfs_handle = devfs_register(NULL, DEVICE_NAME, DEVFS_FL_DEFAULT, xxx_MAJOR, 0, S_IFCHR | S_IRUSR | S_IWUSR, &xxx_fops, NULL);
…
printk(DEVICE_NAME “ initialized\n”);
return 0;
}
static void __exit xxx_exit(void)
{
devfs_unregister(devfs_handle);/*撤消设备文件*/
unregister_chrdev(XXX_MAJOR, DEVICE_NAME);/*注销设备*/
}
 
module_init(xxx_init);
module_exit(xxx_exit);

在最新的Linux 2.6的内核中, devfs已经被抛弃,udev取代了它。udev取代devfs的几点原因如下:

  • devfs所做的工作被确信可以在用户态来完成
  • 一些bug相当长的时间内未被修复
  • devfs的维护者和作者停止了对代码的维护工作。
  • udev完全在用户态工作,利用设备加入或移除内核所发送的热插拔事件来工作。在热插拔时,设备的详细信息会由内核输入到位于/sys的sysfs文件系统。udev的设备名策略、权限控制和事件处理都是在用户态下完成的,它利用sysfs中的信息来进行创建设备文件节点工作。
  • 由于udev根据系统中硬件设备的状态动态更新设备文件、进行设备文件的创建和删除等,因此,在使用udev后,在/dev目录下就只包含系统中真正存在的设备了。
  • devfs与udev的另一个显著区别在于:采用devfs,当一个并不存在的/dev节点被打开的时候,devfs能自动加载对应的驱动,而udev则不能。这是因为udev的设计者认为Linux应该在设备被发现的时候加载驱动模块,而不是当它被访问的时候。udev的设计者认为devfs所提供的打开/dev节点时自动加载驱动的功能对于一个配置正确的计算机是多余的。系统中所有的设备都应该产生热插拔事件并加载恰当的驱动,而udev能注意到这点并且为它创建对应的设备节点。

使用udev的例子如下:

#include <linux/device.h>
…
 
static struct class * xxx_class;
static int __init xxx_init(void)
{
int ret;
int i;
/*在内核中注册设备*/
ret = register_chrdev(XXX_major, DEVICE_NAME, &xxx_fops);
if( ret < 0)
{
   printk(DEVICE_NAME “ can’t register major number\n”);
   return ret;
}
//注册一个类,使mdev可以在"/dev/"目录下面建立设备节点
xxx_class = class_create(THIS_MODULE, DEVICE_NAME);
if(IS_ERR(led_class))
{
   printk("Err: failed in EmbedSky-leds class. \n");
   return -1;
}
//创建一个设备节点,节点名为DEVICE_NAME
class_device_create(xxx_class, NULL, MKDEV(xxx_major, 0), NULL, DEVICE_NAME);
…
printk(DEVICE_NAME “ initialized\n”);
return 0;
}
static void __exit xxx_exit(void)
{
unregister_chrdev(XXX_MAJOR, DEVICE_NAME);/*注销设备*/
class_device_destroy(xxx_class, MKDEV(xx_major, 0));//删掉设备点
class_destroy(xxx_class);               //注销类
}
 
module_init(xxx_init);
module_exit(xxx_exit);

mdev是busybox自带的一个简化版的udev,适合于嵌入式的应用埸合。其具有使用简单的特点。它的作用,就是在系统启动和热插拔或动态加载驱动程序时,自动产生驱动程序所需的节点文件。在以busybox为基础构建嵌入式linux的根文件系统时,使用它是最优的选择。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 我眼中的Linux设备树(四 中断)

    四 中断 中断一般包括中断产生设备和中断处理设备。中断控制器负责处理中断,每一个中断都有对应的中断号及触发条件。中断产生设备可能有多个中断源,有时多个中断源对...

    233333
  • cyclictest 简介

    1. cyclictest 简介以及安装 1.1 cyclictest 简介       cyclictest 是什么? 看名字应该就能大致猜出来它是一种 te...

    233333
  • 高通spi 屏幕 -lk代码分析

    233333
  • Nodes小程序追加评论功能

    话说,最近深圳发生了一次恶性的超市砍人事件,事发点所在的超市竟然位于花叔第一套房子所在的小区!

    花叔
  • ElasticSearch核心概念和文档的CRUD

    Elastic 本质上是一个分布式数据库,允许多台服务器协同工作,每台服务器可以运行多个 Elastic 实例。单个 Elastic 实例称为一个节点(node...

    海向
  • 骚操作!如何完成垃圾分类的图像识别?

    计算机视觉作为人工智能的主流技术领域之一,历经图像分类-->目标定位-->目标检测,最终发展到图像语义分割技术。

    zhisheng
  • 爬虫——scrapy入门

    py3study
  • 『Go 语言学习专栏』-- 第十二期

    谢伟
  • Dubbo负载均衡

    接口LoadBalance 的定义说明,LoadBalance 的实现只是在一个服务提供的调用者列表(invokers)中选出一个调用者即可,默认的负载方式是随...

    用户5325874
  • 记录安装oracle的那些事(一)之oracle我很大

    安装第一遍的时候,遇到了各种问题,一一百度之。最后一个问题,磁盘不足,这个实在没法解决。只好重做系统。其实最好的办法是调整分区大小,但是我之前觉得磁盘剩余的27...

    用户1154259

扫码关注云+社区

领取腾讯云代金券