操作系统-I/O设备
一个典型的系统架构:CPU 通过某种内存 总线(memory bus)或互连电缆连接到系统内存。图像或者其他高性能 I/O 设备通过常规的 I/O 总线(I/O bus)连接到系统,在许多现代系统中会是 PCI 或它的衍生形式。最后,更下 面是外围总线(peripheral bus),比如 SCSI、SATA 或者 USB。它们将最慢的设备连接到系 统,包括磁盘、鼠标及其他类似设备。
标准设备模型:一个(简化的)设备接口包含 3 个寄存器:一个状态(status)寄存器, 可以读取并查看设备的当前状态;一个命令(command)寄存器,用于通知设备执行某个具 体任务;一个数据(data)寄存器,将数据传给设备或从设备接收数据。通过读写这些寄存 器,操作系统可以控制设备的行为。 描述操作系统与该设备的典型交互,以便让设备为它做某事。协议如下: 第 1 步,操作系统通过反复读取状态寄存器,等待设备进入可以接 收命令的就绪状态。我们称之为轮询(polling)设备(基本上,就是问它正在做什么)。 第2 步,操作系统下发数据到数据寄存器。 可以想象如果这是一个磁盘,需要多次写 入操作,将一个磁盘块(比如 4KB)传递给设备。如果主 CPU 参与数据移动(就像这个示 例协议一样),我们就称之为编程的 I/O(programmed I/O,PIO)。 第 3 步,操作系统将命令写入命令寄存器 最后一步, 操作系统再次通过不断轮询设备,等待并判断设备是否执行完成命令
关键问题:如何减少轮询开销 利用中断减少 CPU 开销: 中断允许计算与 I/O 重叠(overlap),这是提高 CPU 利用率的关键 进程 1 在 CPU 上运行一段时间(对应 CPU 那一行上重复的 1),然后发出一个 读取数据的 I/O 请求给磁盘。如果没有中断,那么操作系统就会简单自旋,不断轮询设备状 态,直到设备完成 I/O 操作(对应其中的 p)。当设备完成请求的操作后,进程 1 又可以继 续运行。 如果我们利用中断并允许重叠,操作系统就可以在等待磁盘操作时做其他事情: 在磁盘处理进程 1 的请求时,操作系统在 CPU 上运行进程 2。磁盘处 理完成后,触发一个中断,然后操作系统唤醒进程 1 继续运行。这样,在这段时间,无论 CPU 还是磁盘都可以有效地利用。
利用 DMA 进行更高效的数据传送 进程 1 在运行过程中需要向磁盘写一些数据,所以它开始进行 I/O 操作,将数据从内存 拷贝到磁盘(其中标示 c 的过程)。拷贝结束后,磁盘上的 I/O 操作开始执行,此时 CPU 才 可以处理其他请求。 关键问题:如何减少 PIO 的开销 原因:使用 PIO 的方式,CPU 的时间会浪费在向设备传输数据或从设备传出数据的过程中。如何才能分 离这项工作,从而提高 CPU 的利用率? 解决方案就是使用 DMA(Direct Memory Access)。DMA 引擎是系统中的一个特殊设备, 它可以协调完成内存和设备间的数据传递,不需要 CPU 介入。 2)设备交互的方法 关键问题:如何与设备通信 主要有两种方式来实现与设备的交互。第一种办法相对老一些 (在 IBM 主机中使用了多年),就是用明确的 I/O 指令。这些指令规定了操作系统将数据发 送到特定设备寄存器的方法,从而允许构造上文提到的协议。 第二种方法是内存映射 I/O(memory- mapped I/O)。通过这种方式,硬件将设备寄存器 作为内存地址提供。当需要访问设备寄存器时,操作系统装载(读取)或者存入(写入) 到该内存地址;然后硬件会将装载/存入转移到设备上,而不是物理内存。
每个设备都有非常具体的接口,如何将它们纳入操作系统? 关键问题:如何实现一个设备无关的操作系统 举例:它只需要简单地向通用块设备层发送读 写请求即可,块设备层会将这些请求路由给对应的设备驱动,然后设备驱动来完成真正的 底层操作。尽管比较简单,但图 36.3 展示了这些细节如何对操作系统的大部分进行隐藏。 设备驱动案例研究: 简单的IDE磁盘驱动程序: IDE 硬盘暴露给操作系统的接口比较简单,包含 4 种类型的寄存器,即控制、命令块、 状态和错误。 初始化设备交互的简单协议: 等待驱动就绪; 向命令寄存器写入参数; 开启I/O; 数据传送(针对写请求); 中断处理; 错误处理;
本章介绍了两种技术,中断和 DMA,用于提高设备效率。我们还介绍了访问设备寄存器的两种方式,I/O 指令和内存映射 I/O。最后,我们介绍了设备驱动程序的概念,展示了操作系统本身如何封装底层细节,从而更容易以设备无关的方式构建操作系统的其余部分。
|