Linux内核(8) - 设备模型(下)
设备模型拍得再玄幻,它也只是个模型,必须得落实在具体的子系统,否则就只能抱着个最佳技术奖空遗恨。既然前面已经以USB子系统的实现分析示例了分析内核源码应该如何入手,那么这里就仍然以USB子系统为例,看看设备模型是如何软着陆的。
内核中USB子系统的结构
我们已经知道了USB子系统的代码都位于drivers/usb目录下面,也认识了一个很重要的目录——core子目录。现在,我们再来看一个很重要的模块——usbcore。你可以使用“lsmod”命令看一下,在显示的结果里能够找到有一个模块叫做usbcore。
localhost:/usr/src/linux-2.6.23/drivers/usb/core # lsmod
Module Size Used by
af_packet 55820 2
raw 89504 0
nfs 230840 2
lockd 87536 2 nfs
nfs_acl 20352 1 nfs
sunrpc 172360 4 nfs,lockd,nfs_acl
ipv6 329728 36
button 24224 0
battery 27272 0
ac 22152 0
apparmor 73760 0
aamatch_pcre 30720 1 apparmor
loop 32784 0
usbhid 60832 0
dm_mod 77232 0
ide_cd 57120 0
hw_random 22440 0
ehci_hcd 47624 0
cdrom 52392 1 ide_cd
uhci_hcd 48544 0
shpchp 61984 0
bnx2 157296 0
usbcore 149288 4 usbhid,ehci_hcd,uhci_hcd
e1000 130872 0
pci_hotplug 44800 1 shpchp
reiserfs 239616 2
edd 26760 0
fan 21896 0
⋯⋯
找到了usbcore那一行吗?core就是核心,基本上你要在你的电脑里用USB设备,那么两个模块是必须的:一个是usbcore,这就是核心模块;另一个是主机控制器的驱动程序,比如这里usbcore那一行我们看到的ehci_hcd和uhci_hcd,你的USB设备要工作,合适的USB主机控制器模块也是必不可少的。
usbcore负责实现一些核心的功能,为别的设备驱动程序提供服务,提供一个用于访问和控制USB硬件的接口,而不用去考虑系统当前存在哪种主机控制器。至于core、主机控制器和USB驱动三者之间的关系,如下图所示。
USB驱动和主机控制器就像core的两个保镖,协议里也说了,主机控制器的驱动(HCD)必须位于USB软件的最下一层。HCD提供主机控制器硬件的抽象,隐藏硬件的细节,在主机控制器之下是物理的USB及所有与之连接的USB设备。而HCD只有一个客户,对一个人负责,就是usbcore。usbcore将用户的请求映射到相关的HCD,用户不能直接访问HCD。
core为咱们完成了大部分的工作,因此咱们写USB驱动的时候,只能调用core的接口,core会将咱们的请求发送给相应的HCD。
USB子系统与设备模型
关于设备模型,最主要的问题就是,bus、device、driver是如何建立联系的?换言之,这三个数据结构中的指针是如何被赋值的?绝对不可能发生的事情是,一旦为一条总线申请了一个struct
bus_type的数据结构之后,它就知道它的devices链表和drivers链表会包含哪些东西,这些东西一定不会是先天就有的,只能是后天填进来的。
具体到USB子系统,完成这个工作的就是USB core。USB core的代码会进行整个USB系统的初始化,比如申请struct
bus_type usb_bus_type,然后会扫描USB总线,看线上连接了哪些USB设备,或者说Root
Hub上连了哪些USB设备,比如说连了一个USB键盘,那么就为它准备一个struct device,根据它的实际情况,为这个struct
device赋值,并插入devices链表中来。
又比如Root Hub上连了一个普通的Hub,那么除了要为这个Hub本身准备一个struct
device以外,还得继续扫描看这个Hub上是否又连了别的设备,有的话继续重复之前的事情,这样一直进行下去,直到完成整个扫描,最终就把usb_bus_type中的devices链表给建立了起来。
那么drivers链表呢?这个就不用bus方面主动了,而该由每一个driver本身去bus上面登记,或者说挂牌。具体到USB子系统,每一个USB设备的驱动程序都会对应一个struct
usb_driver结构,其中有一个struct device_driver driver成员,USB
core为每一个设备驱动准备了一个函数,让它把自己的这个struct device_driver
driver插入到usb_bus_type中的drivers链表中去。而这个函数正是我们此前看到的usb_register。而与之对应的usb_deregister所从事的正是与之相反的工作,把这个结构体从drivers链表中删除。
而struct
bus_type结构的match函数在USB子系统里就是usb_device_match函数,它充当了一个红娘的角色,在USB总线的USB设备和USB驱动之间牵线搭桥,类似于交大BBS上的鹊桥版,虽然它们上面的条件都琳琅满目的,但明显这里match的条件不是那么的苛刻,要更为实际些。
可以说,USB
core的确是用心良苦,为每一个USB设备驱动做足了功课,正因为如此,作为一个实际的USB设备驱动,它在初始化阶段所要做的事情就很少,很简单了,直接调用usb_register即可。事实上,没有人是理所当然应该为你做什么的,但USB
core这么做了。所以每一个写USB设备驱动的人应该铭记,USB设备驱动绝不是一个人在工作,在他身后,是USB
core所提供的默默无闻又不可或缺的支持。
Linux内核(8) - 设备模型(下)的更多相关文章
- Linux内核(7) - 设备模型(上)
对于驱动开发来说,设备模型的理解是根本,毫不夸张得说,理解了设备模型,再去看那些五花八门的驱动程序,你会发现自己站在了另一个高度,从而有了一种俯视的感觉,就像凤姐俯视知音和故事会,韩峰同志俯视女下属. ...
- Linux内核系列设备模型(一) Kobject与Kset
1.Kobject Kobject是设备驱动模型的核心结构,它使所有设备在底层都有统一的接口.在内核注册的kobject对象都会对应sysfs文件系统中的一个目录(目录名称有Kobject结构中k_n ...
- 基于tiny4412的Linux内核移植 -- 设备树的展开
作者信息 作者: 彭东林 邮箱:pengdonglin137@163.com QQ:405728433 平台简介 开发板:tiny4412ADK + S700 + 4GB Flash 要移植的内核版本 ...
- 基于tiny4412的Linux内核移植 -- 设备树的展开【转】
转自:https://www.cnblogs.com/pengdonglin137/p/5248114.html#_lab2_3_1 阅读目录(Content) 作者信息 平台简介 摘要 正文 一.根 ...
- linux驱动之设备模型
linux 设备驱动模型 inux2.6提供了新的设备模型:总线.驱动.设备.基本关系简要的概括如下: 驱动核心可以注册多种类型的总线. 每种总线下面可以挂载许多设备.(通过kset devices) ...
- 对Linux内核tty设备的一点理解(转)
虽然一直做嵌入式Linux,宿主机和开发板通信天天都在用tty设备通信,但是其实自己对TTY设备及终端的概念认识几乎是0.对于Linux内核的终端.tty.控制台等概念的认识很模糊.由于在学习的时候碰 ...
- Linux 内核 动态设备
术语"热插拔"最普遍使用的意义产生于当讨论这样的事实时, 几乎所有的计算机系统现在 能够处理当系统有电时设备的出现或消失. 这非常不同于只是几年前的计算机系统, 那时 程序员知道他 ...
- 羽夏看Linux内核——引导启动(下)
写在前面 此系列是本人一个字一个字码出来的,包括示例和实验截图.如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作.如想转载,请把我的转载信息附在文章后面,并 ...
- Linux 内核类设备
一个类的真正目的是作为一个是该类成员的设备的容器. 一个成员由 struct class_device 来表示: struct class_device { struct kobject kobj; ...
随机推荐
- Objective-C面向对象之实现类
一般涉及到面向对象都会C#,Java都不可避免的涉及到类,C#中类的后缀名是.cs,Java中是.java,Object-C中一般用两个文件描述一个类,后缀名为.h为类的声明文件,用于声明成员变量和方 ...
- Android动画-帧动画
Android 平台提供了两种动画一种是 Frame动画,即顺序的播放事先做好的图像,与gif图片或者说跟放电影的原理相似,另一种是Tween动画,就是对场景里的对象不断的进行图像变化来产生动画效果( ...
- 修改一行SQL代码 性能提升了100倍
在PostgreSQL中修改了一行不明显的代码,把(ANY(ARRAY[...]) 改成 ANY(VALUES(...))),结果查询时间从20s变为0.2s.最初我们学习使用 EXPLAN ANAL ...
- Java基础(三):修饰符、运算符、循环结构和分支结构
一.Java修饰符: Java语言提供了很多修饰符,主要分为以下两类:访问修饰符和非访问修饰符.修饰符用来定义类.方法或者变量,通常放在语句的最前端. 1.访问控制修饰符: Java中,可以使用访问控 ...
- 为什么空格拷贝到linux 会变成两个
为什么空格拷贝到linux 会变成两个 学习了:https://zhidao.baidu.com/question/266438357.html 在vi界面内输入:set paste 然后进行拷贝: ...
- 【C/C++】:用C实现输出日期的阴历日子
前言 输出阴历一直是个老大难的问题.由于阴历日子没有规律.所以这里须要做的就是通过打表的算法做到输出阴历日子,可是非常多人都不太了解原理,我这里就给大家送上了一个福利.把自己做好的基于打表的阴历的日子 ...
- ArcGIS高程Z值的去除方法
在ArcGIS中,我们常用的几何类型有点.线.面.体(体,在涉及三维的情况下使用),但在这之外,可能会遇到带ZM的类型,如图所示,面ZM,它与面类似,但比面多两个字段. 在编辑中查看草图属性可看到Z值 ...
- 在windows资源管理器添加进入当前目录dos窗口的快捷菜单
regedit.exe进入注册表 定位到HKEY_CLASSES_ROOT\Folder\shell 新建一项cmd,在cmd下再新建一项command,修改command的值为cmd.exe /k ...
- SQLServer 之 树查询
一.SqlServer树查询 1.使用公用表表达式(CTE) 很多人可能想要查询整个树形表关联的内容都会通过循环递归来查...事实上在微软在SQL2005或以上版本就能用别的语法进行查询,下面是示例. ...
- mac 安装升级python3
如果没有安装过python3的话那就直接下载dmg文件安装升级,一般下载安装后的路径为 /Library/Frameworks/Python.framework/Versions 如果同时安装了多个p ...