I/O 设备
低频考点,对于本节重点掌握 I/O 软件层次的概念,I/O 控制方式的部分建议和计算机组成原理中的 I/O 系统 共同学习。
I/O 接口类型
根据设备类型的不同,我们将 I/O 接口 分为三种类型:
- 块设备:
块设备(Block Device)是计算机中一类以 固定大小的数据块 为单位进行数据读写的 I/O 设备,通常用于存储和检索大量数据。它们 支持随机访问,意味着可以直接定位到任意数据块,而无需按顺序读取。
典型例子包括机械硬盘(HDD)、固态硬盘(SSD)和 USB 闪存盘。块设备 的 数据传输速率较高,但涉及复杂的控制器和协议(如 SATA 或 NVMe),因此在操作系统中通常由专门的驱动程序管理。
- 字符设备:
字符设备是另一类 I/O 设备,以 连续的字符流 形式进行数据传输,不支持随机访问,也不依赖数据块的概念。它们通常用于与硬件设备交互,如 键盘、鼠标、串口终端 或 打印机。字符设备的数据流是顺序的,适合实时或低速数据传输场景。
例如,键盘输入的字符流直接发送到系统,而无需缓存整个数据块。字符设备在操作系统中通常通过简单的驱动程序管理,且不涉及文件系统,适合处理非结构化数据。
- 网络设备:
网络设备是专门用于计算机网络通信的 I/O 设备,负责在计算机与网络之间传输 数据包。它们包括网络适配器 和调制解调器等设备。网络设备 以数据包为单位 工作,通常通过协议栈(如 TCP/IP) 处理数据,支持点对点或广播通信。
与块设备和字符设备不同,网络设备更注重 数据的高速传输 和 实时性,常涉及中断机制和 DMA(直接内存访问)来提高效率。操作系统通过网络驱动程序管理这些设备,以实现网络连接和数据交换。
I/O 接口、端口与控制器
不要把“设备”“接口”和“端口”混为一谈。CPU 通常不直接操作盘片、键盘按键或网线,而是通过 设备控制器 暴露的寄存器同设备通信;这些 CPU 可见的寄存器地址构成 I/O 端口。端口既可能采用独立 I/O 编址,也可能映射到内存地址空间;编址和总线细节与组成原理中的 I/O 系统 对应学习。
| 控制器提供的对象 | CPU / 驱动用它做什么 | 例子 |
|---|---|---|
| 数据寄存器 | 读取输入数据或写入输出数据 | 读键盘扫描码、向串口发送字节 |
| 状态寄存器 | 查询就绪、忙、完成或出错状态 | 检查磁盘控制器是否已完成命令 |
| 控制寄存器 | 下达命令、设置方向和中断使能 | 启动读盘、复位设备、配置 DMA |
控制器把寄存器级命令转换为具体设备动作;设备驱动程序正是负责这层转换的软件。
I/O 控制方式
在计算机系统中,I/O(输入/输出)控制方式决定了 CPU 与外设之间如何协作完成数据传输。主要有三种方式,每种方式在性能、复杂度与使用场景上各有不同:
- 程序查询方式: 又称“轮询方式”,CPU 主动不断地检查外设状态是否准备好。在设备较少、交互不频繁的场景下实现简单,但会占用大量 CPU 时间,效率较低。
- 程序中断方式: 外设准备就绪后向 CPU 发出中断信号,CPU 暂停当前任务处理 I/O 操作,相比轮询更高效。适用于响应及时性要求较高的系统,能够显著降低 CPU 的无效等待。
- DMA 方式:CPU 先设置主存地址、传输方向和数据量并启动 DMA 控制器;DMA 控制器在设备与主存之间成批传输,完成或出错后再中断 CPU。CPU 不参与每个字的数据搬运,但总线仲裁和最终处理仍需系统配合。
| 方式 | 谁搬运数据 | CPU 在等待期间 | CPU 再次介入的时机 | 易混点 |
|---|---|---|---|---|
| 程序查询 | CPU 经数据寄存器逐次搬运 | 反复读状态寄存器,忙等 | 每次查询发现就绪后 | “简单”不等于 CPU 空闲 |
| 程序中断 | 通常仍由 CPU 执行数据传送 | 可运行其他任务 | 设备用中断报告就绪或完成 | 中断减少的是等待,不是自动取消逐字搬运 |
| DMA | DMA 控制器在设备与主存间成批传送 | 可运行其他任务,但要参与总线仲裁 | 设置 DMA 后以及批传送完成/出错时 | DMA 仍需要 CPU 初始化和最终中断处理 |
I/O 软件层次
I/O 软件层次是计算机系统中用于管理和协调输入输出操作的软件架构,从用户应用程序到硬件设备,分为多个层次,每一层负责特定的功能,确保高效、可靠的 I/O 操作。
| 层次 | 主要解决的问题 | 向下一层交付的内容 |
|---|---|---|
| 用户层 I/O 软件 | 让应用以文件、流或库函数发起请求 | 系统调用及其参数 |
| 设备独立性软件 | 统一命名、保护、缓冲、分配与错误处理 | 与设备型号无关的通用请求 |
| 设备驱动程序 | 将通用请求翻译成某一控制器的命令 | 寄存器操作、DMA 描述符或设备队列项 |
| 中断处理程序 | 快速接收完成/异常事件并唤醒后续工作 | 完成状态、已传输数量或错误码 |
| 硬件 | 真正执行机械、电气或网络传输 | 数据与设备状态 |
用户层 I/O 软件
用户层 I/O 软件是 I/O 软件体系结构的最上层,直接与用户应用程序交互,提供标准化的接口 以便程序能够访问 I/O 设备。
它主要包括库函数和系统调用接口,例如 C 语言中的 stdio 库(提供 printf、scanf 等函数)或 POSIX 系统调用(如 read、write)。这些软件封装了底层的复杂性,让用户程序无需关心具体设备细节即可进行输入输出操作。
应用程序接口
应用程序通常按“打开 → 读/写 → 关闭”使用 I/O:open 根据逻辑名称取得一个句柄或文件描述符;read / write 提交数据传输请求;close 释放与该请求相关的内核对象。对需要特殊控制的设备,还可通过设备控制命令设置工作模式。接口统一的是调用形式与语义,不是所有设备的传输单位和时延:读块设备、收网络包、等键盘字符都可能经过同一类系统调用,却由不同驱动完成。
设备独立性软件
设备独立性软件位于用户层和设备驱动程序之间,负责屏蔽不同 I/O 设备的硬件差异,提供统一的接口供上层软件使用。它 实现了设备无关的功能,例如文件系统管理、设备命名、缓冲管理和错误处理。
例如,操作系统通过设备独立性软件将不同类型的存储设备(如硬盘、USB 驱动器)抽象为统一的文件系统接口,程序只需操作文件路径而无需关心底层设备类型。此外,它还管理设备的分配与释放,避免多个进程同时访问同一设备导致冲突。设备独立性软件的核心作用是提高系统的模块化和可移植性。
设备驱动程序
设备驱动程序是 I/O 软件层次中直接 与具体硬件设备交互 的部分,每个设备驱动程序针对特定类型的硬件设备设计,负责将设备独立性软件的通用命令转换为设备能够理解的特定指令。
例如,一个硬盘驱动程序会处理扇区读写命令,而一个打印机驱动程序可能发送控制字符序列。驱动程序通常由设备制造商提供,运行在操作系统的内核态,能够直接访问设备寄存器和端口。由于硬件设备的多样性,驱动程序需要处理设备初始化、数据传输和错误恢复等任务,是连接软件与硬件的关键桥梁。
中断处理程序
中断处理程序是 I/O 软件层次中 专门处理硬件中断 的部分,当设备完成操作或发生事件(如数据到达、错误发生)时,硬件会触发中断信号,中断处理程序迅速响应以处理这些事件。它运行在极低的层次,通常以极高的优先级执行,负责保存中断现场、处理设备状态、通知上层软件或触发后续操作。
例如,当网卡接收到 数据包 时,中断处理程序会将数据移到内存并通知网络协议栈。由于中断处理需要极快的响应速度,代码通常高度优化且精简,尽量减少处理时间,以避免影响系统性能。
硬件
硬件是 I/O 软件层次的最底层,直接负责 执行物理 I/O 操作,包括实际的设备控制器、寄存器、端口和数据传输通道。硬件层由具体的 I/O 设备(如硬盘、键盘、网络适配器)及其控制器组成,控制器通过寄存器和端口接收驱动程序的指令,执行数据读写或状态查询等操作。
例如,硬盘控制器通过 DMA(直接内存访问)将数据直接传输到内存,而网卡通过硬件队列处理 数据包。硬件层的性能和特性直接决定了 I/O 操作的效率,软件层的所有操作最终都依赖硬件的物理实现。
一次读请求如何往返各层
以阻塞式 read 为例,请求向下传递到控制器,完成事件再由中断向上反馈。被阻塞的进程不是“在 CPU 上等磁盘”,而是由内核挂入等待队列;完成中断到来后,它才转为就绪态并等待调度。
一次 read 请求如何穿过 I/O 软件层次再返回
点击各步骤,查看请求如何向下抵达控制器,以及完成中断如何把等待进程重新放回就绪队列。
当前查看:应用发起 read。用户程序经库函数或系统调用提交逻辑设备 / 文件句柄、缓冲区地址和读取长度。