当前课程知识点:Linux 内核分析与应用 > 第9章 设备驱动 > 9.2 I/O空间管理 > Video
大家好
今天我们来开始讲设备驱动的第二讲
I/O空间的管理
首先我们来介绍一下设备控制器
什么是设备控制器呢
它是计算机中的一个实体
其主要职责
是控制一个或多个I/O设备
以实现I/O设备
和处理器之间的数据交换
它是CPU与I/O设备之间的接口
它通过控制总线
接收从CPU发来的命令
并去控制I/O设备工作
控制器相当于CPU
与外设打交道的一个助理
以使处理器
从繁杂的设备控制事务中
解脱出来
设备通常会提供一组
寄存器来控制设备
读写设备
以及获取设备的状态
这些寄存器呢
就是控制寄存器
数据寄存器和状态寄存器
它们位于控制器中
从编址方式来说
如果I/O空间与内存一起编址
对应的内存空间被称为I/O内存
如图中的左边所示
如果I/O空间单独编址
就位于I/O空间
通常被称为I/O端口
如图中的右边所示
那么我们简单介绍一下
I/O端口
设备驱动程序
要直接访问外设
或其接口卡上的物理电路
通常以寄存器的形式出现访问
外设寄存器也称为I/O端口
通常包括
控制寄存器 状态寄存器
和数据寄存器
那么如何访问
I/O内存和I/O端口呢
问“I/O 内存”的方式呢
一般呢是通过
访问一般内存的指令呢
就可以访问I/O内存
那么访问 I/O 端口”的方式呢 是通过
外设寄存器的读 写
专门设置的指令呢来进行访问
下面我们来看一下
I/O内存资源的访问
用于I/O指令的 地址空间
相对来说呢是很小的
自从PCI总线出现后呢
无论CPU的设计采用I/O 端口方式
还是I/O内存方式呢
都必须将外设卡上的存储器
映射到内存空间
实际上是采用了虚拟内存的手段
这样的映射是通过专门的函数
叫做ioremap来建立的
该函数呢 如图所示
其中的参数呢
含义呢也在图里头呢给出来了
那么如何访问I/O端口空间呢
在驱动程序
请求了I/O端口空间中的端口资源后呢
它就可以通过CPU的I/O指令
来读写这些I/O端口
在读写I/O端口时要注意的一点就是
大多数平台都区分
8位 16位和32位的端口
其中port参数呢
指定I/O端口空间中的端口地址
在大多数平台上比如说x86上
它都是无符号的短整型
其它的一些平台上则是无符号的整型
显然 端口地址的类型
是由I/O端口空间的大小来决定的
那么如何查看你机子上的I/O口呢
你可以通过访问proc目录下
有个ioports文件
来获取设备当前的 I/O 端口号
下面我们给出I/O资源的管理
Linux将基于I/O端口
和I/O内存的映射方式呢
通称为 I/O区域
Linux设计了一个通用的数据结构
resource 来描述各种 I/O 资源
该结构呢定义在ioport.h中
那么这个结构的
其中各个字段以及含义呢
我们在这里已经列出 就不具体来说了
Linux下对I/O资源
主要用结构体resource来管理
管理的方法就是用resource来描述
使用的I/O资源的状态
并将这些resource用如下两个
resource作为表头
一个是呢ioport_resource
一个是iomem_resource
这个链表按地址
大小的顺序呢链接起来了
那么任何设备驱动程序都可以使用
下面三个函数申请 分配和释放资源
传递给它们的参数呢
作为资源树的根节点
和要插入的新资源数据结构的地址
是作为参数的
那么第一个函数叫request_resource
它是把一个给定范围分配给一个 I/O 设备
第二个函数是分配资源
第三个函数就是释放资源
那么如何管理I/O端口资源
我们采用I/O端口的
X86处理器为外设实现一个
单独的地址空间
也即 I/O空间 或称为 I/O 端口空间
其大小是64KB
Linux在其所支持的所有平台上
都实现了I/O端口空间 这一概念
Linux是基于 I/O 区域 这一概念来实现
对I/O端口资源的管理的
那么它在ioport.h这个文件里头
定义了三个对I/O端口空间
进行操作的接口函数
同样这三个函数分别是
申请资源
然后检查这个是否已被占用
最后呢是释放这个资源
在这里我们列出了三个具体的函数
下面介绍一下如何管理I/O区域资源
Linux将基于I/O端口和基于I/O内存
的资源统称为 I/O区域
I/O 区域仍然是一种I/O资源
因此它仍然可以用
resource结构类型来描述
Linux在头文件include/linux/ioport.h中
定义了三个对I/O区域进行操作的函数
那么这三个函数我们看
前面都加了两下划线
啊 一般表示内部的函数
其中我们对第一个函数
__request_region这个函数做一个
简要的介绍
它是查找resource
链表中是否有与申请的I/O资源有冲突
如果冲突则返回NULL
如不冲突则将新申请的resource地址
从小到大的
顺放依次插入至以ioport_resource或者
iomem_resource为链表头的单向链表中
那么如何管理I/O内存资源呢
基于I/O区域的操作函数一般为
__xxx_region
如前面所示
那么在这里呢
定义了三个对I/O内存进行操作的函数
I/O内存操作的函数呢
是在中间呢 我们看加了一个mem
表示是对内存的操作
那么第一个函数同样是分配资源
第二个是检测
最后呢是一个释放内存的资源
那么最后我们对
这部分的内容呢做一个小结
Linux是以一种倒置的树形结构
来管理每一类I/O资源
包括I/O端口 外设内存 DMA和IRQ等
每一类I/O资源
都对应有一颗倒置的资源树
树中的每一个节点
都是一个resource结构
而树的根结点root则描述了
该类资源的整个资源空间
下面我们来给出参考文献
首先呢就是Linux驱动开发
依然是最经典的参考书
那么网上有大量的驱动开发的资料
我们在这里针对这一节的内容
推荐一篇基础篇
大家可以去查阅
最后我们带着疑问上路
内核对I/O资源的管理
为什么采用树结构 谢谢大家
-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