Linux 中 字符类设备驱动,很大一部分代码都是相同的,具有一些共性。内核工作者,总是考虑得那么全面。MISC驱动模型就简化了一类字设备符驱动。MISC 其主设备号为10,次设备号则是由驱动开发者来分配。当然有些次设备号也是已经被使用了。可以查看源码下面的Documentation/devices.txt 。字符设备的流程不再赘言。直接先看看用MISC模型的字符驱动流程。
从这个流程可以看出来,MISC字符设备驱动很简单。当然这个简单是由内于核来完成了一部分工作,才变得如此清晰。
与MISC模型有关的文件:
drivers/char/misc.c 模型建立。实现了面向用户的接口函数misc_register ,misc_deregister。
proc文件实现等。
include/linux/miscdevice.h 函数申明以及一些结构体。
- struct miscdevice {
- int minor; // 次设备号
- const char *name; //设备名
- const struct file_operations *fops; //字符设备fops
- struct list_head list; //内核有misc list链表
- struct device *parent; //这两个设备结构体是为了创建设备文件
- struct device *this_device; //
- const char *devnode;
- };
从流程图中看不出有任何字符设备的痕迹。看看如何封装的。在misc.c中misc_init这个就是MISC驱动模型的入口。
从上面图中可以知道,字符设备的那一套在misc_init中实现了。
在misc_register()中
- int misc_register(struct miscdevice * misc)
- {
- struct miscdevice *c;
- dev_t dev;
- int err = 0;
-
-
- INIT_LIST_HEAD(&misc->list); //链表项使用时必须初始化
-
-
- mutex_lock(&misc_mtx);
- list_for_each_entry(c, &misc_list, list) {
- if (c->minor == misc->minor) {
- mutex_unlock(&misc_mtx);
- return -EBUSY;
- }
- } //遍历链表如果发现次设备号一样的,返回错误
-
-
- if (misc->minor == MISC_DYNAMIC_MINOR) { //动态次设备号
- int i = DYNAMIC_MINORS;
- while (--i >= 0)
- if ( (misc_minors[i>>3] & (1 << (i&7))) == 0)
- break;
- if (i<0) {
- mutex_unlock(&misc_mtx);
- return -EBUSY;
- }
- misc->minor = i;
- }
-
-
- if (misc->minor < DYNAMIC_MINORS)
- misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);
- dev = MKDEV(MISC_MAJOR, misc->minor);
-
- //创建了设备节点,所有的misc设备都是基于misc_class这个类的,仅次设备号就可以
- // 创建区别于其他misc设备的设备节点
- misc->this_device = device_create(misc_class, misc->parent, dev,
- misc, "%s", misc->name);
- //udev创建设备节点使用,linux设备模型相关
- if (IS_ERR(misc->this_device)) {
- err = PTR_ERR(misc->this_device);
- goto out;
- }
-
-
- /*
- * Add it to the front, so that later devices can "override"
- * earlier defaults
- */
- list_add(&misc->list, &misc_list); //添加到misc_list之中
- out:
- mutex_unlock(&misc_mtx);
- return err;
- }
首先遍历misc_list链表,查找所用的次设备号是否已经被注册,防止冲突。如果是动态次设备号则分配一个,然后调用MKDEV生成设备号,从这里可以看出所有的misc设备共享一个主设备号MISC_MAJOR,然后调用device_create,生成设备文件,这里就用到了misc_init中的class_create创建的类。最后将此注册的设备驱动中的list加入到misc_list链表中。
misc_deregister 中与misc_register中刚好是相反的工作。在misc_list 链表中删除此list ,device_destroy 删除设备文件。MISC模型大概就是这样的。
参考资料:http://blog.csdn.net/yaozhenguo2006/article/details/6760575
阅读(8958) | 评论(0) | 转发(0) |