I/O 设备
I/O 设备的概念比较简单,大家日常生活中接触的也很多,在第一部分就简单介绍一下 I/O 设备的划分。
I/O 设备分类
- 传输速度:低速、中速、高速。
- 信息交换单位:块设备和字符设备。
- 共享属性:独占设备、共享设备、虚拟设备。
I/O 设备控制实现
现在,我们简单了解了 I/O 设备的基本概念,但是这些 I/O 设备具体是怎么跟 CPU 进行交互的或者说是怎么接入这个系统的?这里便需要引出 I/O 设备控制器的概念了,简单来说 I/O 设备控制器就是 I/O 与 CPU 之间的中介(一层抽象/间接)。由它统一管理外接设备,并向 CPU(用户程序)提供统一的 I/O 接口。
在硬件实现上,通过设备控制器 CPU 总线与 I/O 总线联系起来。在软件层面上,用户的 I/O 请求一般会先以系统调用的形式陷入内核态,再让操作系统内核去与设备驱动程序进行交互,最终传达到对应的设备上进行 I/O 操作。
I/O 设备管理的目标和功能
- 提高效率:提高 I/O 访问速率,匹配 CPU 和多种不同处理速度的外设。
- 方便使用:方便用户使用,对不同类型的设备提供统一的调用接口,并协调设备的并发使用。
- 方便控制:方便 OS 内部对设备的控制,例如:增加和删除设备,以适应新的设备类型。
设备控制器
设备控制器由以下三个部分组成:
- 控制器与 CPU 的接口:控制器设有数据寄存器、控制寄存器、状态寄存器,并为控制器设置专门的 I/O 指令,并在开机之后,借由内存映射(I/O 地址空间映射到内核虚拟地址空间)的机制,使得 CPU 可以借由设备控制器与外设进行交互。
- 控制器与设备的接口
- I/O 逻辑:用于实现 CPU 对于 I/O 设备的控制。
而设备控制器肩负着以下重任:
- 接收和识别 CPU 命令。
- 负责 CPU 与设备之间数据交换的桥梁。
- 设备状态的了解和报告。
- 设备地址识别。(初始化 I/O 地址空间)
- 缓冲区的维护。(稍后介绍)
- 对设备传来的数据进行差错检测。
设备驱动程序
设备驱动程序由一下几个部分组成:
- 自动配置和初始化子程序:检测所要驱动的硬件设备是否存在、正常。若设备正常,则对该设备及其相关设备驱动程序所需的软件状态进行初始化。在系统初始化的时候被调用一次。
- 服务于 I/O 请求的子程序:程序 I/O 系统调用最终会调转到该子程序,故系统仍认为该子程序是和调用进程属同一个进程,只是由用户态变成内核态,可在其中调用sleep()等与进程运行环境有关的函数来让进程陷入阻塞等待的状态。
- 中断服务子程序:系统接收来自硬件的中断,再由中断分配处理程序跳转到该子程序,进行相应的中断处理,唤醒相应的子程序等。
具体的 I/O 控制技术
程序控制 I/O(Programmed I/O)
程序控制 I/O 也称轮询或者查询方式 I/O,它由 CPU 代表进程向 I/O 模块发出指令,然后进入忙等待状态,直到操作完成后进程才能够继续执行。说白了,也就是弄一个死循环,不停的问所需要的 I/O 设备能不能被自己使用,直到可以使用之后才退出该死循环。
由于是忙等待,所以会耗用 CPU 资源,虽然易于实现,但是代价也挺大的。
- 应用程序提出 I/O 请求。
- 设备驱动程序检查设备的状态。
- 状态正常,就向设备发出相应的控制命令。
- 不断轮询设备是否完成了该次操作。
- 完成操作,将数据送给应用程序。
- 应用程序继续进行相应的处理。
中断驱动方式
中断方式,与轮询就有鲜明的对比,轮询是程序不停的问 I/O,而中断是 I/O 好了之后通过中断信号的方式,让 CPU(程序知道 I/O 好了)。这样就不用进程忙等待,可以干其他事儿或者被阻塞让其他进程上来。但是这种中断的方式,会浪费 CPU 的一定时间,所以只适用于数据传输率低的设备。
-
一至三步同轮询。
-
将状态记录在设备状态表中, CPU继续其它工作。
-
设备完成工作后向CPU发中断信号,转入中断处理程序。
-
中断处理程序发现这是一个正常地完成了控制命令的信号后,把结果提交给设备管理程序。
-
设备管理程序会从设备状态表里查询是哪一个请求的完成。
-
把相应的数据送到 应用程序。
-
通知应用程序可以继续执行。
直接存储访问方式(DMA)
DMA 是由一个专门的控制器来控制 I/O 操作。在 DMA 开始之前,CPU 会设置好 DMA 控制器的相关寄存器(与哪一个设备进行交互,进行什么交互等等),然后让出系统总线的控制权(让给 DMA 控制器)。DMA 控制器根据设好的参数与外设交互,结束之后通过中断的方式告知 CPU 自己任务结束了,并交出系统总线的控制权(在 DMA 期间,CPU 自己可以进行一下数值计算 emmm 不需要总线的工作都行)。
采用 DMA 的方式,主要是为了减轻 CPU 的中断负载,一般是用于大量数据的高速交换(这样就用一次中断代替了很多次密集的中断),如与硬盘、显卡、声卡、网卡等进行交互的时候。
通道技术
通道与 DMA 原理相似,都是一种 CPU 的放权,通道自身是一个特殊的处理器,有自己的指令与程序专门负责数据输入输出的传输控制。而 CPU 便可将“传输控制”的功能下方给通道,自身只需要负责“数据处理”即可。
与 DMA 不同在于,通道一次可以进行几组不同的 I/O 操作(相当于 DMA 的进阶),进一步减少 CPU 的干预,不过带来的负面效果是实现逻辑复杂,费用较高。
I/O 缓冲区
缓冲技术出现的原因:
- 为了匹配 CPU 与外设的不同处理速度。
- 减少对 CPU 的中断次数
- 提高 CPU 和 I/O 设备之间的并行性。
单缓冲
一个缓冲区,CPU 和外设轮流使用,一方处理完之后接着等待对方处理。外设将数据传入缓冲区之后,操作系统便将数据从缓冲区写入用户进程空间之中,写入完成之后,外设又可以向缓冲区写入同时用户进程可以进行计算。这样可以使用户进程计算与外设写入缓冲区一定程度上的并行进行。
双缓冲
有两个缓冲区,那么再单缓冲区的基础上(用户进程计算与外设读写缓冲区并行),可以进一步的实现外设读写缓冲区和操作系统将缓冲区内容传送至用户进程空间之间的并行,不过由于 CPU 速度与外设速度不匹配,这种并行也只是一定程度上的。
环形缓冲
有多个缓冲区,这些缓冲区组成一个循环链条,链条上有两个指针,一个是 I/O 设备当前读写的缓冲区,一个是操作系统当前读写的缓冲区,整个工作原理有点像“生产者-消费者模型”,I/O设备负责生产,操作系统负责消费。环形缓冲适合 CPU 与外设处理速度相差较大的应用场景。
缓冲池
缓冲区由三个队列构成,空闲缓冲区队列,输入缓冲区队列,输出缓冲区队列。这样能够提高缓冲区的整体利用率。
设备从输出缓冲区队列中读取数据,读取完毕后将该缓冲区置入空闲队列;设备从空闲队列中取出一个缓冲区,向其写入数据并置入输入缓冲区队列。与设备操作相反,操作系统从输入队列中取出缓冲区读取数据交给用户进程,再将该缓冲区置入空闲队列;对于用户进程输出,将包含输出数据缓冲块置入输出队列。