孤独的 CPU

CPU 只是 “无情的指令执行机器”

  • 取指令、译码、执行

Altair-8800 (1975), with Intel 8080A; 256B 板卡 RAM

(你需要在面板上拨动开关输入执行指令的起始地址)

CPU 如何指挥 “外部” 的设备?

需求:能否实现核弹发射箱?

  • 如何使计算机能感知外部状态 (眼睛、耳朵)、对外实施动作 (手)?
    • 计算机系统:计算驱动的输入/输出

答案:一根线

核弹发射箱

  • 把钥匙的状态写入 flip/flop (0/1),并配指示灯
  • 把按钮的状态写入 flip/flop (0/1)
  • CPU 提供一条指令
    • reg_read(x)
    • 检测到按钮和钥匙的装填,reg_write(launch, 1)
  • 检测到 launch 寄存器,即发射核弹

(这个可以做数字电路课的选做实验)

I/O 设备:“计算” 和 “物理世界” 之间的桥梁

I/O 设备 (CPU 视角):“一个能与 CPU 交换数据的接口/控制器

说人话

  • 就是 “几组约定好功能的线” (RTFM)
    • 通过握手信号从线上读出/写入数据
  • 每一组线有自己的地址
    • CPU 可以直接使用指令 (in/out/MMIO) 和设备交换数据
    • (CPU 完全不管设备具体是如何实现的)

例子 (1): 串口 (UART)

“COM1”; putch() 的实现

#define COM1 0x3f8

static int uart_init() {
  outb(COM1 + 2, 0);   // 控制器相关细节
  outb(COM1 + 3, 0x80);
  outb(COM1 + 0, 115200 / 9600);
  ...
}

static void uart_tx(AM_UART_TX_T *send) {
  outb(COM1, send->data);
}

static void uart_rx(AM_UART_RX_T *recv) {
  recv->data = (inb(COM1 + 5) & 0x1) ? inb(COM1) : -1;
}

例子 (2): 键盘控制器

IBM PC/AT 8042 PS/2 (Keyboard) Controller

  • “硬编码” 到两个 I/O port: 0x60 (data), 0x64 (status/command)
Command Byte Use 说明
0xED LED 灯控 ScrollLock/NumLock/CapsLock
0xF3 设置重复速度 30Hz - 2Hz; Delay: 250 - 1000ms
0xF4/0xF5 打开/关闭 N/A
0xFE 重新发送 N/A
0xFF RESET N/A

参考 AbstractMachine 的键盘部分实现

例子 (3): 磁盘控制器

ATA (Advanced Technology Attachment)

  • IDE (Integrated Drive Electronics) 接口磁盘
    • primary: 0x1f0 - 0x1f7; secondary: 0x170 - 0x177
void readsect(void *dst, int sect) {
  waitdisk();
  out_byte(0x1f2, 1);          // sector count (1)
  out_byte(0x1f3, sect);       // sector
  out_byte(0x1f4, sect >> 8);  // cylinder (low)
  out_byte(0x1f5, sect >> 16); // cylinder (high)
  out_byte(0x1f6, (sect >> 24) | 0xe0); // drive
  out_byte(0x1f7, 0x20);       // command (write)
  waitdisk();
  for (int i = 0; i < SECTSIZE / 4; i ++)
    ((uint32_t *)dst)[i] = in_long(0x1f0); // data
}

例子 (4): 打印机

打印机:将字节流描述的文字/图形打印到纸张上

  • 可简单 (打字机)
  • 可复杂 (编程语言描述的图形)
    • 高清全页图片的传输是很大的挑战

例子:PostScript (1984)

  • 一种描述页面布局的 domain-specific language
    • 类似于汇编语言
    • 可以用 “编译器” (例如 latex) 创建高质量的文稿
  • PDF 是它的 superset (page.ps)
    • 打印机是另一个带 CPU 的设备

我们的计算机系统里有什么设备?

厂商必须告诉操作系统:哪个设备在什么地址

  • 0x1f2 - ATA 控制器
  • 0x3f8 - COM1

Linux 有一个 Device Tree 机制

  • qemu-system-aarch64 -machine virt -cpu cortex-a57 -machine dumpdtb=dtb.dtb
  • 可以通过 dtc 查看厂商给出的配置