📂 操作系统 - Operating System / Chapter IV 持久性 / Section 1 IO设备与磁盘 / 1-1 IO设备

I/O设备

2026-06-02
#OS
  • 系统架构

    • 一个典型的系统架构:
      • CPU通过某种内存总线(memory bus)互联电缆连接到系统内存
      • 图形设备GPU或者其他高性能I/O设备通过常规的I/O总线(I/O bus)连接到系统
      • 更下层的外围总线(peripheral bus)更慢的设备连接到系统,例如磁盘、鼠标或其他类似设备
  • 标准设备

    • 一个标准I/O硬件设备(理想的)应当具有以下组成部分:
      • 接口(interface)

        • 像软件一样,硬件也需要提供接口来让系统软件控制它。设备都有自己的特定接口以及典型交互协议
        • 其中包含3个寄存器
          • 状态(status)寄存器:用于读取并查看设备的当前状态
          • 命令(command)寄存器:用于通知设备执行某个具体任务
          • 数据(data)寄存器:用于将数据传给设备从设备接收数据
      • 内部(internal structure)

        • 包含设备相关的特定实现,负责将设备展现给外部的复杂接口(服务)实现出来
        • 简单的设备通常会用若干个芯片来实现其功能
        • 复杂的设备可能会需要简单的CPU、一些通用内存、设别相关的特定芯片来完成其工作,例如现代RAID控制器会包含成百上千行固件(firmware)(即硬件设备中的软件)
  • 标准协议

    • 操作系统通过程序控制输入输出(PIO, Programmed Input/Output) 来进行与设备之间的数据传输,其中的步骤就是操作系统与设备的典型交互
      1. 操作系统通过反复读取状态寄存器等待设备进入可以接受命令就绪状态。这个操作被称为轮询(polling) 设备
      2. 操作系统下发数据到数据寄存器
      3. 操作系统将命令写入命令寄存器,这样设备就知道数据和命令都已经准备好了,要开始执行命令
      4. 操作系统又开始不断地轮询设备等待设备完成指令(指令可能成功完成也可能失败)
    • 这个简单协议具有一些低效性,例如操作系统在等待设备时可以切换执行下一个就绪进程,而不是一直轮询
  • 利用中断减少CPU开销

    • 中断减少CPU开销

      • 有了中断(interrupt),操作系统不需要再轮询设备,而是向设备发出一个请求后,让对应进程睡眠,然后自己就可以切换执行其他进程
      • 当设备完成命令,就会抛出一个硬件中断,引发CPU跳转执行操作系统预先定义好的中断服务例程(ISR, Interrupt Service Routine),或者更简单的中断处理程序(Interrupt handler),它们是一段操作系统代码,会结束之前的请求(例如从设备接收到了结果数据或错误码)唤醒等待I/O的进程继续执行
      • 由此,中断允许计算与I/O重叠(overlap),这是提高CPU利用率的关键
    • 中断的局限

      • 中断并不总是好用,假设有一个性能极高的设备,在接收命令后的几乎一瞬间就可以完成请求,此时如果使用中断,反而会使系统变慢,毕竟这代表着切换到其他进程再切换回来
      • 可以采用混合(hybrid) 策略,即在给设备发送请求后先轮询一小段时间,如果设备没有完成请求再执行中断
      • 网络中也不适合使用中断,因为网络端会接收大量数据包,如果每一次数据包都会引发一次中断,那么就有可能导致操作系统发生活锁,即一直处理中断而无法处理用户层的请求
      • 另一个优化方法是合并(coalescing),即设备在抛出中断前先等一小段时间,在此期间,其他请求可能很快可以完成,这样就可以将多次请求结果合并为一次中断
  • 利用DMA进行更高效的数据传送

    • 在PIO中,CPU向设备拷贝数据的过程也是不小的时间开销
    • 解决方法是使用DMA(Direct Memory Access)。DMA引擎是系统中的一个特殊设备,可以协调完成内存与设备间的数据传输,不需要CPU介入
    • 使用DMA流程如下:
      1. 操作系统会告诉DMA引擎目标数据在内存中的位置要拷贝的大小以及要拷贝到哪个设备,然后操作系统就可以处理其他任务了
      2. 当DMA的任务完成后,DMA控制器会抛出一个中断告诉操作系统自己已经完成了数据传输
      3. 后来的步骤就和PIO一样,当设备完成了请求后,操作系统就会过来获取结果
  • 设备交互的办法

    • 软件与设备交互的办法有两种:
      • 操作系统通过特权指令(privileged) 来和设备交互,且操作系统是唯一可以与设备直接交互的实体
      • 通过内存映射I/O(memory-mapped I/O) 来交互。通过这种方式,硬件将设备寄存器作为内存地址提供。当需要访问设备寄存器时,操作系统直接装载(读取)/存入(写入)该内存地址,然后硬件会将数据装载/存入到设备上,而不是物理内存
  • 设备驱动程序

    • 通过设备驱动程序设备的接口就可以被纳入操作系统