Skip to main content

输入/输出设备

概述

I/O 设备

tip

I/O 设备管理是操作系统设计中最凌乱也最具挑战的部分,因为其包含了很多领域的不同设备及其相关应用程序,很难有一个通用且一直的方案。

分类

按照信息交换的单位分类:

  1. 块设备,以数据块为单位,属于有结构设备,如磁盘等,传输速率较高,可寻址(即可随机地读写任意一块);
  2. 字符设备,无结构,如交互式终端、打印机等,速率较低,不可寻址,常使用终端 I/O 方式; 按照速率分类:
  3. 低速设备,几到几百 b/sb/s,如键盘鼠标等;
  4. 中速设备,数千到数万 b/sb/s,如激光打印机等;
  5. 高速设备,数百千之千兆 b/sb/s,如磁盘机和光盘机等。

I/O 接口

I/O 接口是一个 设备控制器,位于 CPU 和设备之间,既要与 CPU 通信,又要与设备通信,还能按照 CPU 发来的命令控制设备工作。

I/O 接口有单独的数据寄存器和控制/状态寄存器,用于传输数据或存储控制信息和状态信息;一个设备控制器可以连接多个设备,因此有一个或多个设备接口,每个接口中都存在数据、状态和控制三种类型的信号。

I/O 逻辑实现对设备的控制,通过一组控制器与 CPU 交互,将 CPU 的 I/O 命令进行译码。

设备控制器的主要功能有:

  1. 接受和识别 CPU 的命令,如磁盘控制器能接受读、写、查找等;
  2. 数据交换,设备和控制器之间、控制器和主存之间的数据传输;
  3. 表示和报告设备状态;
  4. 地址识别;
  5. 数据缓冲;
  6. 差错控制。

I/O 端口

指的是设备控制器当中可被 CPU 直接访问的 寄存器

  1. 数据寄存器,实现 CPU 和外设之间的缓冲;
  2. 状态寄存器,获取执行结果和设备状态,让 CPU 知道是否准备好;
  3. 控制寄存器,由 CPU 写入,一边启动命令或更改设备模式;

为了实现 CPU 和 I/O 端口的通信有两种方式:

  1. 独立编址,为每个端口分配一个 I/O 端口号,所有的 I/O 端口形成 I/O 端口扣减,普通用户程序不能访问,只有操作系统使用特殊的 I/O 指令才能访问;
  2. 统一编址,有称为 内存映射 I/O,每个端口被分配唯一的内存地址,该地址不会被实际分配给其他内存,通常分配给端口的地址靠近地址空间的顶端;

I/O 控制方式

I/O 软件层次结构

tip

I/O 软件涉及面很宽,向下与硬件密切相关,向上与虚拟存储器系统、文件系统和用户直接交互;目前普遍采用层次结构设计,煤层利用下层提供的服务:

  1. 用户 I/O 软件,实现与用户交互的接口,一般大部分都实现在操作系统内部,用户层软件必须通过系统调用获取服务;
  2. 设备独立性软件,用于实现用户程序和设备驱动器的统一接口、设备命令、设备的保护及设备的分配和释放等,同时为设备管理和数据传送提供必要的存储空间;又称为 设备无关性,使得应用程序独立于具体使用的物理设备;在应用程序中可是使用逻辑设备名来请求某种设备,系统实际执行时转换为物理设备名;逻辑设备名可以增加设备分配的灵活性,易于实现 I/O 重定向(改变具体设备,而不必改变应用程序);
  3. 设备驱动程序,与硬件直接相关,负责具体实现对设备发出的操作指令,驱动 I/O 设备工作的驱动程序;通常每类设备配置一个设备驱动程序,是 I/O 进程与设备控制器之间的通信程序,通常以进程的形式存在;向上提供接口,向下和设备控制器通信;可以隐藏 I/O 内核子系统和设备控制器的差异;
  4. 中断处理程序,保存被中断进程的 CPU 环境,转入相应的中断处理程序,处理完毕后恢复现场,返回被中断进程;中断处理层的重要任务有,进行进程上下文的切换,对处理中断信号源进行测试,读取设备状态和修改进程状态等;
  5. 硬件

应用程序与 I/O 接口

字符设备接口,以字符为单位、如键盘打印机,传输速率较低,不可寻址,常采用中断驱动方式;

块设备接口,以数据块为单位,如磁盘,传输速率高、可寻址,常采用 DMA 方式;

网络设备接口,网络套接字接口,通过套接字进行连接和发送数据;

阻塞/非阻塞 I/O,调用 I/O 时进程会被阻塞,需要等待 I/O 操作完成;非阻塞就是 I/O 时进程不阻塞,完成后返回错误返回值,通常进程通过轮询方式查询 I/O 是否完成;大多数操作系统都采用阻塞式。

设备独立性软件

总体而言,设备独立性软件包括执行所有设备公有操作的软件;

高速缓存与缓冲区

磁盘高速缓存,利用内存中的一块空间作为缓存,因此逻辑上属于磁盘,物理上是驻留在内存的盘块;有两种形式:

  1. 开辟单独的空间,大小固定;
  2. 将未利用的内存空间作为缓冲池,供请求分页系统和磁盘 I/O 时共享。

缓冲区,主要作用:

  1. 缓和 CPU 和 I/O 设备速度不匹配的矛盾;
  2. 减少对 CPU 的中断频率,放宽对 CPU 中断响应时间的限制;
  3. 解决基本数据单元大小不匹配的问题;
  4. 提高 CPU 和 I/O 设备之间的并行性。 实现方法有:
  5. 硬件缓冲器,但成本高,一般只用于关键部位;
  6. 在内存内设置缓冲区:
    1. 单缓冲,同一时刻只能由一方写入或取出;
    2. 双缓冲,由于单缓冲存在缓冲区为空之后才能写入,因此使用两个缓冲区,写入和读取分离,提高并行度;此外还能实现双向的数据传输;
    3. 循环缓冲,由多个大小相等的缓冲区组成,链表组成的环形式;
    4. 缓冲池,由多个系统中公用的缓冲区组成,分配三个队列,空缓冲队列,输入队列(输入数据已满)和输出队列(输出数据已满)

缓冲区和高速缓存都是介于高速设备和低速设备之间,区别有:

  1. 高速缓存中的数据在低速设备上也有,而缓冲区不一定;
  2. 若高速缓存中没有对应数据,则会去低速设备查找,而缓冲区则必须访问,高速设备不会直接访问低速设备;

设备分配和回收

根据用户 I/O 请求分配设备,让设备经可能忙碌,同时避免不合理分配造成死锁,使用三种方式:

  1. 独占式设备;
  2. 分时式共享设备;
  3. 以 SPOOLing 方式使用外部设备,实现了虚拟设备的功能,可以同时将设备分配给多个进程,实质上是实现了对设备 I/O 操作的批处理。

设备分配的主要数据结构有:

  1. 设备控制表(DCT),一个设备控制表表示一个设备,表现是设备的属性,申请设备的进程 PCB 会排成一个设备队列;
  2. 控制器控制表(COCT),控制设备与内存交换数据,而设备控制器又要请求通道为它服务,每个 COCT 都有一个表相指向相应的通道控制表指针;
  3. 通道控制表(CHCT),一个通道可以为多个设备控制器服务,因此 COCT 中还有指向这些设备控制器表的指针;CHCT 与 COCT 的关系是一对多的关系;
  4. 系统设备表(SDT),整个系统只有一张 SDT,记录所有已连接的设备。

设备分配有静态和动态,前者主要用于独占式设备的分配,在作业开始前,系统一次性分配需要的所有设备、控制器,不会出现死锁但利用率低;后者在进程执行过程中,按需分配。

安全分配方式:阻塞式,阻塞过程中也不保持任何资源,但 CPU 和 I/O 串行工作;

不安全分配方式,非阻塞式,仅当所需设备被占用才阻塞,一个进程可操作多个设备,推进迅速,但可能造成死锁。

逻辑设备名到物理设备名的映射:提高设备分配的灵活性和利用率,方便实现 I/O 重定向,引入了设备独立性。系统中有一张 逻辑设备表(Logical Unit Table, LUT),表项包括逻辑设备名、物理设备名和设备驱动程序入口地址;一般可以为整个系统或是每个用户设立一张 LUT。

SPOOLing 技术(假脱机技术)

tip

将独占设备改造称共享设备的技术,利用专门的外围控制器,将低速 I/O 设备上的数据传送到高速磁盘,或者相反。

输入井和输出井,在磁盘中,模拟脱机输入/出时的磁盘,分别接收 I/O 和用户程序的输入/出;一个进程的输入/输出保存为一个文件,所有进程的文件连接为一个队列。

输入/输出缓冲区,在内存中,连接输入/输出设备和输入/输出井;

实际上就是 I/O 设备将输入存入缓冲区,或者进程将输出存储缓冲区,等到其设备空闲时再从缓冲区中获取数据。

设备驱动程序接口

要求每个驱动程序与操作系统之间有相同或相近的接口,方便添加新设备驱动程序。对于每种设备类型,例如磁盘,操作系统都要定义一组驱动程序必须支持的函数,对磁盘而言,必须包含读、写、格式化等,驱动程序中常包含一张表,