该答案基于内核2.6。并且讲述字符设备驱动,但是对所有的驱动都是合适的。
终于知道了到底是怎么样把设备文件和驱动程序联系在一起了。
对于每一个已经存在的文件,在其相对应的inode里,都有两个字段
dev_t i_rdev;
struct cdev *i_cdev;
const struct file_operations *i_fop;
i_rdev主要是用来说明当前的设备文件的主设备号,而i_cdev则说明当前的设备文件所对应的设备,而i_fop则对应操作该设备文件的函数(由i_cdev提供)。看cdev的结构:
struct cdev {
struct kobject kobj;
struct module *owner;
const struct file_operations *ops;
struct list_head list;
dev_t dev;
unsigned int count;
};
在该结构中可以看到有两个比较重要的字段
const struct file_operations *ops;
dev_t dev;
在内核看来,如果一个设备文件的i_rdev和一个cdev的dev一样的话,那么对该文件所有的操作(open, read ..)都映射到该设备文件cdev的ops上,该通过inode的i_rdev来寻找cdev的人物就交给了函数chrdev_open上,该函数通过查找和i_rdev相对应的cdev中的dev中的ops 来修改inode的i_fop。在__dentry_open中,这个函数会用inode中的i_fop来修改struct file中的filp字段,这样,当open完成之后,对该文件所有的操作都会映射到cdev上的ops上了,也就是都是他哦难过该驱动来完成了。
|