『现代操作系统』IO硬件原理

I/O 硬件原理

0.1. I/O 设备

0.1.1. 块设备(block device)

把信息存储在固定大小的块中,每个块都有自己的地址. 每个块可以独立于其他块读写. 如 硬盘, CD-ROM , USB 盘 …

0.1.2. 字符设备(character device)

字符设备以字符为单位发送或接收一个字符流, 而不考虑任何块结构. 它是不可寻址的.
如打印机,网络接口, 鼠标(用作指点设备)…

0.2. 设备控制器(device controller / adapter)

I/O 设备一般由两部分组成: 机械部分和电子部分.
电子部分就是设备控制器. 常以插入(PCI)扩展槽中的印刷电路板的形式出现.

控制器与设备之间的接口是很低层次的接口. 它的任务就是把串行的位流转换为字节块,并进行必要的错误校正.

0.3. 内存映射 I/O

每个控制器有几个寄存器, OS 可以读写来了解,更改设备的状态信息. 控制器还有 OS 可以读写的 数据缓冲区.

问题来了: CPU 如何与设备的控制寄存器和数据缓冲区通信.

0.3.1. 方案

  • 方法一: 每个控制寄存器被分配一个 I/O 端口(所有端口形成端口空间,受保护不被普通用户访问). 然后可以设置指令来读写,

IN REG, PORT将读取控制器寄存器 PORT 中的内容到 CPU 寄存器 REG

  • 方法二: 内存映射 I/O. 将所有控制寄存器映射到内存空间, 都被分配唯一的地址, 且这些内存地址不会再分配.

IO-hardware-1

0.3.2. 工作原理

CPU 读入一个字时, 不论是从内存还是 I/O 端口, 都将目的地址放在总线的地址线上, 总线控制线置 READ 信号看. 还要用一条线表明是 I/O 空间 还是内存空间. 如果是 I/O空间, I/O设备将响应请求.

0.3.3. 优点

  • 如果需要特殊的 I/O 指令读写设备控制寄存器,那么访问这些寄存器需要使用汇编代码, 调用这样的过程需要增加开销,

对于`内存映射 I/O ,设备控制寄存器只是内存中的变量, 和其他变量一样寻址,可以用 C 语言编写驱动程序

  • 对于内存映射 I/O , 不需要特殊的保护机制来阻止用户进程执行 I/O 操作. 操作系统只需注意不要将内存映射的地址映射到用户虚拟地址空间. 更有利的是, 如果有多个设备, 可以将内存映射 I/O 映射到不同的页, 可以分配特定的页给用户,使其使用驱动程序, 而且不担心各驱动程序之间的影响

0.3.4. 缺点

  • 不能对设备控制器的寄存器进行 cache, 因为设备的状态改变, 软件将没有办法发现. 所以硬件必须对每个页面具备选择性的禁用 chche. 增加了复杂性
  • 在内存映射机器上, 具有单独的内存总线会使 I/O 设备没有办法查看内存地址,因为内存地址旁路到内存总线上, 没有办法响应.

0.4. DMA(直接存储器存取, Direct Memory Access)

独立于 CPU 访问系统总线

IO-hardware-2

0.4.1. 工作原理

IO-hardware-3

也就是不用浪费 CPU 处理缓冲区到内存的时间, 相当于另有一个” CPU “ 专门处理 磁盘 到 内存 的 I/O

0.4.2. 对 CPU 的延迟

0.4.2.1. 周期窃取(Cycle Stealing)

注意 上面的操作是字模式传送, 在 DMA 请求传送一个字并且得到这个字时, CPU 不能使用总线,必须等待.

0.4.2.2. 突发模式(burst mode)

上面是字传输模式, 对于块模式下的传送, DMA 会发起一连串的传送,然后才释放总线. 这比周期窃取效率更高.

上面 的模式是飞越模式(fly-by mode), 即 DMA 控制器直接通知设备控制器将数据传送到 主存, 只请求一次总线

某些 DMA 使用其他模式. 让设备控制器将字发送到 DMA, 然后 DMA 再 请求总线将数据发送到其他地方(其他设备, 主存…), 这样会多消耗一个总线周期, 但是更加灵活: 可以 设备->设备, 内存->内存(内存读, 然后 内存写)

不使用 DMA 的考虑:

  • CPU 比 DMA 快得多,当限制因素不是 I/O 设备的读写速度时,没必要使用 DMA
  • 去除 DMA 而用 CPU 使用软件做所有工作可以节省硬件的开销

0.5. 中断

当一个 I/O 设备完成它的工作后,它就产生一个中断, 通过在分配给它的一条总线信号线上置起信号.
中断

如果有多个中断请求, 按优先级, 如果还没有被处理, 设备一直发出中断知道得到 CPU 服务

中断控制器通过在地址先上放置一个数字(中断向量 interrupt vector)表明哪个设备需要关注,同时向 CPU 发出中断

中断信号导致 CPU 停止当前工作, 并处理其他事情. 根据中断向量跳转到需要的中断服务程序

0.5.1. 问题

开始中断服务之前, 硬件需要保存信息

0.5.1.1. 哪些信号需要保存?

至少程序计数器, 至多可见的寄存器, 一些内部寄存器…

0.5.1.2. 保存在哪里?

  • 如果放在内部寄存器, 那么中断控制器之后无法得到应答,知道所有可能的相关信息被读出,以免第二个中断重写内部寄存器保存状态. 这样在中断被禁止时将导致长时间的死机,并可能丢失中断和数据
  • 如果在堆栈中, 使用谁的堆栈?

    • 如果使用当前堆栈, 可能是用户进程的,堆栈指针可能是不合法的.
    • 可能指向一个页面的末端, 若干次内存写之后, 可能超出页面发生页面故障. 那么在何处保存状态以处理页面故障?
    • 如果用内核堆栈. 切换到和心态可能要求改变 MMU 上下文, 并且可能使 cache 和 TLB 的大部分失效. 静态地或动态地重新状态所有东西将增加处理一个中断的时间,因而浪费 CPU 的时间

      0.5.1.3. 谁来保存?

      对谁可见就谁来保存

0.5.1.4. 考虑流水线,超标量(内部并行)

在流水线满的时候,如果出现一个中断, 由于许多指令处于不同的正在执行的截断. 程序计数器可能无法正确反应已经执行的指令和未执行之间的边界.
在超标量机器上, 指令可能分解成微操作, 为操作可能乱序执行

  • 精确中断(precise interrupt):将机器留在一个明确状态

IO-hardware-4

IO-hardware-5

  • 不精确中断(imprecise interrupt)

不满足上面的条件

文章目录
  1. 1. 0.1. I/O 设备
    1. 1.1. 0.1.1. 块设备(block device)
    2. 1.2. 0.1.2. 字符设备(character device)
  2. 2. 0.2. 设备控制器(device controller / adapter)
  3. 3. 0.3. 内存映射 I/O
    1. 3.1. 0.3.1. 方案
    2. 3.2. 0.3.2. 工作原理
    3. 3.3. 0.3.3. 优点
    4. 3.4. 0.3.4. 缺点
  4. 4. 0.4. DMA(直接存储器存取, Direct Memory Access)
    1. 4.1. 0.4.1. 工作原理
    2. 4.2. 0.4.2. 对 CPU 的延迟
      1. 4.2.1. 0.4.2.1. 周期窃取(Cycle Stealing)
      2. 4.2.2. 0.4.2.2. 突发模式(burst mode)
  5. 5. 0.5. 中断
    1. 5.1. 0.5.1. 问题
      1. 5.1.1. 0.5.1.1. 哪些信号需要保存?
      2. 5.1.2. 0.5.1.2. 保存在哪里?
      3. 5.1.3. 0.5.1.3. 谁来保存?
      4. 5.1.4. 0.5.1.4. 考虑流水线,超标量(内部并行)