Sysfs文件系统与Linux设备模型

http://hi.baidu.com/%F2%DF%F2%D1%B7%C9%B9%FD%BC%D0%D6%F1%CC%D2/blog/item/cc307dfdcafcbd89b801a06b.html

Sysfs文件系统与Linux设备模型

sysfs把连接在系统上的设备和总线组织成为一个分级的目录及文件,它们可以由用户空间存取,向用户空间导出内核数据结构以及它们的属性,这其中就包括设备的主次设备号。新的设备文件系统udev的工作过程就依赖于sysfs文件系统的这些功能特点。udev文件系统在用户空间工作,它可以根据sysfs文件系统导出的信息(设备号等),动态建立和删除设备文件,而不再需要使用mknod来手动建立设备文件,也不必为查找设备号(尤其是驱动中动态申请产生的设备号)而头疼。

kobject内核对象提供了基本的对象管理能力,是linux 2.6设备模型的核心结构,每个在内核中注册的kobject对象都对应于sysfs文件系统的一个目录,这可以通过以下函数调用体现:

kobject_add()-> kobject_add_varg()->kobject_add_internal()->create_dir()->sysfs_create_dir()

(好像已经不存在kobject_register函数了)

sysfs文件系统下的所有目录,其最终的建立过程都是通过注册添加kobject到linux设备层次来实现的,举两个例子:

1、class

class_register-> __class_register-> kset_register-> kobject_add_internal

2、device

device_register-> device_add-> kobject_add

因此,对应于一个设备,在sysfs文件系统下不是一个文件,而是一个目录,目录名字的来源是kobject对象的name域。目录中会有两个文件和若干目录,这两个文件是设备的属性文件。我们可以看看device_add函数的实现,其中有:

912 error = device_create_file(dev, &uevent_attr);

913 if (error)

914 goto attrError;

915

916 if (MAJOR(dev->devt)) {

917 error = device_create_file(dev, &devt_attr);

918 if (error)

919 goto ueventattrError;

其中会在sysfs文件系统对应设备目录下创建两个属性文件(可以看看device_create_file函数的实现,是调用sysfs_create_file),其中有两个参数是两个结构体指针,两个结构体的定义如下:

311 static struct device_attribute uevent_attr =

312 __ATTR(uevent, S_IRUGO | S_IWUSR, show_uevent, store_uevent);

428 static struct device_attribute devt_attr =

429 __ATTR(dev, S_IRUGO, show_dev, NULL);

再看看_ATTR:

48 #define __ATTR(_name,_mode,_show,_store) { \

49 .attr = {.name = __stringify(_name), .mode = _mode }, \

50 .show = _show, \

51 .store = _store, \

52 }

再看看__stringify:

19 #define __stringify_1(x) #x

20 #define __stringify(x) __stringify_1(x)

(真是无底洞呀,到这为止吧!)这两个宏看起来很怪异,有人说这个定义很奇妙,具体奇妙在哪目前我还没体会到,等有机会再补充(留个脚印吧)。简单来说,它们的功能就是x转化为字符串,所以uevent和dev就转化为“uevent”和”dev“了,把它们赋给name,这就是sysfs具体设备目录下的两个文件uevent和dev名字的来源了!

这两个属性文件的内容是怎么等到的呢?sysfs是虚拟文件系统,大家应该知道proc文件系统吧,类似地它们都是在内存中,内容都是动态生成的而不是存储在非易失存储器中。大家应该注意到属性结构体中有两个函数指针show和store,在这里被赋值了

422 static ssize_t show_dev(struct device *dev, struct device_attribute *attr,

423 char *buf)

424 {

425 return print_dev_t(buf, dev->devt);

426 }

所有欺骗中,自欺是最为严重的

Sysfs文件系统与Linux设备模型

相关文章:

你感兴趣的文章:

标签云: