I/O 设备分类与 I/O 控制器:硬件如何与 CPU 对话
引言
你敲击键盘,字符出现;点击保存,数据写入磁盘。
CPU 并不是直接跟键盘或磁盘"说话"的——中间隔着 I/O 控制器和 UNIX 提供的统一文件接口。本文拆解 I/O 设备分类体系与控制器的硬件架构,并为有工程背景的读者揭示底层设计在真实系统中的痕迹。
📌 核心要点
- I/O 设备按使用特性(人机交互/存储/网络)、传输速率(低/中/高)和信息>交换单位(块/字符)三个维度分类 [共识]
- 块设备可寻址、以块为单位传输;字符设备不可寻址、以字符为单位、常采>用中断驱动——408 选择题核心辨析点 [引用:王道 5.1_1]
- I/O 控制器通过数据寄存器、控制寄存器、状态寄存器,经 CPU 接口、I/O 逻辑、设备接口三大模块充当"翻译官" [引用:王道 5.1_2]
- 内存映像 I/O 将寄存器编址纳入内存地址空间、复用访存指令;寄存器独立编址需专用 I/O 指令
什么是 I/O 设备?——UNIX 的"一切皆文件"哲学
I/O 设备(Input/Output Device)将数据输入计算机或接收计算机的输出,属于裸机(Bare Machine)的组成部分。UNIX 将其抽象为特殊文件(Special File)——操作键盘等同于读文件(Read),向显示器输出等同于写文件(Write),用户态程序无需关心设备的具体型号或协议 [经验]。
需要记牢一对定义:Write(写) = 向外部设备写出数据(CPU → 设备),Read(读) = 从外部设备读入数据(设备 → CPU)。方向判断的视角始终是 CPU [引用:王道 5.1_1]。鼠标、键盘属于输入型,显示器属于输出型,移动硬盘可输入可输出。
常见混淆:I/O 设备是物理硬件(键盘机械轴体、磁盘磁头),设备驱动程序(Device Driver)是内核中的软件。前者在硬件层,后者在软件层——分清这一点,学习 I/O 软件层次结构时才不会概念错位 [共识]。
I/O 设备的三种分类维度——怎么给设备"贴标签"?
同一块键盘,从不同角度可贴上不同标签。三个分类维度反映的是操作系统设计者管理设备的真实决策逻辑。
按使用特性:人机交互类(鼠标、键盘、打印机)速率较低;存储设备(移动硬盘、光盘)以块传输,追求高吞吐;网络通信设备(网卡、调制解调器)关注延迟与可靠性 [共识]。这种分类影响调度策略——不会用磁盘的电梯算法去管键盘。
按传输速率:低速(几个 ~ 几百 B/s,如键盘);中速(数千 ~ 上万 B/s,如打印机);高速(数千 B/s ~ 千兆 B/s,如磁盘、网卡)。速率量级决定 I/O 控制方式:低速用程序直接控制,高速需要 DMA(直接存储器访问,Direct Memory Access)。
按信息交换单位——408 考研最重要的分类维度 [共识]。块设备(Block Device)以块为单位,可寻址,CPU 可随机访问任意块,磁盘即典型。字符设备(Character Device)以字符为单位,不可寻址,常采用中断驱动,如键盘、串口。
块设备 vs 字符设备——408 考研必考辨析
| 对比维度 | 块设备 | 字符设备 |
|---|---|---|
| 寻址能力 | 可寻址,随机读写任一块 | 不可寻址,顺序访问 |
| 传输单位 | 以"块"为单位(512B、4KB) | 以字符/字节为单位 |
| 传输速率 | 较高 | 较低 |
| 典型控制方式 | 常采用 DMA | 常采用中断驱动 |
注意:两个分类维度不互斥。磁盘从信息交换单位看是块设备,从使用特性看是存储设备。不要误以为块设备的本质是"按块传输"——本质是可寻址。
I/O 控制器的硬件构成——CPU 的"翻译官"
CPU 读得懂寄存器里的 0 和 1,但读不懂键盘的物理行程和磁头偏转角度。因此 CPU 无法直接控制 I/O 设备的机械部件,需要 I/O 控制器(I/O Controller,又称 Device Controller)作为中介。
I/O 设备由机械部件(磁头臂、按键弹簧等物理机构)和电子部件(I/O 控制器——主板扩充槽上的印刷电路板)组成。控制器内部三个逻辑模块:
- CPU 与控制器接口(Host Interface):通过数据线、地址线、控制线与 CPU 相连。
- I/O 逻辑(I/O Logic):负责地址译码(判断访问哪个寄存器)和命令识别(将 I/O 指令转为设备控制信号)。
- 控制器与设备接口(Device Interface):一个控制器可通过多接口连多个设备。例如一块 SATA 控制器挂载多块硬盘——408 考点:“一个 I/O 控制器可能对应多个设备” 。
I/O 控制器的寄存器
寄存器是控制器中 CPU 直接访问的存储单元:
- 数据寄存器(Data Register):暂存 CPU 与设备间的数据。输入时设备放入、CPU 读取;输出时 CPU 写入、设备取走 。
- 控制寄存器(Control Register):存放 CPU 的命令和参数。如"读磁盘第 100 扇区"——命令码和扇区号写入此寄存器。
- 状态寄存器(Status Register):记录设备状态。典型约定 1=空闲(Idle),0=忙碌(Busy)。CPU 发命令前须先读它。
- 地址译码:非严格意义的寄存器,是 I/O 逻辑功能——将地址信号译码以定位目标寄存器。各控制/状态寄存器可有多个实例对应不同设备 。
分设四种的原因:数据双向暂存,命令 CPU 单向下发,状态设备单向上报——方向时序不同,合并会导致读写冲突 。
内存映像 I/O vs 寄存器独立编址——两种寄存器寻址方案
CPU 如何定位控制器中的寄存器?两种方案。
内存映像 I/O(Memory-Mapped I/O):将寄存器地址映射到内存地址空间。CPU 用普通访存指令(如 MOV)即可操作控制器。优点是简化了指令,可以采用对内存进行操作的指令来对控制器进行操作。代价是寄存器挤占内存地址空间。
寄存器独立编址(Port-Mapped I/O):寄存器使用独立地址空间。CPU 需专用 I/O 指令(如 x86 IN/OUT),指令要指明寄存器地址和控制器编号 。优点是不占内存地址空间,代价是指令集复杂度增加。
两种方案的工程权衡
| 对比维度 | 内存映像 I/O | 寄存器独立编址 |
|---|---|---|
| 指令复杂度 | 低,复用访存指令 | 高,需专用 I/O 指令 |
| 地址空间利用率 | 寄存器挤占内存地址 | 独立空间,互不干扰 |
| 硬件成本 | 需地址区分逻辑 | 需额外 I/O 指令译码电路 |
| 典型架构 | ARM、MIPS | x86(IN/OUT 指令) |
工程中两种方案并存 [经验]。Linux 通过 /proc/iomem 暴露内存映像 I/O 的地址映射,/proc/ioports 暴露独立编址的端口范围——可直观看到两类编址的共存。
考点串联——从硬件到软件的全景视角
I/O 设备分类和控制器属于硬件层。往上是本系列第二篇的四种 I/O 控制方式(程序直接控制、中断驱动、DMA、通道控制),再往上是第三篇 I/O 软件层次结构(中断处理程序→设备驱动→设备独立性软件→用户层 I/O)。之前讲的系统调用与中断机制是前置知识——用户态通过系统调用进内核,内核通过中断获知 I/O 完成。
本章后续还覆盖 SPOOLing 技术(第四篇,独占设备虚拟化为共享)和设备分配与缓冲区管理(第五篇,设备争用与速率匹配)。
FAQ
Q1: 块设备和字符设备的根本区别是什么?最容易混淆的点在哪?
根本区别是寻址能力。块设备每个数据块有独立地址、可随机访问;字符设备不可寻址、按字符流顺序进出。最易混淆:把"块设备"等同于"按块传输"——本质是可寻址。
Q2: I/O 控制器为什么需要四类不同的寄存器?
数据、命令、状态是三类方向不同、时序不同的信息。数据双向流动,命令 CPU 单向下发,状态设备单向上报。合并会导致读写冲突,分设是清晰的职责分离。
Q3: 内存映像 I/O 用得更多,还是寄存器独立编址?
两者并存。x86 保留独立编址(IN/OUT),现代设备越来越多用内存映像 I/O(PCIe BAR 机制)。ARM 从设计之初仅支持内存映像 I/O。取决于 CPU 架构哲学与兼容性约束。
Q4: 状态寄存器的 1/0 含义是统一标准吗?
没有强制国际标准。主流约定 1=空闲、0=忙碌,特定设备可能有相反定义。驱动必须知道具体控制器的寄存器定义——这正是驱动必须针对具体硬件编写的原因。
总结
I/O 设备的三维分类体系和 I/O 控制器的寄存器架构构成了操作系统 I/O 管理的硬件基础。理解这些不是为了背诵,而是为后续掌握"为什么不同设备适用不同控制方式"——硬件特性决定了软件方案的选择空间。
📚 延伸阅读
- Linux Kernel Documentation: Memory-Mapped I/O
- 本系列第二篇:四种 I/O 控制方式(程序直接控制 / 中断驱动 / DMA / 通道控制)—— 即将发布
- 本系列第三篇:I/O 软件层次结构 —— 即将发布
- 本系列第四篇:SPOOLing 技术 —— 即将发布
- 本系列第五篇:设备分配与缓冲区管理 —— 即将发布
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)