在linux驱动中有一类杂散(misc)设备,其实他本质上还是字符设备,只是内核开发者对字符设备驱动模型做了进一步的封装。杂散设备的主设备号同意使用10,次设备号从0~256。下面来具体分析一下杂散设备的原理。
在内核代码linux/drivers/char/misc.c中我们可以看到这么一句subsys_initcall(misc_init);这说明在内核启动的时候会调用misc_init()函数,这个函数也在linux/drivers/char/misc.c文件中,它主要完成的功能是注册一个典型的字符设备(和普通字符设备的注册流程基本相同),misc_init()函数的关键代码如下:
register_chrdev(MISC_MAJOR,"misc",&misc_fops)。
从上面代码中我们可以看到注册的字符设备的file_operations结构体名为misc_fops,我们同样可以在文件linux/drivers/char/misc.c中找到misc_fops结构体的定义如下:
static const struct file_operations misc_fops = {
.owner = THIS_MODULE,
.open = misc_open,
};
可以看到杂散字符设备的file_operations结构体中只有一个 .open函数,按照字符设备设备驱动原理当应用程序通过open API函数打开一个主设备号为10次设备号为0~256的设备文件时最终调用的就是这里的misc_open函数,那它是怎样最终调用用户给定的open函数的呢?这就要去看看misc_open的具体实现代码了。
在介绍misc_open函数前我们先来熟悉一下使用杂散设备的另外两个函数:
misc_register(struct miscdevice * misc)和misc_deregister(struct miscdevice *misc)这里我们重点讲一下misc_register函数。这个函数有一个参数misc,这个参数就是我们在实现杂散设备驱动时定义的struct miscdevice结构体,其中实现了这个驱动的file_operations结构。misc_register函数最主要的一个工作就是把misc挂到一个名为misc_list的双向链表上。我们具体看一下misc_open函数的实现,这个函数主要的一项工作是通过struct inode传过来的次设备号在链表misc_list中查找对应的struct miscdevice 结构,然后把struct miscdevice 结构中的用户file_operations结构的指针赋值给misc_open的另一个参数struct file对应的段位上,进而调用struct miscdevice 中的open函数,这样用户的open函数就最终被调用了,此时打开的设备文件的file_operations指针就是指向了struct miscdevice中的file_operations,当我们调用read,write函数时最终就会调用我们自己编写的对应的函数了。
阅读(2115) | 评论(0) | 转发(2) |