当前课程知识点:Linux 内核分析与应用 > 第9章 设备驱动 > 9.3 设备驱动模型 > Video
大家好 我们今天来讲
设备驱动的第三讲设备驱动模型
那么首先我们来讲一下为什么要引入设备驱动模型
由于Linux支持世界上几乎所有的 不同功能的硬件设备
导致Linux内核中有一半的代码是设备驱动 而且
随着硬件的快速升级换代
设备驱动的代码量也快速增长
为了降低设备多样性带来的Linux驱动开发的复杂度
以及设备热插拔处理
电源管理等等
Linux内核提出了设备模型
也称为Driver Model的概念
设备模型将硬件设备归纳
分类 然后抽象出一套标准的数据结构和接口
驱动的开发 就简化为对内核所
规定的数据结构的填充和实现
因此 Linux设备驱动模型是一种抽象
为内核建立起统一的设备模型
其目的是提供一个对系统结构的
一般性抽象描述
Linux设备模型跟踪
所有系统所知道的设备
以便让设备驱动模型的核心程序
协调驱动和新设备之间的关系
Linux设备驱动程序
那么引入目的呢 我们在这块列出一个表
第一个目的呢就是电源管理和系统的关机
设备之间大多数情况下都是有依赖
有耦合的 因此呢要实现电源管理
就必须对系统的设备结构有清楚的理解
应知道先关哪个 然后才能再关哪个
另外呢 Linux设备驱动程序非常的复杂
它提供了一种与用户空间进行通信的机制
也就是sys文件系统
sys虚拟文件系统的实现与设备模型密切相关
并且向外界展示了它所表述的结构
向用户空间所提供的系统信息
以及改变操作参数的接口
就要通过sys文件系统来实现
也就是通过设备模型来实现的
第三个目的呢 是热插拔设备
它处理与用户空间进行热插拔设备的
通信呢是通过设备模型来管理的
第四种呢是设备分类机制
设备模型包括了对设备分类的机制
它会在更高的功能层上描述这些设备
并使得这些设备对用户空间可见
尤其是将命名设备的功能从内核层
转移到了用户层
大大提高了设备管理的灵活性
第五点呢是对象生命周期的管理
设备模型实现一系列机制
以及处理对象的生命周期
对象之间的关系 以及这些对象在用户空间中的表示
简化了编程人员创建和管理对象的工作
下面我们来介绍一下sys文件系统
sys文件系统是一个类似于proc文件系统的特殊文件系统
用于将系统中的设备呢组织成层次结构
并向用户程序提供详细的内核数据信息
也就是说 在用户态下
可以通过对sys文件系统的访问呢
来查看内核态的
一些驱动或者设备等信息
如图呢为sys文件系统的目录以及子目录的信息
下面我们对Linux的设备模型进行一个简要的概述
Linux设备驱动模型使用一系列抽象
也就是面向对象设计思想里头的类
提供统一的设备管理视图
这些抽象包括 总线 类 设备和设备驱动
首先 我们对这几个概念做一个概要的概述
第一个概念就是总线
总线是CPU和一个或多个设备之间信息交互的通道
为了方便设备模型的抽象呢
所有的设备都应该连接到总线上
第二个概念是分类 在Linux设备模型中呢
Class的概念非常类似面向对象程序设计中的Class
它主要是集合具有
相似功能或属性的设备
这样就可以抽象出一套可以在
多个设备之间共用的数据结构和接口函数
因而从属于相同Class的设备的驱动程序
不再需要重新定义这些公共的资源
直接从Class中继承即可
第三种呢是Device设备
抽象系统中所有的硬件设备 描述它的名字
属性 从属的Bus 从属的Class等信息
第四种Device Driver设备驱动
Linux设备模型用Driver抽象硬件设备的驱动程序
它包括设备的初始化
电源管理相关的接口实现
而Linux内核中的驱动开发
基本都围绕该抽象进行
也就是实现所规定的接口函数
下面我们来介绍一下这个模型的
核心对象kobject
那么在这里我们给出了kobject
这个数据结构以及各个字段的含义
kobject结构体是设备驱动模型底层的一个结构体
这个结构体是设备驱动模型下所有对象的
一个基本单元
它是对设备驱动模型下所有对象抽象出来的
共有的部分
kobject结构体提供了一些公共型的服务
比如对象的引用计数
维护对象的链表
对象的上锁
对于用户空间的表示等等
设备驱动模型中各种对象其
内部呢都会包含一个kobject
它的地位呢
相当于面向对象思想中的总基类
第二种对象呢我们介绍一下集合体kset
那么在这里同样给出了这个数据结构
它的各个字段以及具体的含义
kset呢
是嵌入相同类型结构的 kobject 的集合
可以把它看成是一个容器
可将所有相关的kobject对象聚集在一起
比如“全部的块设备”就是一个kset
kset 结构关心的是对象的聚集与集合
它与 kobject 的关系如图所示
第三个对象是具有共同特性的ktype
kobject是一个抽象而基本的对象
对于一族具有共同特性的kobject呢
就是用定义在头文件kobject.h中的ktype来描述
这里给出了这个数据结构的定义以及各个字段的含义
下面呢我们来介绍一种
总线模型 叫做platform平台总线驱动模型
为了解决驱动代码和设备信息耦合
Linux提出了platform bus也就是平台总线的概念
也就是使用虚拟总线
将设备信息和驱动程序进行分离
也就是机制与策略分离的这样一种策略
平台总线呢会维护两条链表
分别管理设备和驱动
当一个设备被注册到总线上的时候呢
总线会根据其名字
搜索对应的驱动
如果找到就将设备信息导入驱动程序并执行驱动
当一个驱动被注册到平台总线的时候呢
总线也会搜索设备
总之 平台总线负责将设备信息和驱动代码进行匹配
这样就可以做到驱动和设备信息的分离
与传统的bus/device/driver机制相比
platform平台由内核进行统一管理
在驱动中使用资源
提高了代码的安全性和移植性
当硬件部分的时序变了或者芯片替换了
我们只需要修改硬件的部分代码
还有一部分代码是属于内核的稳定部分是不需要修改的
这就是一种通用的接口 因此呢
本讲重点讲解platform模型
这里我们给出了platform总线驱动模型的一个图
platform平台总线是一条虚拟总线
其中呢platform_device为相应的设备
platform_driver为相应的驱动
我们首先看一下描述平台的结构
platform_driver
那么在这里给出了这个结构的具体字段
可以看到platform_driver结构体中
包含了probe和remove等相关的操作
同时呢还内嵌了device_driver结构体
那么我们下面就来看一下
描述设备驱动的结构device_driver
从这个结构里头呢我们看到最后一个域指针p呢
它是指向driver_private
这是一个描述驱动私有数据的结构
那么这个结构到底包含哪些字段呢
我们从这个结构中可以看到
无论是从名字上 还是从上面的注释中呢
我们都可以看到呢void *driver_data这个数据结构
就是为了设计用来放置不同驱动的数据的
那么下面我们来看一下描述设备的结构
platform_device结构
那么从这个结构里头呢,我们可以看到
其中呢有一个sturct resource
那么这个数据结构我们在前面I/O空间管理里头呢已经讲过了
在这里我们主要来
给大家讲解一下 设备与驱动呢
如何进行匹配 我们通过一个比喻来给大家来进行一个解释
比如说这个红娘呢就相当于总线
她负责男方比如说设备 女方呢相当于驱动的撮合
那么男方找到红娘以后呢
说我要登记一下 看看有没有合适的姑娘
那么这个时候呢就相当于设备或驱动的注册
红娘这时候需要看看有没有匹配的姑娘
那么这时就是match 函数进行匹配
这个匹配是怎么匹配的呢 就是看name是不是相同
如果没有找到匹配的就告诉
男方没有合适的对象 先等一等 别急
设备和驱动呢就会等待 直到匹配成功
那么终于遇到匹配的呢 那就结婚呐
结完婚呢 男方就向女方交代 他有哪些资源
比如 存款 房子等等
那么这个就相当于我们那个resource结构
女方说好呀 于是去拿钱买东西 比如买书 买衣服呢
那么这个呢就相当于probe函数
匹配成功以后我们驱动执行的第一个函数
那么通过这个例子呢 我们对于设备和
驱动的匹配过程呢有一个感性的认识
下面我们来通过代码说明
设备和驱动 到底是如何匹配的
那么首先是总线来出场
系统为platform总线呢定义了一个bus_type
来实例化platform_bus_type这种结构
系统为platform呢总线定义了一个
bus_type这样一个数据结构
那么我们在这里呢 给它进行实例化
其定义如下
接下来我们看它又是怎么样工作的呢
在platform.c 中呢可以看到注册函数
那么在这个注册函数里头呢 我们看到呢把相关的
函数呢都给挂上去了
然后呢我们看一下设备与驱动匹配的代码
那么在这个代码的
最后呢我们看到呢就是名字的匹配
在 platform_bus_type 中呢调用了
platform_match
基本的匹配规则呢实际上就是名字匹配
设备驱动中呢
引入platform 这个概念呢
隔离了BSP和驱动
在BSP中呢定义platform设备
和设备使用的资源呢
备的具体匹配信息
而在驱动中呢
只需要通过API去获取资源和数据
做到了板相关代码和
驱动代码的分离
使得驱动呢具有更好的可扩展性和
跨平台性
最后我们来给出参考文献
上面介绍了这些基本的知识以后呢
大家通过编写相关代码并进行调试呢
真正地感受这些基础知识
如何具体的应用起来 那么通过
参考资料给出大家如何去编写代码
那么第一个呢参考资料就是《Linux 驱动开发》
网上有大量的详尽的开发资料
在这里给大家推荐一篇
从这个代码里头呢 大家就可以
写出具体的platform这样的一个驱动程序
从这个参考资料中呢我们可以
具体地写出驱动程序并进行调试
最后大家带着疑问来上路
platform平台模型的优势到底是什么
谢谢大家
-1.1 Linux操作系统概述
-1.2 Linux内核结构以及内核模块编程
--Video
-1.3 Linux内核源码中的双链表结构
--Video
-1.4 源码分析-内核中的哈希表
--Video
-1.5 动手实践-Linux内核模块的插入和删除
--Video
-第1章 概述--章节测验
-2.1 内存管理之内存寻址
--Video
-2.2 段机制
--Video
-2.3分页机制
--Video
-2.4 动手实践-把虚拟地址转换成物理地址
--Video
-第2章 内存寻址--章节测验
-3.1 进程概述
--Video
-3.2 Linux进程创建
--Video
-3.3 Linux进程调度
--Video
-3.4 动手实践-打印进程描述符task_struct中的字段
--Video
-3.5工程实践-基于内核模块的负载监控
--Video
-第3章 进程管理--章节测验
-4.1 Linux内存管理机制
--Video
-4.2 进程用户空间管理机制
--Video
-4.3 物理内存分配与回收机制(上)
--Video
-4.4 物理内存分配与回收机制(下)
--Video
-4.5 动手实践-Linux内存映射基础(上)
--Video
-4.6 动手实践-Linux内存映射实现(中)
--Video
-4.7 动手实践-Linux内存映射测试(下)
--Video
-4.8 初学者对内存管理的常见疑惑
-第4章 内存管理--章节测验
-5.1 中断机制概述
--Video
-5.2 中断处理机制
--Video
-5.3 中断下半部处理机制
--Video
-5.4 时钟中断机制
--Video
-5.5 动手实践-中断上半部的代码分析及应用
--Video
-5.6 动手实践-中断下半部的代码分析及应用
--Video
-第5章 中断--章节测验
-6.1 Linux中的各种API
--Video
-6.2 系统调用机制
--Video
-6.3 动手实践-添加系统调用(系统调用日志收集系统)
--Video
-第6章 系统调用--章节测验
-7.1 内核同步概述
--Video
-7.2 内核同步机制
--Video
-7.3 动手实践-内核多任务并发实例(上)
--Video
-7.4 动手实践-内核多任务并发实例(下)
--Video
-第7章 内核同步--章节测验
-8.1 虚拟文件系统的引入
--Video
-8.2 虚拟文件系统的主要数据结构
--Video
-8.3 文件系统中的各种缓存
--Video
-8.4 页高速缓存机制以及读写
--Video
-8.5 动手实践-编写一个文件系统(上)
--Video
-8.6 动手实践-编写一个文件系统(中)
--Video
-8.7 动手实践-编写一个文件系统(下)
--Video
-第8章 文件系统--章节测验
-9.1 设备驱动概述
--Video
-9.2 I/O空间管理
--Video
-9.3 设备驱动模型
--Video
-9.4 字符设备驱动程序简介
--Video
-9.5 块设备驱动程序简介
--Video
-9.6 动手实践-编写字符设备驱动程序
--Video
-9.7工程实践-编写块设备驱动的基础(上)
--Video
-9.8 工程实践-块设备驱动程序分析(中)
--Video
-9.9 工程实践-块设备驱动程序实现(下)
--Video
-第9章 设备驱动--章节测验
-致谢与说明
--Video