您的位置:首页 > 其它

设备文件系统(DevFS)

2009-12-10 08:16 134 查看
DevFS设备文件系统是Linux
2.4一个全新的功能,它主要为了有效的管理/dev目录而开发的。我能知道,Unix/Linux中所有的目录都是层次结构,唯独/dev目录是一维结构(没有子目录),这就直接影响着访问的效率及管理的方便与否。另外,/dev目录下的节点并不是按实际需要创建的,因此,该目录下存在大量实际不用的节点,但一般也不能轻易删除。

理想的/dev目录应该是层次的、其规模是可伸缩的


Devfs就是为达到此目的而设计。它在底层改写了用户与设备交互的方式和途径。它会给用户在两方面带来影响。首先,几乎所有的设备名称都做了改变
,例如:“/dev/hda”是用户的硬盘,现在可能被定位于“/dev/ide0/...”。这一修改方案增大了设备可用的名字空间,且容许USB类和类似设备的系统集成。其次,不再需要用户自己创建设备节点。
DevFS的
/dev目录最初是空的,里面特定的文件是在系统启动时、或是加载模块后驱动程序装入时建立的。当模块和驱动程序卸载时,文件就消失了。为保持和旧版本的兼容,可以使用一个用户空间守护程序“devfsd”,以使先前的设备名称能继续使用。目前,Devfs的使用还只是一个实验性选项,由一个编译选项
CONFIG_DEVFS_FS加以选择。

(1) 注册和注销字符设备驱动程序

如前所述,一个新的文件系统要加入系统,必须进行注册
。那么,一个新的驱动程序要加入系统,也必须进行注册。在下一章我们会看到,我们把设备大体分为字符设备和块设备。字符设备的注册和注销调用register_chrdev()和unregister_chrdev()函数。注册了设备驱动程序以后,驱动程序应该调用devfs_register()登记设备的入口点,所谓设备的入口点就是设备所在的路径名;在注销设备驱动程序之前,应该调用
devfs_unregister()取消注册。

devfs_register()和 devfs_unregister() 函数原型为:

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 *ops, void *info);

void devfs_unregister(devfs_handle_t de);

其中devfs_handle_t表示Devfs的句柄(一个结构类型),每个参数的含义如下:

dir : 我们要创建的文件所在的Devfs的句柄。NULL意味着这是Devfs的根,即 /dev。

flags
:设备文件系统的标志,缺省值为DEVFS_FL_DEFAULT。

major : 主设备号,普通文件不需要这一参数。

minor : 次设备号,
普通文件也不需要这一参数

mode : 缺省的文件模式(包括属性和许可权)。

ops : 指向 file_operations 或
block_device_operations结构的指针

info : 任意一个指针,这个指针将被写到file结构的private_data域。

例如,如果我们要注册的设备驱动程序叫做DEVICE_NAME,其主设备号为MAJOR_NR,次设备号为MINOR_NR,缺省的文件操作为
device_fops:则该设备驱动程序的init_module()函数和cleanup_module()函数如下:

int init_module(void)

{

int ret;

if ((ret =
register_chrdev(MAJOR_NR, DEVICE_NAME, &device_fops)) == 0)

return ret;

}

void cleanup_module(void)

{

unregister_chrdev(MAJOR_NR,
DEVICE_NAME);

}

对以上代码进行改写以支持设备文件系统(假定设备入口点的名字为DEVICE_ENTRY)

#include <linux/devfs_fs_kernel.h>

devfs_handle_t devfs_handle;

int init_module(void)

{

int ret;

if ((ret = devfs_register_chrdev(MAJOR_NR, DEVICE_NAME, &device_fops))
== 0)

return ret;

devfs_handle = devfs_register(NULL, DEVICE_ENTRY,
DEVFS_FL_DEFAULT,

MAJOR_NR, MINOR_NR, S_IFCHR | S_IRUGO | S_IWUSR,

&device_fops, NULL);

}

void cleanup_module(void)

{

devfs_unregister_chrdev(MAJOR_NR, DEVICE_NAME);

devfs_unregister(devfs_handle);

}

(2)在Devfs名字空间中创建一个目录



devfs_mk_dir()用来创建一个目录,这个函数返回Devfs的句柄,这个句柄用作devfs_register的参数dir。
例如,为了在“/dev/mydevice”目录下创建一个设备设备入口点,则进行如下操作:

devfs_handle = devfs_mk_dir(NULL, "mydevice", NULL);

devfs_register(devfs_handle, DEVICE_ENTRY, DEVFS_FL_DEFAULT,

MAJOR_NR,
MINOR_NR, S_IFCHR | S_IRUGO | S_IWUSR,

&device_fops, NULL);

(3)注册一系列设备入口点

如果一个设备有几个次设备号,就说明同一个设备驱动程序控制了几个不同的设备,例如主IDE硬盘的主设备号为3,但其每个分区都有一个从设备号,例如
/dev/had2的从设备号为2。在Devfs下,每个从次设备号也有一个目录,例如/dev/ide0/,/dev/ide1/等,也就是说,每个次设备号都有一个设备入口点,于是就可以调用devfs_register_series来创建一系列的设备入口点。设备入口点的名字以printf()函数中format参数的形式来创建。

注册DEVICE_NR设备入口点(次设备号从MINOR_START开始)的操作如下:

devfs_handle =
devfs_mk_dir(NULL, "mydevice", NULL);

devfs_register_series(devfs_handle,
"device%u", max_device, DEVFS_FL_DEFAULT,

MAJOR_NR, MINOR_START, S_IFCHR |
S_IRUGO | S_IWUSR,

&device_fops, NULL);

(4)块设备

注册和注销块设的函数为:

devfs_register_blkdev()

devfs_unregister_blkdev ()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: