linux分类驱动对字符设备框架压力的卸载_dog250的博客-程序员秘密

技术标签: struct  input  file  linux  linux内核  框架  

2.6内核引入了input字系统,usb子系统,misc子系统等一系列字符设备子系统,在熟练掌握这些子系统之后,我们来看一下linux内核设计这么些子系统的意义何在?可以连接的设备越来越多,这些设备的种类也越来越杂,传统的字符设备/块设备的分类已经不能满足要求,以字符设备为例,现在的linux字符设备体系已经不能代表所有支持的字符设备的最小交集,况且,在随着设备的增多,越来越长的线性设备链表给管理带来了诸多不便,因此“需要增加一个层”来给字符设备体系卸载一些压力了,于是就将所有的“一类”设备总结成“一个”设备,然后将这一个设备作为字符设备加入链表,而真正的字符设备需要新设计的“层”来管理了,在重新设计之后,被总结出来的“那个”字符设备已经不再是传统的设备了,而是“设备类”了,同时,/dev目录下也有了相应的“设备类”,比如/dev/input,这个下面有一系列文件,其中有些文件就代表上面所说的“设备类”,比如mice就是所有的鼠标,而还有些文件代表真实的设备,比如mouse0,mouse1之类的。从应用的角度来看,input子系统确实卸载了字符设备系统的压力,只因新增了一个层,至于这种层该如何实现,还是要看代码:
static int __init input_init(void)
{
    int err;
    err = class_register(&input_class);
    err = input_proc_init();
    err = register_chrdev(INPUT_MAJOR, "input", &input_fops); //只需要初始化一个字符设备即可,主设备号为0xd
    return 0;
}
static const struct file_operations input_fops = {
    .owner = THIS_MODULE,
    .open = input_open_file,
};
static int input_open_file(struct inode *inode, struct file *file)
{
    struct input_handler *handler;
    const struct file_operations *old_fops, *new_fops = NULL;
    handler = input_table[iminor(inode) >> 5]; //可看出,目前input子系统只支持8类设备
    new_fops = fops_get(handler->fops); //得到input子系统“层”中设置的真正的fops
    old_fops = file->f_op;
    file->f_op = new_fops;
    err = new_fops->open(inode, file);
    ...
}
由上述字符设备体系的代码可见,被卸载的真正的字符设备需要input层来集中实现。可以想见,input子系统中一个设备类就应该有一个handler,由设备文件inode得到的minor来索引,我们看一个例子:
# stat mice
File: `mice'
Size: 0               Blocks: 0          IO Block: 4096   character special file
Device: 1607h/5639d     Inode: 23921566    Links: 1     Device type: d,3f  #主设备号为0xd,次设备号为0x3f
...
注意主次设备号,input子系统将整个设备号空间按照高3位分割成了8个子空间,每一个子空间代表input子系统中一类设备的所有设备。
static int __init mousedev_init(void)
{
    mousedev_mix = mousedev_create(NULL, &mousedev_handler, MOUSEDEV_MIX); //建立了/dev/input/mice文件
    input_register_handler(&mousedev_handler);
    return 0;
}
mousedev_init只是初始化了input子系统中鼠标设备的框架,然后通过mousedev_create创建了一个通用的鼠标类,那么真实的鼠标类文件何时建立呢?每一类input设备都有一个input_handler,对于鼠标就是mousedev_handler,它通过mousedev_init注册进系统,所有的handler形成一个链表,同时系统中input子系统还拥有另一条链表,那就是input设备,每当有新的设备插入机器时,在更底层的设备驱动知道这是一个input设备时,就将之纳入input子系统的管理,也就是初始化一个input_dev,然后将之链接进input_dev链表,随后遍历input_handler链表,在找到“可以处理该设备”的input_handler之后调用其connect方法,对于鼠标那就是mousedev_connect,在mousedev_connect中会初始化一个鼠标设备:mousedev_create:
static struct mousedev *mousedev_create(struct input_dev *dev, struct input_handler *handler, int minor)
{
    struct mousedev *mousedev;
    mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL);
    ...
    if (minor == MOUSEDEV_MIX)
        strlcpy(mousedev->name, "mice", sizeof(mousedev->name));
    else
        snprintf(mousedev->name, sizeof(mousedev->name), "mouse%d", minor);
...
    mousedev->dev.devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor);//用于创建/dev/input下面的文件
...
}
input子系统中input_dev链表和input_handler链表相认的过程和底层bus中的的device链表和device_driver链表相认的过程几乎是一样的,运用了相同的思想。在device和device_driver的层次,顶多在pci的层次,由probe函数调用input子系统的初始化规程,比如分配input_dev,注册中断等等,注册好input_dev之后,该设备就被纳入input子系统的管辖了,整个层次是device--pci...--input_dev--input_handler--input字符设备--/dev/input/xxx,在中断发生的时候,中断处理程序会从参数中得到input_dev,然后就可以用input_report_XX来报告了,该报告可以顺着刚刚说过的层次线索一直到达用户空间需要该中断结果的地方,比如移动了一下鼠标的中断会被Xwindow来使用。
     input子系统仅仅是一个卸载原始结构压力的一个例子,诸如usb子系统,sound子系统以及misc子系统都是这样实现的,给你的感觉并没有什么不一样,如果所有的字符设备统统直接在chrdev框架下实现,/dev下将被创建所有的字符设备,如果很多字符被分类了,比如分到了input类中,或者分到了usb类中,那么每一个设备依然拥有一个/dev下的字符设备文件,只是位置不同了,可能被放入了input,usb子目录下,stat的结果仍然是character special file,没有什么不同,在使用sysfs/udevd的情况下,你甚至可以不建立input,usb等子目录,依然将所有文件建立在/dev目录下也没什么不可。注意,input/usb/misc等子系统仅仅规整了内核设备驱动的结构,这种规整对于用户空间是透明的。我感觉,linux内核的这种规整最能体现计算机业的一句真理,那就是“加一个层次”,linux内核通过引入新的层次,在不改变原有字符驱动结构的情况下,成功将几个新的分类驱动层次插入到了既有的框架,这同时也说明了linux内核中字符设备框架原本的灵活性。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/dog250/article/details/5676429

智能推荐

CREATE TABLE 表名 AS SELECT 语句用法详解_xuehongyou的博客-程序员资料_as select

这里写自定义目录标题新表不存在,创建新表新表已经存在新表不存在,创建新表1.创建新表并且携带数据create table new_table as select * from exist_table2.创建新表不携带数据create table new_table as select * from exist_table where 1=2注意:复制只会复制表的结构和数据,原始表中的索引,主键等都不会复制。新表已经存在1.全量复制旧表

webstorm vue-cli3 配置别名_Moqin89的博客-程序员资料_webstorm 别名

配置后就可以跳转到别名的函数了我们知道在vue-cli1.x,vue-cli2.x  webstorm配置别名时候可以设置中指向webpack.base.conf.js就可以了但是vue-cli3.x中是没有webpack.base.conf.js的,别名在vue-config.js中设置了,chainWebpack: (config) => { config....

spring-boot-maven-plugin插件_客 人的博客-程序员资料

<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> &amp

没工作经验不是借口_普通网友的博客-程序员资料_php没有工作经验

一、具有基本的兴趣和强烈的责任心每个程序员,在专业上都是从不会到会,从不熟悉到熟悉,一步一步走过来,技术可以学习,工作能力可以提升,兴趣和责任心有一个最基本的好处——可以缩短这个过程。 二、随时明确工作目标1、项目组的工作目标是什么?2、项目有几个阶段?每个阶段的目标是什么?3、我的工作在项目中处于什么位置?4、本月我的工作目标是什么?5、本周我的工作目标是什么?6、今

自学编程,看书还是视频?为你分析利弊_C语言进阶之路的博客-程序员资料_学c语言是看书好还是看视频好

前面我们说过,学习C语言可以通过书籍、视频、结合实战来学习。但是具体为什么这么做,不这么做会怎样,很多人还纠结于此,这里就为大家详细分析一下,看书、看视频的好处和坏处,用充分的理由来为你说明。一、书,有什么好处呢?第一,书籍比较全面,系统化,可以针对一个技术点、一门语言,循序渐进,深度挖掘。我们从小到大,在学校学习,学校都会发书籍给我们。即使没有用上,也仍然要给我们发书籍。这是因为书籍可以给我们一个参考,从第一页到最后一页,学习的过程是循序渐进的,也是比较系统的。第二,书和书之间可以形.

select count(0) from 和 select count(*) from 的区别_热带鱼2020的博客-程序员资料

select count(*) :查询总行数,并且会对表的每个字段进行扫描select count(0) :忽略所有列,只进行全表总行数

随便推点

【郭林专刊】多个js技巧代码 ._云哥中国的博客-程序员资料

1.文本框焦点问题onBlur:当失去输入焦点后产生该事件onFocus:当输入获得焦点后,产生该文件Onchange:当文字值改变时,产生该事件Onselect:当文字加亮后,产生该文件(value=='') {value='mm'}">点击时文字消失,

谷歌,微软,阿里,美团实习生面经_triplebee的博客-程序员资料_有一个n乘n的棋盘,上面有m个糖果,最开始有一个人在棋盘左上角,他可以向左向右或者

新鲜出炉的实习生面经!主要包括:Google,微软,阿里,美团和因为各种原因没有面试成的公司…… 基本情况基本情况:某985硕士,常用语言C/C++、Python,研究方向为深度学习、计算机视觉,有一篇水的会议论文、一篇水的期刊论文,有ACM等算法竞赛和数据挖掘类竞赛获奖经历,在导师和Github上都有项目。除了谷歌投的是SWE,其它都是算法岗。谷歌Warm up: Go...

Qt 实现拖放内容 drag - drop 【简单明了】_ShenMingYi_的博客-程序员资料_qt drag drop

前言:看几天看了 Qt 实现跨‘窗口’,‘程序’ 拖拽 文件,信息,图片之类感觉看完他们写的文章 ,还是不太明白 自己看了看 试了试写这篇文章巩固一下本文说的比较详细简单我下面录制的 gif 因为拖拽时 的图标不会被录制进去 观看会受到极大的影响下面是我用手机照的照片移动过程中 …我们仔细的看这个过程1.当我们鼠标 点击 send widget 时候 会触发 mousePr...

Vue中v-model与v-bind区别_笋干zzZ~的博客-程序员资料

Vue中v-model与v-bind区别:绑定数据的三种方式:{{}}从data中取对应的值v-model:v-bind:v-model主要用于表单元素,实现了双向绑定。在同时使用v-model和v-bind中,v-model能建立双向绑定并且对input,select,textarea具有优先权。<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <

FATE开源社区开发工作最新进展_普通网友的博客-程序员资料

题图摄于北京中轴线近日,FATE 开源社区成立了由多家单位组成的开发专委会,主导 FATE 项目的开发,本文介绍最新开发进展,并欢迎社区成员踊跃参与社区建设。有兴趣参与社区建设的朋友,可以...

机器学习入门(2):Ubuntu16.04环境搭建安装Anaconda和Pycharm_2022.8.22起夯实基础100天的博客-程序员资料

1.Ubuntu上安装Anaconda在Windows上清华大学开源软件镜像站https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/下载位于最下面的Anaconda3-5.3.1-Linux-x86_64.sh,然后将Anaconda3-5.3.1-Linux-x86_64.sh拖到虚拟机Ubuntu下,打开terminal,进行到An...

推荐文章

热门文章

相关标签