Skip to content

1. 设备及其基本工作方式

  • 设备也是数字电路: 设备(如键盘控制器、VGA 控制器)本质上也是数字电路,就像 CPU 一样。它们接收数字信号(命令字)并按照信号的含义工作。

  • 设备的工作方式: 设备拥有自己的状态寄存器和功能部件,类似于 CPU 的寄存器和运算器。设备接收“命令字”(设备指令),进行译码和执行,从而完成特定的功能。

  • CPU 访问设备的目的: CPU 访问设备是为了进行输入输出 (I/O),包括:

    • 读取数据 (输入): 从设备获取数据,如从键盘控制器读取按键扫描码。
    • 写入数据 (输出): 向设备发送数据,如向显存写入颜色信息。
    • 控制状态: 查询或设置设备的状态,如获取键盘状态、设置 VGA 分辨率。
    • CPU 与设备的接口:设备寄存器
      CPU 通过访问设备内部的 寄存器 来与设备进行交互。设备寄存器充当 CPU 和设备之间的接口。

    • 数据寄存器: 用于数据输入输出。

    • 状态寄存器: 用于读取设备状态。
    • 命令寄存器: 用于写入命令字,控制设备行为.
    • I/O 编址方式:
      CPU 需要一种方式来寻址和访问设备寄存器,这就是 I/O 编址。常见的编址方式有两种:

    • 端口 I/O (Port-mapped I/O):

      • 专用 I/O 指令: CPU 使用专门的 I/O 指令 (in, out in x86) 访问设备.

      • 端口号: 设备寄存器的地址称为 端口号.

      • 端口号分配: IBM PC 兼容机对常见设备端口号有专门规定.

      • x86 inout 指令示例:

        代码段

        movl $0x41, %al ; 将数据 0x41 放入 AL 寄存器 movl $0x3f8, %edx ; 将端口号 0x3f8 放入 EDX 寄存器 outb %al, (%dx) ; 将 AL 寄存器的数据输出到端口 0x3f8

        这段代码将数据 0x41 (字符 'A' 的 ASCII 码) 发送到 0x3f8 端口(通常是串口的端口)。CPU 只负责数据传输,不关心设备如何处理数据.

      • 局限性:I/O 地址空间有限
        端口 I/O 的 I/O 地址空间大小在指令集设计时就已固定,随着设备增多和功能复杂化,端口 I/O 的地址空间逐渐受限.

    • 内存映射 I/O (Memory-mapped I/O, MMIO):

      • 物理内存地址编址: 使用 物理内存地址 来给设备寄存器编号.

      • 内存访问重定向: 将一部分物理内存地址的访问 重定向 到 I/O 地址空间,CPU 访问这些内存地址时,实际上访问的是 I/O 设备.

      • 普通访存指令访问设备: CPU 可以使用 普通的访存指令 (如 mov, load, store) 来访问设备寄存器.

      • 优点:I/O 地址空间无限
        MMIO 利用物理内存地址空间进行编址,物理内存地址空间和 CPU 位宽不断增长,MMIO 不受 I/O 地址空间大小的限制.

      • 缺点:无法直接访问被映射的物理内存
        被映射到 I/O 地址空间的物理内存无法通过正常方式直接访问,但现代 64 位计算机物理地址空间巨大,划出一部分用于 MMIO 几乎没有影响.

      • 现代计算机主流:
        MMIO 成为现代计算机主流 I/O 编址方式,RISC 架构 (MIPS, RISC-V) 只提供 MMIO,PCI-e、网卡、x86 APIC 等主流设备也支持 MMIO.

      • NEMU 中的 MMIO 示例:VGA 显存
        NEMU 中物理地址区间 [0xa1000000, 0xa1800000) 被映射到 VGA 显存.

        C

        memset((void *)0xa1000000, 0, SCR_SIZE); // 清屏操作

        这段 C 代码使用 memset 函数,直接向显存地址 0xa1000000 开始的内存区域写入数据,实现清屏操作。程序员可以将 I/O 设备像普通内存一样访问,简化了驱动开发.

2. 状态机模型下的输入输出

  1. 设备的两部分:数字电路 (D) 和 模拟电路

    • 数字电路 (D): 设备状态
      设备内部也包含数字电路,其时序逻辑电路可以看作是设备数字电路部分的状态 D。计算机通过 端口 I/O 指令内存映射 I/O (MMIO) 访存指令 来访问和修改 D.

    • 模拟电路:连接物理世界
      设备还包含模拟电路,负责与物理世界交互。例如,键盘的模拟电路检测按键电容变化,并将按键信息写入键盘控制器的寄存器 (设备状态 D)。用户在物理世界中按键的动作,通过模拟电路影响设备状态 D.

    设备是计算机和物理世界的桥梁。

    状态机模型 | 状态机模型之外 S = <R, M> | D 计算机/程序 <----I/O指令----> 设备 <----模拟电路----> 物理世界 | |

  2. 扩展状态机模型:仅建模 I/O 指令行为

    由于设备行为多样且受物理世界影响,对设备状态和行为进行精确建模非常困难。因此,状态机模型扩展 不将设备状态 D 加入到 S 中,而是 仅对输入输出相关指令的行为进行建模

    • 普通指令执行:
      状态机按照 TRM 模型 进行状态转移 (基于指令改变寄存器 R 和内存 M 的值).
    • 设备输出指令 (如 out, MMIO 写):
      • 状态机 仅更新 PC (程序计数器)寄存器 R 和内存 M 的状态保持不变.
      • 设备状态 D 和物理世界会发生相应变化 (例如,向串口输出字符,VGA 显存写入像素信息).
    • 设备输入指令 (如 in, MMIO 读):
      • 状态机的转移会 “分叉”,变成 不确定的状态转移.
      • 状态机转移到哪个新状态 取决于执行指令时设备的状态 D.
    • 设备输入指令的状态转移“分叉”示例 (键盘控制器 in addr, r)

    假设程序执行指令 in addr, r,从键盘控制器地址 addr 读取数据到 CPU 寄存器 r.

    • 不确定性:
      寄存器 r 的值 不确定,取决于用户是否按键以及按了什么键.
      • r 可能是 0x01: 读到 "按下扫描码为 1 的按键" 的信息.
      • r 可能是 0x81: 读到 "释放扫描码为 1 的按键" 的信息.
      • r 可能是 0x00: 没有任何按键信息.
    • 影响后续程序:
      不确定的状态转移会影响后续程序运行。例如,游戏程序会根据读取的按键信息来决定游戏逻辑.
    • 游戏响应逻辑:普通计算指令
      游戏如何响应按键输入,仍然是通过 TRM 模型中的普通计算指令 实现,与输入输出本身无关.

    总结:
    从状态机微观视角来看,设备的输入输出都是通过 CPU 寄存器 进行数据交互的。输入输出对程序的影响体现在 输入指令执行时会发生一次不能提前确定的状态转移。这基本上就是程序眼中输入输出的全部.

3. 通过内存进行数据交互的输入输出:DMA

  • S = 交互:
    端口 I/O 和内存映射 I/O 都是通过 寄存器 R 进行数据交互的.
  • 通过内存 M 交互:DMA (Direct Memory Access)
    存在通过 内存 M 进行数据交互的 I/O 方式,称为 DMA (Direct Memory Access).
  • DMA 的优势:高性能
    DMA 通常用于高性能设备,可以 直接在设备和内存之间传输数据,无需 CPU 寄存器中转,提高数据传输效率.