I/O 设备

I/O 设备的概念

I/O 就是输入/输出(Input/Output),I/O 设备就是可以将数据输入到计算机,或者可以接收计算机输出数据的外部设备,属于计算机中的硬件部件。I/O 设备一般是由执行 I/O 操作的机械部分和执行控制 I/O 的电子部件组成,I/O 设备的机械部件主要用来执行具体 I/O 操作,例如鼠标/键盘的按钮、显示器的 LED 屏和移动硬盘的磁臂、磁盘盘面。
CPU 无法直接控制 I/O 设备的机械部件,因此 I/O 设备还要有一个电子部件作为 CPU 和 I/O 设备机械部件之间的“中介”,用于实现 CPU 对设备的控制。这个电子部件就是 I/O 控制器,又称设备控制器,通常是一块插入主板扩充槽的印刷电路板。CPU 可控制 I/O 控制器,又由 I/O 控制器来控制设备的机械部件。

I/O 设备的类型

I/O 设备的类型繁多,除了能将它们分为块设备和字符设备、独占设备和共享设备外,还可按使用特性分类和按传输速率分类。按使用特性分类的第一类是存储设备,也称外存、辅存,用以存储信息,存取速度较内存慢但容量大且价格便宜。第二类就是 I/O 设备,它又可分为输入设备、输出设备和交互式设备。

设备类型 说明
输入设备 用来接收外部信息,如键盘、鼠标、扫描仪、视频摄像等
输出设备 用于将计算机处理后的信息送向处理机外部的设备,如打印机、绘图仪等
交互式设备 则是指集成的上述两类设备,用于同步显示用户命令以及命令执行的结果

按传输速度的高低,可将 I/O 设备分为三类。

设备类型 说明
低速设备 传输速率仅为每秒钟几个字节至数百个字节,例如键盘、鼠标器
中速设备 传输速率在每秒钟数千个字节至数十万个字节,例如行式打印机、激光打印机等
高速设备 传输速率在数十万字节至千兆字节,例如磁带机、磁盘机、光盘机等

设备与控制器之间的接口

通常设备并不是直接与 CPU 进行通信,而是与设备控制器通信,因此在 I/O 设备中应含有与设备控制器间的接口.
操作系统:I/O 设备与 I/O 系统_缓冲池
在该接口中有三种类型的信号,各对应一条信号线。

信号线 说明
数据信号线 在设备和设备控制器之间传送数据信号
控制信号线 由设备控制器向 I/O 设备发送控制信号时的通路,信号规定了设备将要执行的操作,如读操作、写操作或执行磁头移动等操作
状态信号线 该信号线用于传送指示设备当前状态的信号,状态有正在读(或写)、设备已读(写)完成
设备控制器

设备控制器的主要功能是控制一个或多个 I/O 设备,以实现 I/O 设备和计算机之间的数据交换。它接收从 CPU 发来的命令,去控制 I/O 设备工作。设备控制器是一个可编址的设备,当它仅控制一个设备时只有一个唯一的设备地址,若控制器可连接多个设备则含有多个设备地址,每一个设备地址对应一个设备。可把设备控制器分成两类:一类是用于控制字符设备的控制器,另一类是用于控制块设备的控制器。

设备控制器的基本功能

功能 说明
接收和识别命令 接收并识别处理机发来的多种命令,利用控制寄存器存放接收的命令和参数,并对所接收的命令进行译码
数据交换 实现 CPU 与控制器之间、控制器与设备之间的数据交换,前者通过数据总线,后者是通过数据寄存器
标识和报告设备的状态 控制器应记下设备的状态供 CPU 了解,在控制器中应设置状态寄存器,用其中的一位反映设备的状态
地址识别 系统中的每一个设备都有一个地址,设备控制器必须能够识别其所控制的每个设备的地址,应配置地址译码器
数据缓冲区 由于 I/O 设备的速率较低,而 CPU 和内存的速率却很高,故在控制器中必须设置缓冲区
差错控制 对于由 I/O 设备传送来的数据,若发现传送中出现了错误,通常是将差错检测码置位并向 CPU 报告

设备控制器的组成

设备控制器位于 CPU 与设备之间,既要与 CPU 通信又要与设备通信,还应具有按照 CPU 所发来的命令去控制设备工作的功能。
操作系统:I/O 设备与 I/O 系统_块设备_02

组件 说明
设备控制器与处理机的接口 用于实现 CPU 与设备控制器之间的通信,在该接口中共有三类信号线:数据线、地址线和控制线
设备控制器与设备的接口 设备控制器上可以连接多个设备,便有多个设备接口。在每个接口中都存在数据、控制和状态三种类型的信号
I/O 逻辑 用于实现对设备的控制,它通过一组控制线与处理机交互,处理机利用该逻辑向控制器发送 I/O 命令。

数据线通常与两类寄存器相连接,第一类是数据寄存器,用于存放从设备送来的数据(输入)或从 CPU 送来的数据(输出)。第二类是控制/状态寄存器,用于存放从CPU送来的控制信息或设备的状态信息。

内存映像

驱动程序将抽象 I/O 命令转换出的一系列具体的命令、参数等数据装入设备控制器的相应寄存器,由控制器来执行这些命令实施对 I/O 设备的控制。这一工作在早期的计算机中利用特定的 I/O 指令实现,为每个控制寄存器分配一个 I/O 端口并设置了一些特定的 I/O 指令。该方法的主要缺点是,访问内存和访问设备需要两种不同的指令。
现在采用的是内存映像 I/O,这种方式中在编址上不再区分内存单元地址和设备控制器中的寄存器地址,而是设置一个 k 值。当 k 值处于 0 ~ n-1 范围时被认为是内存地址,若 k ≥ n 时被认为是某个控制器的寄存器地址。内存映像 I/O 方式统一了对内存和对控制器的访问方法,简化 I/O 的编程。
操作系统:I/O 设备与 I/O 系统_缓冲池_03

I/O 系统

I/O 系统是 OS 的重要组成部分,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设备进行控制 目前对 I/O 设备有四种控制方式:采用轮询的可编程 I/O 方式、采用中断的可编程 I/O 方式、直接存储器访问方式、I/O 通道方式
确保对设备的正确共享 进程应互斥地访问独占设备,共享设备可以在一段时间内允许多个进程同时访问
错误处理 低层软件能够解决的错误就不向上层报告,只有低层软件解决不了的错误才向上层报告,请求高层软件解决

I/O 软件的层次结构

通常把 I/O 软件组织成四个层次。
操作系统:I/O 设备与 I/O 系统_块设备_04

层次 说明
用户层 I/O 软件 实现与用户交互的接口,用户可以直接调用该层提供的库函数对设备进行操作
设备独立性软件 实现用户程序与设备驱动器的统一接口、设备命名、设备的保护以及设备的分配与释放等,为设备管理和数据传送提供必要的存储空间
设备驱动程序 用于具体实现系统对设备发出的操作指令,驱动 I/O 设备工作的驱动程序
中断处理程序 用于保存被中断进程的 CPU 环境,转入相应的中断处理程序进行处理,处理完毕再恢复被中断进程的现场后,返回到被中断的进程

I/O 系统模型

与前面所述的 I/O 软件组织的层次结构相对应,I/O 系统本身也可分为三个层次。

层次 说明
中断处理程序 处于 I/O 系统的底层,直接与硬件进行交互。当有 I/O 设备发来中断请求信号时,中断处理程序首先保存被中断进程的 CPU 环境,然后转入相应设备的中断处理程序进行处理,在处理完成后又恢复被中断进程的 CPU 环境,返回断点继续运行
设备驱动程序 处于 I/O 系统的次底层,是进程和设备控制器之间的通信程序,将上层发来的抽象 I/O 请求转换为对 I/O 设备的具体命令和参数,并把它装入到设备控制器中的命令和参数寄存器中
设备独立性软件 实现了与设备无关性,内容包括设备命名、设备分配、数据缓冲和数据高速缓冲一类软件等

操作系统:I/O 设备与 I/O 系统_块设备_05
由于设备之间的差异很大,每类设备的驱动程序都不相同,故必须由设备制造厂商提供。每当在系统中增加一个新设备时,都需要由安装厂商提供新的驱动程序。这些层次之间有 I/O 系统接口和软件/硬件接口。

接口 说明
I/O 系统接口 I/O 系统与上层系统之间的接口,向上层提供对设备进行操作的抽象 I/O 命令,一些 OS 在用户层提供了与 I/O 操作有关的库函数
软件/硬件(RW/HW)接口 在它的上面是中断处理程序和用于不同设备的设备驱动程序,在它的下面是各种设备的控制器

I/O 系统接口

在 I/O 系统与高层之间的接口中,根据设备类型的不同,又进一步分为若干个接口,例如块设备接口、流设备接口和网络接口。

块设备接口

块设备接口是块设备管理程序与高层之间的接口,用于控制该类设备的输入或输出。块设备是指数据的存取和传输都是以数据块为单位的设备,典型的块设备是磁盘。该设备的基本特征是传输速率较高,并且可寻址。块设备接口将磁盘上的所有扇区从 0 到 n-1 依次编号,n 是磁盘中的扇区总数。这样编号后把磁盘的二维结构改变为一种线性序列,使块设备接口隐藏了磁盘地址是二维结构的情况。块设备接口支持上层发来的对文件或设备的打开、读、写和关闭等抽象命令,将上述命令映射为设备能识别的较低层具体操作。
虚拟存储器系统也需要使用块设备接口,因为在进程运行期间若所访问的页面不在内存时会发生缺页中断,此时就需要利用 I/O 系统,通过块设备接口从磁盘存储器中将所缺之页面调入内存。

流设备接口

流设备接口是流设备管理程序与高层之间的接口,用于控制字符设备的输入或输出。字符设备指数据的存取和传输是以字符为单位的设备,如键盘、打印机等,基本特征是传输速率较低,并且不可寻址,因而对它只能采取顺序存取方式,用户程序获取或输出字符的方法是采用 get 和 put 操作。由于大多数流设备都属于独占设备,必须采取互斥方式实现共享,为此流设备接口提供了打开和关闭操作。

网络通信接口

在现代 OS 中都提供了面向网络的功能,首先需要通过某种方式把计算机连接到网络上,同时操作系统也必须提供相应的网络软件和网络通信接口,使计算机能通过网络与网络上的其它计算机进行通信或上网浏览。

I/O 通道

引入 I/O 通道的动机

虽然在 CPU 与 I/O 设备之间增加了设备控制器后能减少 CPU 对 I/O 的干预,但当主机所配置的外设很多时 CPU 的负担仍然很重。为此在 CPU 和设备控制器之间又增设了I/O 通道(I/O Channel)。主要目的是使一些原来由 CPU 处理的 I/O 任务转由通道来承担,从而把 CPU 从繁杂的 I/O 任务中解脱出来。
在设置了通道后,CPU 只需向通道发送一条 I/O 指令,通道从内存中取出本次要执行的通道程序然后执行。仅当通道完成了规定的 I/O 任务后,才向 CPU 发中断信号。实际上 I/O 通道是一种特殊的处理机,它具有执行 I/O 指令的能力,通过执行通道 I/O 程序来控制 I/ O操作。但 I/O 通道的指令类型单一,且没有自己的内存。

通道类型

外围设备的类型较多,传输速率相差甚大,因而使通道具有多种类型。根据信息交换方式的不同,可把通道分成以下三种类型。

通道 说明
字节多路通道(Byte Multiplexor Channel) 按字节交叉方式工作的通道,通常都含有许多非分配型子通道,按时间片轮转方式共享主通道,当第一个子通道控制其 I/O 设备完成一个字节的交换后,便立即腾出主通道让给第二个子通道使用
数组选择通道(Block Selector Channel) 按数组方式进行数据传送的数组选择通道,可以连接多台高速设备,但它只含有一个分配型子通道,在一段时间内只能执行一道通道程序
数组多路通道(Block Multiplexor Channel) 将数组选择通道传输速率高和字节多路通道能使各子通道(设备)分时并行操作的优点相结合,它含有多个非分配型子通道,既具有很高的数据传输速率,又能获得令人满意的通道利用率

瓶颈问题

由于通道价格昂贵,致使机器中所设置的通道数量势必较少,这往往又使它成了 I/O 的瓶颈,进而造成整个系统吞吐量的下降。例如在图中如果要使用设备 1 需要占用通道 1 和控制器 1,但此时如果还要使用设备 2,会因为通道和控制器数量不足而无法使用。
操作系统:I/O 设备与 I/O 系统_信号线_06
解决“瓶颈”的方法是增加设备到主机间的通路而不增加通道,也就是把一个设备连接到多个控制器上,而一个控制器又连接到多个通道上。
操作系统:I/O 设备与 I/O 系统_缓冲池_07

缓冲区管理

缓冲区

缓冲区是一个存储区域,可以由专门的硬件寄存器组成,也可利用内存作为缓冲区。使用硬件作为缓冲区的成本较高,容量也较小,一般仅用在对速度要求非常高的场合(如存储器管理中所用的联想寄存器)一般情况下利用内存作为缓冲区,“设备独立性软件”的缓冲区管理就是要组织管理好这些缓冲区。
引入缓冲区的原因有:

  1. 缓和 CPU 与 I/O 设备间速度不匹配的矛盾:CPU 的运算速率远远高于 I/O 设备的速率,如果没有缓冲区,在运行时会因为 I/O 设备跟不上 CPU 的速度导致 CPU 停下来等待;
  2. 减少对 CPU 的中断频率,放宽对 CPU 中断响应时间的限制。随着传输速率的提高,需要配置位数更多的寄存器进行缓冲;
  3. 解决数据粒度不匹配的问题:生产者所生产的数据粒度比消费者小时,生产者进程可以一连生产多个数据单元的数据。生产者比消费者粒度大时,生产者每次生产的数据消费者可以分几次从缓冲区中取出消费;
  4. 提高 CPU 和 I/O 设备之间的并行性:生产者在生产了一批数据并将它放入缓冲区后,便可立即去进行下一次的生产。

单缓冲区

假设某用户进程请求某种块设备读入若干块的数据。若采用单缓冲(Single Buffer)的策略,操作系统会在主存中为其分配一个缓冲区。当缓冲区数据非空时,不能往缓冲区冲入数据,只能从缓冲区把数据传出。当缓冲区为空时可以往缓冲区冲入数据,但必须把缓冲区充满以后,才能从缓冲区把数据传出。
操作系统:I/O 设备与 I/O 系统_缓冲池_08
假定从磁盘把一块数据输入到缓冲区的时间为 T,OS 将该缓冲区中的数据传送到用户区的时间为 M,CPU 数据处理(计算)的时间为C。由于 T 和 C 是可以并行的,当 T > C 时系统对每一块数据的处理时间为 M + T,反之则为M + C,故可把系统对每一块数据的处理时间表示为 Max(C,T) + M
操作系统:I/O 设备与 I/O 系统_数据_09

双缓冲区

由于缓冲区是共享资源,生产者与消费者在使用缓冲区时必须互斥。如果消费者尚未取走缓冲区中的数据,即使生产者又生产出新的数据,也无法将它送入缓冲区,生产者等待。
如果设置了两个缓冲区能解决这一问题,同时可以加快输入和输出速度,提高设备利用率。双缓冲区机制(Double Buffer)也称缓冲对换(Buffer Swapping),在设备输入时先将数据送入第一缓冲区,装满后便转向第二缓冲区。此时操作系统可以从第一缓冲区中移出数据,并送入用户进程,接着由 CPU 对数据进行计算。
操作系统:I/O 设备与 I/O 系统_信号线_10
在双缓冲时系统处理一块数据的时间可以粗略地认为是 Max(C,T),如果 C < T 可使块设备连续输入,如果 C > T 则可使 CPU 不必等待设备输入。对于字符设备,若采用行输入方式,在 CPU 执行第一行中的命令时,用户可继续向第二缓冲区输入下一行数据。
操作系统:I/O 设备与 I/O 系统_块设备_11
如果在实现两台机器之间的通信时仅为它们配置了单缓冲,那么它们之间在任一时刻只能实现半双工的数据传输。为了实现全双工数据传输,必须在两台机器中都设置两个缓冲区,一个用作发送缓冲区,另一个用作接收缓冲区。
操作系统:I/O 设备与 I/O 系统_块设备_12

环形缓冲区

若两个缓冲区的速度相差甚远,双缓冲的效果则不够理想,不过可以通过缓冲区数量的增加来改善。多缓冲机制可将多个缓冲区组织成环形缓冲区形式,在环形缓冲中包括多个缓冲区,其每个缓冲区的大小相同。
作为输入的多缓冲区可分为三种类型:用于装输入数据的空缓冲区 R、已装满数据的缓冲区 G 以及计算进程正在使用的现行工作缓冲区 C。作为输入的缓冲区可设置三个指针:用于指示计算进程下一个可用缓冲区 G 的指针 Nextg、指示输入进程下次可用的空缓冲区 R 的指针 Nexti,以及用于指示计算进程正在使用的缓冲区 C 的指针 Current。
操作系统:I/O 设备与 I/O 系统_块设备_13
使用输入循环缓冲,可使输入进程和计算进程并行执行,相应地指针 Nexti 和 Nextg 将不断地沿着顺时针方向移动。这样就可能出现下 Nexti 指针追赶上 Nextg 指针,这意味着输入进程输入数据的速度大于计算进程处理数据的速度。也有可能出现 Nextg 指针追赶上 Nexti 指针,这意味着输入数据的速度低于计算进程处理数据的速度。

缓冲池

当系统较大时会存在大量的循环缓冲,这不仅要消耗大量的内存空间,而且其利用率不高。目前广泛流行既可用于输入又可用于输出的公用缓冲池,在池中设置了多个可供若干个进程共享的缓冲区。缓冲池与缓冲区的区别在于,缓冲区仅仅是一组内存块的链表,而缓冲池则是包含了一个管理的数据结构及一组操作函数的管理机制。
缓冲池管理着多个缓冲区,每个缓冲区由用于标识和管理的缓冲首部以及用于存放数据的缓冲体两部分组成。缓冲首部一般包括缓冲区号、设备号、设备上的数据块号、同步
信号量以及队列链接指针等。为了管理上的方便,一般将缓冲池中具有相同类型的缓冲区链接成一个队列,于是可形成以下三个队列。除了三个队列外,还应具有四种工作缓冲区:用于收容输入数据的工作缓冲区、用于提取输入数据的工作缓冲区、用于收容输出数据的工作缓冲区,以及用于提取输出数据的工作缓冲区。

队列 说明
空白缓冲队列 emq 由空缓冲区所链成的队列
输入队列 inq 由装满输入数据的缓冲区所链成的队列
输出队列 outq 由装满输出数据的缓冲区所链成的队列

缓冲区可以有如下 4 个工作方式:

  1. 输入进程请求输入数据;
  2. 计算进程想要取得一块输入数据;
  3. 计算进程想要将准备好的数据冲入缓冲区;
  4. 输出进程请求输出数据。

操作系统:I/O 设备与 I/O 系统_块设备_14

参考资料

《计算机操作系统(第四版)》,汤小丹 梁红兵 哲凤屏 汤子瀛 编著,西安电子科技大学出版社