目录

  • I/O 系统概述:性能、功能与操作系统角色
  • I/O 设备模型与磁盘存储器
  • 磁盘性能、DMA 读盘流程与 RAID
  • 总线、系统互连与 I/O 接口
  • I/O 端口与设备寻址
  • I/O 传输方式:轮询、中断、DMA
  • I/O 子系统的软件层次与驱动程序
  • 总结与对比

1 I/O 系统概述

1.1 I/O 系统的性能指标

I/O 系统讨论的是计算机怎样与外部世界交换信息。这里的“外部世界”既包括键盘、鼠标、显示器、打印机等人机交互设备,也包括磁盘、网卡、声卡、A/D、D/A 等机器可读设备。衡量 I/O 系统时,需要关注两个核心性能指标:吞吐率响应时间

吞吐率(Throughput, I/O bandwidth)表示单位时间内系统完成了多少数据传输,或单位时间内完成了多少次 I/O 操作。视频播放、文件服务器、Web 服务器等场景很重视吞吐率,因为系统要持续不断地搬运大量数据。

响应时间(Response time, latency)表示一次 I/O 请求从发出到完成所经历的时间。事务处理系统、交互式终端、银行存取款等更关心响应时间,因为用户感受到的是“等了多久”。

这两个指标不是完全独立的。某些设计提高吞吐率时,可能会牺牲单个请求的等待时间;而过分追求短延迟,也可能降低批量传输效率。需要能根据应用场景判断主要矛盾:多媒体连续流更看重带宽,交互事务更看重延迟,服务器通常两者都要兼顾。

1.2 I/O 系统的功能

输入/输出系统的基本功能是:解决各种形式信息在主机与外设之间的输入和输出问题。用户输入文字、图像、声音、视频,计算机处理后再输出显示、打印、声音或网络数据,这些都要依靠 I/O 系统完成。

为了实现这个功能,计算机系统必须解决一组具体问题:

  • 怎样在 CPU、主存和外设之间建立高效的信息传输通路。
  • 怎样把用户或程序提出的 I/O 请求转换成设备能够理解的命令。
  • 怎样给外设或 I/O 端口编址,使 CPU 能找到要访问的设备。
  • 怎样读取设备状态,判断设备是否就绪、是否出错。
  • I/O 硬件和操作系统如何协同完成数据传送。

因此,本章不是单纯讲“外设有哪些”,而是围绕三条主线展开:设备如何连接、设备如何寻址、数据如何传输

1.3 操作系统在 I/O 系统中的角色

需要强调:I/O 系统不能只靠用户程序直接控制,操作系统(Operating System, OS)在其中非常关键。原因主要有三个。

第一,I/O 设备具有共享性。多个进程可能同时请求同一块磁盘、同一台打印机或同一个网络接口,必须由 OS 统一调度和管理,否则会造成冲突。

第二,I/O 设备具有复杂性。不同设备的控制寄存器、状态位、命令格式、错误处理方式各不相同。用户程序不应该直接面对这些细节,而应通过 OS 提供的设备驱动程序访问设备。

第三,I/O 常常依赖中断机制。外设完成任务或发生异常时,会通过外部中断请求 CPU 处理。中断会导致处理器进入内核态,因此必须由操作系统中的中断服务程序处理。

OS 在 I/O 中的职责可以概括为:权限管理、设备驱动、I/O 中断处理、共享资源调度。从用户程序角度看,调用 printf()scanf()read()write() 等函数似乎很简单;但底层会经历用户态到内核态的切换、设备驱动程序执行、中断或 DMA 配合等一系列过程。

2 I/O 设备模型与磁盘存储器

2.1 外设分类

从交互方式看,外设可分为两类。

分类 含义 例子
人机交互设备 输入/输出信息是人可直接理解的 键盘、鼠标、扫描仪、显示器、打印机
机器可读设备 信息主要供机器处理,人不能直接读取 网络接口、Modem、D/A、A/D、磁盘、声音输入设备

从功能行为看,也可分为两类。

分类 主要作用 典型特点
输入/输出设备 完成信息输入或输出 多数是字符型设备,如键盘、打印机
外部存储设备 保存大量信息 多数按块传送,如磁盘、磁带、光盘

字符型设备通常一次传输一个字符或少量数据,速度较慢,适合轮询或中断方式。块设备通常一次传输一个扇区或一批数据,速度较快,适合 DMA 方式。

2.2 外部设备的通用模型

虽然外设种类很多,但 可以用一个统一抽象模型来描述。一个外设通常包含以下部分:

  • I/O 接口或电缆:在设备和主机之间传送控制、状态、数据信号。
  • 控制逻辑:根据主机给出的控制信息驱动设备动作,并检测设备状态。
  • 缓冲器:暂存主机与设备之间交换的数据,用来缓和速度不匹配。
  • 变换器:在计算机内部电信号与设备实际信号之间转换,例如磁盘中的磁-电、电-磁转换。
  • 设备本体与环境:真正执行输入、输出或存储动作的物理设备。

image-20260615141406098

所有设备传输的信息都可以抽象为三类:控制信息、状态信息、数据信息。CPU 向设备发控制命令,设备向 CPU 返回状态,双方再通过数据缓冲完成数据交换。后面讲 I/O 控制器、I/O 端口、轮询、中断和 DMA 时,本质上都围绕这三类信息展开。

2.3 磁盘的信息存储原理

磁盘是一种典型的外部存储设备。磁盘片表面被划分为许多同心圆,每个同心圆称为磁道;每个磁道又被划分为若干段,每段称为扇区。传统扇区大小长期为 512 字节,后来逐渐迁移到 4096 字节的高级格式化扇区。

磁盘读写依赖磁头与盘片表面的磁化状态。写入时,线圈通以不同方向的电流,使磁介质呈现不同磁化状态,用来表示二进制 \(0\)\(1\)。读取时,盘片旋转,磁化单元经过磁头,在磁头线圈中产生不同极性的感应电压,从而判断读出的比特。

磁盘地址通常由三部分组成:柱面号或磁道号、磁头号或盘面号、扇区号。读写一个扇区时,硬盘的大致流程是:

  1. 所有磁头同步寻道,移动到指定柱面。
  2. 选择目标磁头,即确定盘面。
  3. 等待目标扇区旋转到磁头下方。
  4. 对该扇区进行读或写。

这也解释了为什么磁盘访问比主存访问慢得多:磁盘不仅要传输数据,还要等待机械寻道和盘片旋转。

image-20260615141604611

2.4 如何提高磁盘容量

提高磁盘片容量的核心是提高信息记录密度。主要有两个方向:

  • 增加磁道数目,即提高磁道密度。
  • 增加扇区数目,即提高位密度,并采用可变扇区数。

image-20260615141706931

早期磁盘所有磁道扇区数相同,这会导致内圈与外圈记录密度不均。现代磁盘通常使不同磁道上的位密度更接近一致,因此外圈磁道可以放更多扇区,从而提高整个盘片容量。

3 磁盘性能、DMA 读盘流程与 RAID

3.1 磁盘平均存取时间

磁盘以扇区为单位读写。平均存取时间通常写为:

\[ T = \text{平均寻道时间} + \text{平均旋转等待时间} + \text{数据传输时间} \]

其中,平均寻道时间是磁头移动到指定磁道所需的平均时间,典型数量级约为 \(5\text{ ms}\)平均旋转等待时间是目标扇区转到磁头下方所需的平均时间,典型值约为 \(4\sim 6\text{ ms}\)数据传输时间通常远小于前两项,例如每扇区约 \(0.01\text{ ms}\),所以很多估算中可以近似忽略。

如果转速为 \(5400\text{ RPM}\),则每秒转数为:

\[ 5400 / 60 = 90\text{ RPS} \]

平均旋转等待时间约为半圈时间:

\[ \frac{0.5}{90}\text{ s} \approx 5.5\text{ ms} \]

假设寻道时间为 \(12\text{ ms}\),数据传输率为 \(4\text{ MB/s}\),扇区大小为 \(512\text{ B}\),控制器开销为 \(1\text{ ms}\),不考虑排队时间,则:

\[ \begin{aligned} T &= 12\text{ ms} + 5.5\text{ ms} + 0.1\text{ ms} + 1\text{ ms} \\ &= 18.6\text{ ms} \end{aligned} \]

如果实际寻道时间因访问局部性降为 \(12/3=4\text{ ms}\),总时间约为 \(10.6\text{ ms}\),此时旋转等待占比接近一半。因此,磁盘转速对机械硬盘性能非常重要

3.2 硬盘存储器的组成

硬盘存储器主要由三部分组成:

  • 磁记录介质:保存信息的盘片表面。
  • 磁盘驱动器:包含读写电路、读写转换开关、读写磁头、磁头定位伺服系统等。
  • 磁盘控制器:连接主机与磁盘驱动器,包含控制逻辑、时序电路、并串/串并转换、数据缓存器、控制寄存器和状态寄存器等。

磁盘控制器通常连接在 I/O 总线上,I/O 总线再通过桥接器与系统总线、存储器总线相连。由于磁盘按扇区成批读写,且数据量较大,所以磁盘通常采用 DMA(Direct Memory Access,直接存储器访问)方式在外设与主存之间传输数据。

3.3 读一个磁盘扇区的三步过程

读一个磁盘扇区的典型流程可以概括为:

  1. CPU 初始化磁盘控制器:CPU 向磁盘控制器写入读命令、磁盘逻辑块号、主存起始地址等参数,然后启动磁盘驱动器工作。
  2. 磁盘控制器读取扇区并 DMA 送主存:磁盘控制器找到相应扇区后,按 DMA 方式把数据直接送入主存,数据不经过 CPU 寄存器搬运。
  3. DMA 结束中断:传输完成后,磁盘控制器向 CPU 发出 DMA 结束中断请求,CPU 再执行后处理,例如检查状态、校验数据、唤醒等待进程。

这里要抓住一个关键点:CPU 负责发起和收尾,真正的大批量数据搬运由 DMA 控制器完成

3.4 RAID 的基本思想

RAID(Redundant Arrays of Inexpensive Disk,冗余磁盘阵列)的背景是:处理器和主存性能提升很快,而单个磁盘性能提升较慢,成为系统瓶颈。RAID 的基本思想是把多个独立磁盘组织成一个磁盘阵列,在操作系统看来像一个逻辑磁盘。

RAID 通过三种方式改善系统:

  • 提高容量:多个物理磁盘组合成更大的逻辑存储空间。
  • 提高性能:把数据分布在多个磁盘上,多盘并行读写,类似主存多体交叉。
  • 提高可靠性:用冗余校验或镜像技术,在磁盘损坏时恢复数据。

RAID 的共同特性是:一组物理磁盘在 OS 下被视为一个逻辑驱动器;数据分布在多个物理盘上;部分 RAID 级别使用冗余信息恢复故障数据。注意 RAID 0 不具备冗余,不满足第三个特性。

3.5 RAID 级别对比

RAID 级别 组织方式 优点 缺点或适用场景
RAID 0 数据条带化,无冗余 容量利用率高,读写性能好 无容错能力,适合非关键高速数据,如视频编辑
RAID 1 镜像盘,一对一冗余 可靠性高,恢复简单;读可选更快磁盘 成本高,写性能受较慢盘限制
RAID 2 小条区交叉,海明码校验 多盘并行,读性能高 校验盘数量与数据盘成比例,开销大,已基本不用
RAID 3 小条区交叉,单独奇偶校验盘 大容量连续 I/O 传输率高 小请求响应差,校验盘参与频繁
RAID 4 块级交叉,独立访问,单独校验盘 可同时响应多个读请求 写操作会使校验盘成为瓶颈
RAID 5 块级交叉,校验块分布在各盘 避免单校验盘瓶颈,成本和性能平衡,应用广 小写仍有校验更新开销
RAID 6 类似 RAID 5,但有两种冗余校验 可容忍双盘故障,可靠性更高 控制器复杂,写入速度较慢
RAID 7 在 RAID 基础上结合 Cache 传输率和响应速度提高 依赖缓存与控制器设计

3.5.1 RAID 4 的少量写损失

RAID 4 的典型要点是少量写的校验更新。设四个数据盘上的对应位为 \(X_0(i),X_1(i),X_2(i),X_3(i)\),校验位为:

\[ p(i)=X_3(i)\oplus X_2(i)\oplus X_1(i)\oplus X_0(i) \]

如果只把 \(X_0(i)\) 改成 \(X'_0(i)\),新校验位为:

\[ p'(i)=X_3(i)\oplus X_2(i)\oplus X_1(i)\oplus X'_0(i) \]

由于 \(X_0(i)\oplus X_0(i)=0\),可化简为:

\[ p'(i)=p(i)\oplus X_0(i)\oplus X'_0(i) \]

因此,更新一个小数据块时必须先读旧校验 \(p(i)\) 和旧数据 \(X_0(i)\),再写新数据 \(X'_0(i)\) 和新校验 \(p'(i)\)。也就是一次少量写包含两次读和两次写,这就是写损失。

3.6 固态硬盘 SSD

SSD(Solid State Disk,固态硬盘)不是磁表面存储器,而是基于 NAND 闪存的外部存储系统。它与 U 盘在原理上类似,但容量更大、性能更好。SSD 使用区块写入和擦除方式,读操作通常快于写操作;由于没有机械寻道和旋转等待,其内部传输速率远高于传统机械硬盘。

SSD 在接口规范和使用方法上与传统硬盘类似,可通过 USB、SATA、IDE 等标准磁盘接口与 I/O 总线互连。SSD 内部有闪存翻译层,把 CPU 发出的逻辑块读写请求转换为底层闪存物理操作。这个翻译层在功能上相当于磁盘控制器。

需要注意的是,闪存擦写次数有限,频繁写入会影响使用寿命。

4 总线、系统互连与 I/O 接口

4.1 总线的分类

总线是在计算机系统不同层次上提供部件连接和信息交换的通路。总线可分为三类:

总线类型 连接对象 特点与例子
芯片内总线 CPU 芯片内部部件 连接寄存器、ALU、指令部件等
系统总线 CPU、主存、I/O 控制器等主要部件 可为单总线或多总线结构
通信总线 主机与 I/O 设备之间,或计算机系统之间 多为电缆式总线,如 SCSI、RS-232、USB、PS/2

系统总线中,又可以区分处理器-存储器总线和 I/O 总线。处理器-存储器总线通常短而快,只需匹配 CPU 与内存;I/O 总线通常长而慢,要适应多种设备和标准接口。

4.2 系统总线的组成

系统总线通常由三组信号线构成:

  • 数据线(Data Bus):承载源部件与目的部件之间传送的信息,宽度决定一次能传送多少位。
  • 地址线(Address Bus):给出主存单元或 I/O 端口地址,宽度决定最大寻址空间。
  • 控制线(Control Bus):传递定时信号和命令信息,控制数据线和地址线的使用。

典型控制信号包括时钟、复位、总线请求、总线允许、中断请求、中断回答、存储器读写、I/O 读写、传输确认等。

有些总线没有单独地址线,而是让地址和数据共享同一组线,这称为地址/数据复用

image-20260615143203551

4.3 总线的基本概念

总线裁决解决的是多个设备同时想使用共享总线时,谁先使用的问题。早期共享总线需要裁决;现代高速互连多采用点对点传输,裁决问题相对弱化。

总线定时定义总线事务中每一步何时开始、何时结束。同步总线用统一时钟控制;异步总线用握手信号控制;半同步总线结合二者。

并行传输一次在多个数据线上传多位,但位与位之间要保持同步,高速时困难较大。串行传输一次只传一位,不需要多位之间同步,现代高速总线反而常采用串行方式。发展趋势是:点对点、异步、串行

4.4 总线性能指标

总线性能主要看三个指标:

  • 总线宽度:数据线条数,决定每次传输的信息位数。
  • 总线工作频率:单位时间内完成数据传送的次数。现代总线可能一个时钟周期传送 2 次或 4 次数据。
  • 总线带宽:最大数据传输率。

对于同步总线,带宽公式为:

\[ B = W \times F / N \]

其中 \(W\) 是总线宽度,\(F\) 是总线时钟频率,\(N\) 是完成一次数据传送所需的时钟周期数。\(F/N\) 实际上就是总线工作频率。

总线传送方式分为非突发传送突发传送。非突发传送每个事务都传地址,一个地址对应一次数据传送;突发传送先传一个地址,之后连续传多个数据,后续地址默认自动递增,适合成块数据传输。

4.5 处理器总线、存储器总线与 I/O 总线

早期 Intel 架构中,前端总线(Front Side Bus, FSB)位于 CPU 与北桥芯片之间,采用并行、同步传输。从 Pentium Pro 起,FSB 使用 quad pumped 技术,即一个总线时钟周期传送 4 次数据。例如工作频率 \(1333\text{ MT/s}\)、宽度 64 位时,带宽为:

\[ 1333\text{ MT/s}\times 8\text{ B}\approx 10.5\text{ GB/s} \]

QPI(Quick Path Interconnect)是高速点对点串行互连。它基于包交换,可用于 CPU 核之间、CPU 芯片之间、CPU 与 I/O Hub 之间互连。若 QPI 速度为 \(4.8\text{ GT/s}\),每次有效数据宽度约 \(2\text{ B}\),双向传输,则带宽为:

\[ 4.8\text{ G}\times 2\text{ B}\times 2 = 19.2\text{ GB/s} \]

I/O 总线为系统中各种 I/O 设备提供输入输出通道。主板扩展槽可看作 I/O 总线的物理形式。I/O 总线的发展大致为:

  • 第一代:ISA/EISA、VESA,已淘汰。
  • 第二代:PCI、AGP、PCI-X,逐渐淘汰。
  • 第三代:PCI-Express,串行总线,主流。

PCI-Express 使用链路(link)连接设备,每个链路含多条通路(lane)。PCIe \(\times n\) 表示有 \(n\) 条通路。以 PCIe 1.0 为例,每条通路发送和接收速率均为 \(2.5\text{ Gb/s}\),每个数据字节编码为 10 位传输,因此带宽为:

\[ 2.5\text{ Gb/s}\times 2\times n / 10 = 0.5\text{ GB/s}\times n \]

所以 PCIe \(\times 16\) 的双向总带宽可达 \(8\text{ GB/s}\)

4.6 I/O 总线、I/O 控制器与 I/O 设备的关系

这些关系可以概括为:

  • I/O 设备通常通过通信总线或电缆连接到 I/O 控制器。
  • I/O 控制器,也称 I/O 接口,可通过扩展卡或南桥芯片连接到 I/O 总线。
  • I/O 总线再通过桥接芯片与 CPU、内存所在的更高速互连结构相连。

因此要区分两个“连接层次”:主板内部的 PCIe 等是 I/O 总线;设备外部的 USB、SATA、PS/2、网线等常体现为设备侧通信总线或连接接口。

5 I/O 接口、端口与设备寻址

5.1 I/O 接口的含义与分类

这里把 I/O 控制器和插座合起来称为 I/O 接口。例如网卡、显卡、键盘适配器、磁盘控制器,以及它们对应的连接器,都可视为 I/O 接口的一部分。I/O 接口包括插头/插座形式、通信规程、电气特性和控制逻辑。

I/O 接口可按多个角度分类:

分类角度 类型
数据传输方式 串行接口(一次只传输1位)、并行接口(多位一起进行传输)
是否能连接多个设备 总线式接口(可连接多个设备)、独占式接口(只能连接1个设备)
是否符合标准 标准接口、专用接口
功能是否可灵活选择 可编程接口、不可编程接口

5.2 I/O 控制器的职能

I/O 控制器承担主机与设备之间的转换、缓冲和控制工作。它的主要职能包括:

  • 数据缓冲:用数据缓冲寄存器匹配主机和外设速度。
  • 状态或错误检测:用状态寄存器保存就绪、忙、出错等信息。
  • 控制和定时:接受系统总线来的控制定时信号,并按设备要求产生控制动作。
  • 数据格式转换:例如串并转换、并串转换、电平或编码转换。
  • 主机与设备通信:在主机侧接收 CPU 命令,在设备侧驱动外设动作。

CPU 通过写控制寄存器向设备发命令,通过读状态寄存器了解设备状态,通过读写数据寄存器交换数据。

image-20260615144027420

5.3 I/O 端口的概念

I/O 控制器中 CPU 能够访问的各类寄存器称为 I/O 端口。常见端口包括:

  • 数据端口:用于读写设备数据。
  • 状态端口:用于读取设备状态和错误标志。
  • 控制端口:用于写入命令或控制字。

对外设的访问,本质上就是对这些 I/O 端口进行读写:向端口发命令、读状态、读数据或写数据。一个 I/O 控制器可能占有多个端口地址,因此必须给 I/O 端口编号,CPU 才能访问它们。

5.4 I/O 设备寻址方式

I/O 设备寻址方式就是 I/O 端口的编号方式。有两种基本方案:统一编址独立编址

方式 又称 地址空间 指令特点 例子
统一编址 内存映射 I/O I/O 端口与主存统一编址 用普通访存指令访问 I/O 端口 RISC 机器、Motorola 处理器等
独立编址 特殊 I/O 指令方式 I/O 端口有独立地址空间 需要专门 I/O 指令,如 INOUT Intel、Zilog 处理器

统一编址方式下,I/O 端口被映射到主存地址空间的一部分。CPU 不需要专门 I/O 指令,只要用普通读写内存指令访问特定地址范围,就能读写 I/O 端口。它的优点是指令系统简单,访存机制统一;缺点是会占用部分主存地址空间,且需要通过地址范围区分访问对象。

image-20260615144232953

独立编址方式下,I/O 地址空间与主存地址空间分开。CPU 通过不同控制信号区分 I/O 读写和存储器读写,例如 IOR、IOW 与 MEMR、MEMW。由于 I/O 端口数量通常远少于存储器单元,端口寻址只需较少地址线。缺点是指令系统必须提供专门 I/O 指令。

image-20260615144314614

奔腾机采用独立编址方式,I/O 地址空间由 \(2^{16}\) 个 8 位端口组成,即 64K 个端口。两个连续 8 位端口可组成 16 位端口,四个连续 8 位端口可组成 32 位端口。

6 I/O 传输方式

6.1 三种基本数据交换方式

I/O 设备与主机之间的数据交换有三种基本方式:

方式 核心机制 CPU 参与程度 适用设备
程序直接控制方式 CPU 主动查询或按时序传送 很高,CPU 常处于等待状态 简单慢速设备
中断 I/O 方式 外设完成或需要服务时主动中断 CPU 中等,CPU 执行中断服务程序传数据 低速或中速设备
DMA 方式 DMA 控制器控制总线,外设与主存直接传送 很低,CPU 主要负责初始化和结束处理 磁盘等高速块设备

这三种方式的根本区别是:数据传送由谁完成,以及 CPU 是否需要持续等待

6.2 程序直接控制或轮询方式

程序直接控制方式是最简单的 I/O 方式。它可以是无条件传送,也可以是条件传送。条件传送又称 轮询(Polling)或程序查询方式。

轮询的基本思想是:I/O 设备把自己的状态放到状态寄存器中,OS 或驱动程序反复读取状态寄存器,检查特定位是否表示“就绪”。如果未就绪,就继续查询;如果就绪,就进行下一步数据传送或发送控制命令。

以打印机为例,“就绪”通常表示打印控制器的数据缓冲区已经空,可以接受新的打印字符。CPU 执行 I/O 指令把字符送到数据端口,再检查状态位、发送启动信号。

image-20260615144553935

6.2.1 打印输出标准子程序例子

下面这个采用程序查询方式打印 AL 寄存器中字符的 8086 风格子程序,很好地说明了轮询 I/O 的三个动作:写数据端口、读状态端口、写控制端口启动设备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
PRINT PROC NEAR
PUSH AX ; 保护 AX,避免子程序破坏调用者现场
PUSH DX ; 保护 DX,因为后面要用 DX 保存 I/O 端口地址
MOV DX, 378H ; 378H 是打印机数据锁存器端口地址
OUT DX, AL ; 将 AL 中待打印字符输出到数据端口
MOV DX, 379H ; 379H 是打印机状态寄存器端口地址
WAIT: IN AL, DX ; 从状态端口读入打印机状态字
TEST AL, 80H ; 检查状态字中的忙碌位
JE WAIT ; 若打印机仍忙,则继续轮询等待
MOV DX, 37AH ; 37AH 是打印机控制寄存器端口地址
MOV AL, 0DH ; 准备控制字:置选通位为 1
OUT DX, AL ; 输出控制字,使选通位置 1
MOV AL, 0CH ; 准备控制字:置选通位为 0
OUT DX, AL ; 输出控制字,使选通位置 0,形成一次选通信号
POP DX ; 恢复 DX
POP AX ; 恢复 AX
RET ; 返回调用程序
PRINT ENDP

这段程序开始用 PUSH AXPUSH DX 保护现场,因为子程序会改写 AXDX。随后 MOV DX, 378H 把打印机数据锁存器端口地址送入 DXOUT DX, AL 将待打印字符写入数据端口。这里的 OUT 就是访问 I/O 端口的输出指令。

接着程序把 DX 改为 379H,这是打印机状态寄存器端口地址。标号 WAIT 处反复执行 IN AL, DXTEST AL, 80H:前者从状态端口读入打印机状态,后者检查状态字中的忙碌位。如果检测结果表示打印机仍忙,JE WAIT 就跳回继续查询;只有状态满足要求时,程序才退出等待循环。因此,这几条指令正体现了程序查询方式的“踏步”特征:CPU 没有停机,但它一直在执行读状态、测试、条件跳转。

最后程序把 DX 改为 37AH,即控制寄存器端口地址,先输出 0DH 使选通位置 1,再输出 0CH 使选通位置 0。这个 1 到 0 的变化相当于向打印控制器发出一次启动或选通信号,通知设备开始处理刚才写入的数据。末尾用 POP DXPOP AX 恢复现场并返回。

image-20260615145524426

程序直接控制方式的优点是简单、控制容易、接口硬件少。缺点也很明显:CPU 与外设串行工作,效率低;查询期间 CPU 不停执行类似“读状态、测试、跳转”的指令,形成所谓的踏步现象。如果一直独占查询,CPU 几乎 100% 时间都在为 I/O 服务。

6.3 中断 I/O 方式

中断 I/O 的基本思想是:CPU 启动外设后,不必一直等待。外设完成任务或需要 CPU 干预时,主动向 CPU 发中断请求。CPU 响应后暂停当前程序,转入操作系统中的中断服务程序;处理结束后,再返回被中断程序继续执行。

中断方式下,外设工作期间 CPU 可以执行其他程序,所以 CPU 与外设具有一定并行性。与轮询相比,它显著降低了 CPU 无意义等待的时间。

image-20260615145704524

6.3.1 中断响应条件

中断响应是硬件过程,指 CPU 发现外部中断请求、中止现行程序并调出中断服务程序。需要满足三个条件:

  1. CPU 处于开中断状态。
  2. 当前指令执行完毕。
  3. 至少存在一个未被屏蔽的中断请求。

外部中断通常在指令执行结束时响应;而内部异常发生在指令执行过程中,不能简单等到指令结束后再处理。这是中断与异常处理时点的重要区别。

6.3.2 中断响应过程

中断响应由处理器硬件完成,可看作执行一条“中断隐指令”。它主要完成三件事:

  • 关中断:清除中断允许标志,防止响应过程本身被打断。
  • 保护断点和程序状态:保存 PC 和 PSW,常保存到堆栈或特殊寄存器,如 EPC、EPSWR。
  • 识别中断源并转入服务程序:获得中断服务程序入口地址和初始状态,装入 PC 和 PSW。

image-20260615155923684

识别中断源有两种方法:

  • 软件识别:进入统一异常/中断处理入口后,由 OS 查询异常原因寄存器或中断请求状态。例如 MIPS 可通过 Cause 寄存器识别异常原因。
  • 硬件识别或向量中断:中断控制器通过优先级电路得到中断类型号,CPU 根据中断类型号查中断向量表,取得服务程序入口地址。例如 8086/8088 的中断向量表有 256 项,每项 4 字节,向量地址为“中断类型号 \(\times 4\)”。

以 8086/8088 为例,中断向量表也称中断入口地址表异常表,位于物理地址 0000H~03FFH。这段空间一共 \(1024\) 字节,被划分为 \(256\) 组,每组占 \(4\) 字节,用来保存一个中断服务程序的入口地址。8086/8088 的程序入口地址由 CS:IP 表示,因此每个中断向量表项保存的就是对应服务程序的 CS:IP

中断类型号和中断向量表地址之间的关系非常直接:

\[ \text{向量地址}=\text{中断类型号}\times 4 \]

例如,除法错的中断类型号为 \(0\),所以它的向量地址为 \(0\times4=0\),对应中断向量表的 00H~03H。单步中断类型号为 \(1\),对应 04H~07H。NMI 的中断类型号为 \(2\),所以向量地址为 \(2\times4=8\),对应 08H~0BH

image-20260615150257277

因此,向量中断的完整思路是:硬件先得到中断类型号,再用“类型号 \(\times 4\)”查中断向量表,取出 CS:IP,最后转到相应中断服务程序执行。进一步的问题是“中断类型号怎么得到”。这正好引出后面的中断控制器:中断控制器通过请求锁存、屏蔽和优先级编码,向 CPU 提供中断类型号。

6.4 中断控制器与 8259A

中断控制器负责接收多个外设的中断请求,进行屏蔽和优先级判断,并向 CPU 提供最高优先级中断的信息。其基本部件包括:

  • 中断请求寄存器:记录来自不同外设的请求。
  • 屏蔽寄存器:由 CPU 通过 I/O 指令设置,用来屏蔽部分中断。
  • 判优线路:从未屏蔽请求中选择优先级最高者。
  • 中断类型号形成线路:生成中断类型号并送到数据线上。

8259A 是典型可编程中断控制器。它支持中断请求锁存、中断屏蔽、优先级排队、中断优先权编码;既支持程序查询式中断,也支持向量式中断;单片支持 8 级中断,多片级联最多可构成 64 级中断。

image-20260615150419300

6.5 中断处理过程与多重中断

中断全过程可分为中断响应中断处理。中断响应由硬件完成;中断处理是执行中断服务程序,由软件完成。

典型多重中断服务程序可分为三段:

  • 先行段或准备阶段:保护现场和旧屏蔽字,查明原因,设置新屏蔽字,开中断。该阶段通常禁止被打断。
  • 本体段:进行具体 I/O 处理。此时可允许更高处理优先级的中断打断。
  • 结束段或恢复阶段:关中断,恢复现场和旧屏蔽字,清除中断请求,开中断并中断返回。该阶段也不允许被打断。

多重中断指在处理某个中断时,又发生新的更高优先级中断请求,CPU 暂停当前中断服务程序,转去处理新中断,处理完后再返回原中断服务程序。

这里要区分两个优先级:

  • 中断响应优先级:多个中断同时请求时,硬件或查询程序先响应谁。
  • 中断处理优先级:通过中断屏蔽字动态设定,决定一个中断服务程序执行期间允许哪些中断打断它。

响应优先级是“同时来时先接谁”,处理优先级是“正在处理时谁能插队”。

6.6 示例:中断优先权的动态分配

一个典型示例可以用来说明响应优先级处理优先级不是同一件事。

题设如下:某中断系统有四个中断源,响应优先级固定为:

\[ 1>2>3>4 \]

在用户程序执行时,\(1\)\(3\)\(4\) 级中断请求同时发生;当 CPU 正在执行 \(3\) 级中断服务程序时,又发生 \(2\) 级中断请求。要求分别写出处理优先级为 \(1>2>3>4\)\(1>4>3>2\) 时,各中断的屏蔽字以及 CPU 完成中断处理的过程。

这里约定:屏蔽字中 1 表示屏蔽,0 表示开放。某一级中断服务程序开始执行后,会设置本级对应的屏蔽字;若某个新中断源对应位为 0,并且系统处于开中断状态,它就可能打断当前中断服务程序。

6.6.1 处理优先级为 \(1>2>3>4\)

当处理优先级与响应优先级相同,即:

\[ 1>2>3>4 \]

屏蔽字可写为:

正在执行的中断服务程序级别 1 级 2 级 3 级 4 级
第 1 级 1 1 1 1
第 2 级 0 1 1 1
第 3 级 0 0 1 1
第 4 级 0 0 0 1

这张表的含义是:正在处理某一级中断时,比它优先级更高的中断开放,比它优先级相同或更低的中断屏蔽。例如执行 3 级中断服务程序时,1 级和 2 级开放,3 级和 4 级屏蔽,所以 2 级中断可以打断 3 级中断。

CPU 的处理过程如下:

  1. 用户程序执行时,1、3、4 级中断同时请求。由于响应优先级为 \(1>2>3>4\),CPU 首先响应 1 级中断。
  2. 1 级中断服务程序的屏蔽字为 1111,执行期间屏蔽所有中断,故 3、4 级只能等待。
  3. 1 级中断处理结束后,待处理请求中还有 3、4 级。按响应优先级,CPU 响应 3 级中断。
  4. 执行 3 级中断服务程序时,屏蔽字为 0011,即 1、2 级开放,3、4 级屏蔽。此时发生 2 级中断请求,由于 2 级开放且处理优先级高于 3 级,所以 2 级中断打断 3 级中断。
  5. 2 级中断服务程序执行完后,CPU 返回被打断的 3 级中断服务程序继续执行。
  6. 3 级中断结束后,最后处理等待中的 4 级中断。

因此,这种情况下的主要处理顺序可概括为:

\[ \text{主程序}\rightarrow 1 \rightarrow 3 \rightarrow 2 \rightarrow 3 \rightarrow 4 \rightarrow \text{主程序} \]

如果只看各级中断完成的先后顺序,则是:

\[ 1,\ 2,\ 3,\ 4 \]

image-20260615151347997

6.6.2 处理优先级为 \(1>4>3>2\)

第二种情况中,响应优先级仍然是:

\[ 1>2>3>4 \]

但处理优先级被动态设置为:

\[ 1>4>3>2 \]

此时屏蔽字变为:

正在执行的中断服务程序级别 1 级 2 级 3 级 4 级
第 1 级 1 1 1 1
第 2 级 0 1 0 0
第 3 级 0 1 1 0
第 4 级 0 1 1 1

这张表要按处理优先级来读。例如执行 3 级中断服务程序时,1 级和 4 级比 3 级处理优先级高,所以开放;2 级比 3 级处理优先级低,所以屏蔽。这正是动态分配中断处理优先权的意义:响应优先级决定先响应谁,但进入某个服务程序后,能不能被打断由屏蔽字决定。

CPU 的处理过程如下:

  1. 用户程序执行时,1、3、4 级中断同时请求。由于响应优先级固定为 \(1>2>3>4\),CPU 仍然首先响应 1 级中断。
  2. 1 级中断服务程序屏蔽所有中断,处理结束后返回。
  3. 待处理请求中还有 3、4 级。虽然处理优先级中 4 高于 3,但此时 CPU 选择响应哪个未处理请求仍按响应优先级,所以先响应 3 级中断。
  4. 进入 3 级中断服务程序后,屏蔽字为 0110,即 1、4 级开放,2、3 级屏蔽。因此原本等待的 4 级中断可以打断 3 级中断。
  5. CPU 转去执行 4 级中断服务程序。4 级的屏蔽字为 0111,只开放 1 级,屏蔽 2、3、4 级。
  6. 4 级中断结束后,CPU 返回 3 级中断服务程序继续执行。执行 3 级服务程序期间发生的 2 级中断因被屏蔽,不能打断 3 级,只能等待。
  7. 3 级中断结束后,CPU 再处理等待中的 2 级中断。

因此,这种情况下的主要处理顺序可概括为:

\[ \text{主程序}\rightarrow 1 \rightarrow 3 \rightarrow 4 \rightarrow 3 \rightarrow 2 \rightarrow \text{主程序} \]

如果只看各级中断完成的先后顺序,则是:

\[ 1,\ 4,\ 3,\ 2 \]

image-20260615151615022

这道题的分析关键是:响应优先级决定“多个请求同时出现时先响应谁”,处理优先级通过屏蔽字决定“服务程序执行过程中谁能打断谁”。所以第二种情况下,3 级会先于 4 级被响应,但 4 级又会在 3 级执行期间打断 3 级;2 级虽然响应优先级高于 3、4,但处理优先级最低,若在 3 级服务程序中出现,会被屏蔽到后面再处理。

6.7 轮询方式与中断方式比较

设某设备输出一批数据:主机把一个数据送到接口输出缓冲 OBR 需 \(1\mu s\),OBR 输出到设备需 \(1\text{ ms}\),每条指令 \(1\mu s\)

程序直接控制方式中,若查询程序有 10 条,第 5 条为启动设备指令,则每个数据周期约:

\[ 1000\mu s + 5\mu s = 1005\mu s \]

数据传输率约为:

\[ \frac{1}{1005\mu s}\approx 995\text{ 个数据/秒} \]

但 CPU 一直查询,主机占用率为 \(100\%\)

中断方式中,若中断服务程序有 30 条,第 20 条启动设备,则数据传输率约为:

\[ \frac{1}{1000+1+20}\mu s \approx 979\text{ 个数据/秒} \]

主机占用率为:

\[ \frac{1+30}{1000+1+20}\approx 3\% \]

所以中断方式的传输率可能略低,因为中断服务程序有保存现场、设置屏蔽字等额外开销;但 CPU 占用率大幅下降,系统整体效率更高。

7 DMA 方式

7.1 为什么引入 DMA

DMA(Direct Memory Access,直接存储器访问)用于解决高速设备与主存之间的大批量数据传送问题。

程序直接控制方式受踏步现象限制,CPU 等待严重,不适合高速设备。中断方式虽然让 CPU 与外设部分并行,但每传一个数据都可能需要一次中断,存在中断响应、保护现场、恢复现场等开销,且数据传送由 CPU 执行软件完成,速度仍然不够。

DMA 的基本思想是:高速外设和主存之间直接传送数据,由专门硬件 DMA 控制器控制总线,CPU 不参与逐字节或逐字的数据搬运

DMA 适合高速设备和成批数据交换,例如磁盘、光盘等。一旦启动,数据会连续读写,数据间隔时间短,必须及时传送,否则可能丢失。

7.2 DMA 与中断的配合

DMA 并不是完全不需要中断,而是与中断配合使用。以磁盘为例:

  • 寻道阶段:可用中断通知 CPU 操作完成。
  • 旋转查找扇区阶段:可用中断通知 CPU。
  • 连续读写阶段:使用 DMA 方式传送数据。
  • 结束和校验阶段:用 DMA 结束中断通知 CPU 后处理。

因此,DMA 的含义不是“没有中断”,而是大批量数据传送期间 CPU 不搬运数据

7.3 DMA 数据传送的三种控制方式

DMA 传送时,真正搬运数据的是 DMA 控制器,但数据最终要进出主存。问题在于:CPU 执行程序也要访问主存,DMA 控制器传数据也要访问主存。两者共享主存和系统总线,就可能出现争用。三种控制方式本质上是在回答同一个问题:当 DMA 要访问主存时,CPU 应该怎样让出主存和总线。

方式 做法 优点 缺点或适用场景
CPU 停止法 DMA 传输一块数据期间,CPU 脱离总线,停止访问主存 控制简单,适合很高速外设成组传送 CPU 基本停止,主存周期利用不充分
周期挪用法 DMA 每次只窃取一个总线或存储周期,传一个数据后释放总线 能及时响应 I/O,又较好发挥 CPU 和主存效率 每次传送都要申请和释放总线,控制开销较大
交替分时访问法 每个存储周期分成两个时间片,一个给 CPU,一个给 DMA CPU 与 DMA 可规则交替访问 需要存储系统支持固定分时

7.3.1 CPU 停止法:一次让出一整块传输时间

CPU 停止法也叫成组传送方式。当 DMA 开始传输一块数据时,CPU 脱离总线,停止访问主存;DMA 控制器独占总线和主存,把这一整块数据传完后,CPU 才重新取得总线控制权。

可以把它理解成:CPU 对 DMA 说“这一段时间总线都归你,你把这一块数据一次搬完”。因此它的控制逻辑最简单,DMA 不需要每传一个字都重新申请总线。

image-20260615153623791

这种方式的优点是控制简单,适合传输率很高的外设进行成组数据传送。缺点是 CPU 受影响很大:DMA 访存期间 CPU 基本不能访问主存,很多情况下只能等待。更细一点说,即使 I/O 设备已经算“高速”,两个数据准备好之间通常仍会有间隔,而这个间隔往往大于一个主存周期;如果 CPU 被整块暂停,就会导致一些主存周期空闲,主存没有被充分利用。

有两种弥补 CPU 停止法缺点的思路:

  • 在 DMA 接口中引入缓冲器:让外设先和 DMA 接口里的小容量半导体缓冲器交换数据,再由缓冲器与主存成批交换。这样 DMA 真正占用系统总线的时间变短,CPU 等待时间也会减少。
  • 改用周期挪用法:DMA 不再一次占住总线直到一整块传完,而是每次只挪用一个存储周期,传完一个数据就释放总线。

7.3.2 周期挪用法:一次只抢一个主存周期

周期挪用法也叫周期窃取法单字传送方式。当外设准备好一个数据时,DMA 控制器向 CPU 请求总线;CPU 让出一个总线事务周期,由 DMA 控制器访问主存,传送一个字或一个数据单位。传完后,DMA 立即释放总线,CPU 可以继续访存。等外设准备好下一个数据时,DMA 再发起下一次请求。

它的关键思想是:不让 DMA 长时间霸占总线,而是在 CPU 执行过程中“插空”拿走一个主存周期

image-20260615153755641

周期挪用法的优点是:既能及时响应 I/O 请求,又能较好发挥 CPU 和主存效率。外设准备下一个数据时,CPU 可以继续使用主存;只有真正要传送一个数据时,DMA 才短暂占用一个周期。因此,它适合 I/O 设备读写周期大于主存周期的情况。换句话说,外设并不是每个主存周期都能给出数据,CPU 可以利用外设准备数据的空隙继续执行程序。

它的缺点是控制开销比 CPU 停止法大。因为每传一个数据,DMA 都要经历申请总线、获得总线、传送数据、释放总线这一小轮流程。如果数据量很大、每个数据都这么申请,控制过程本身也会消耗时间。

周期挪用法需要区分三种可能情况:

DMA 请求发生时的 CPU 状态 是否冲突 处理方式
CPU 暂时不需要访问主存 不冲突 DMA 可直接访问主存,两者在功能上并行
CPU 正在访问主存 暂时冲突 等当前存储周期结束后,CPU 让出总线,DMA 再访存
CPU 也正准备访问主存 发生访存竞争 DMA 优先,先窃取一个主存周期,CPU 延迟访存

第三种情况最能体现“周期挪用”的名字:DMA 像是从 CPU 手里临时借走一个主存周期。为什么 DMA 优先?因为高速外设的数据缓冲可能很小,如果不及时传送,后续数据到来时可能覆盖旧数据,造成数据丢失;CPU 延迟一个主存周期通常只是性能下降,不会直接丢数据。

7.3.3 交替分时访问法:把每个存储周期分成两份

交替分时访问法的思想更规则:把每个存储周期划分成两个时间片,一个固定给 CPU,一个固定给 DMA。这样在每个存储周期内,CPU 和 DMA 都有自己的访问机会,不需要每次都临时争抢。

可以理解成:CPU 和 DMA 不是“谁急谁抢”,而是事先约定好轮流使用主存。例如一个周期的前半段 CPU 访问主存,后半段 DMA 访问主存;或者按硬件规定的节拍交替进行。这样 CPU 不会像 CPU 停止法中那样长时间被停住,DMA 也不必像周期挪用法那样每次都重新申请总线。

它的优点是访问节奏稳定,CPU 和 DMA 都能规律地使用主存;缺点是对硬件时序要求较高,需要存储系统支持这种固定分时安排。如果某一方暂时不需要访存,它分到的时间片可能浪费;如果某一方特别急,也不能随意多占时间片。

7.3.4 三种方式的对比

可以按“DMA 一次占用主存多久”来记:

控制方式 DMA 一次占用粒度 CPU 受影响程度 总线控制开销 适合场景
CPU 停止法 一整块数据传送期间 最大,CPU 基本停止访存 最小 传输率很高、适合成组传送,且允许 CPU 短暂停顿
周期挪用法 一个主存周期或一个数据单位 中等,只延迟部分访存周期 较大 外设读写周期大于主存周期,常见 DMA 方式
交替分时访问法 固定时间片 较稳定,不长时间阻塞 中等,依赖硬件时序 CPU 与 DMA 都需要规律访存、硬件支持分时

一句话总结:CPU 停止法是“整块让路”,周期挪用法是“临时借一个周期”,交替分时访问法是“预先排班轮流用”。

7.4 DMA 控制器的功能

image-20260615154431432

DMA 接口也称 DMA 控制器。它要能完成以下功能:

  • 接收外设发来的 DMA 请求,并向 CPU 发总线请求。
  • 在 CPU 发出总线响应后,接管总线控制权。
  • 在地址线上给出主存地址,并自动修改主存地址。
  • 根据传送方向在控制线上给出正确读写控制信号。
  • 记录和判断传送数据个数。
  • 传送结束时发出 DMA 结束信号,引起 DMA 中断,进入后处理。

典型 DMA 控制器中会有地址寄存器、字计数器、设备地址寄存器、控制寄存器、状态逻辑和总线控制逻辑等。

7.5 DMA 操作步骤

DMA 操作可分为三个阶段:

  1. DMA 控制器初始化,由软件实现
    OS 或设备驱动准备内存缓冲区,设置内存首址、字计数值、传送方向、设备地址等参数,并启动外设。
  2. DMA 数据传送,由硬件实现
    外设准备好数据或准备好接收数据后发出 DMA 请求;DMA 控制器向 CPU 申请总线;CPU 完成当前机器周期后让出总线;DMA 控制器控制总线完成读写,自动修改地址并递减计数。
  3. DMA 结束处理,由软件实现
    当计数值为 0 时,DMA 控制器发出 DMA 结束信号,引起中断。CPU 执行中断服务程序,完成数据校验、状态检查、唤醒进程等后处理。

7.5.1 DMA 控制器初始化的详细步骤

DMA 初始化也叫 DMA 控制器预置,由软件完成,通常是操作系统中的设备驱动程序执行。它的目的不是传数据本身,而是先把 DMA 控制器“配置好”,让它后面能独立完成硬件传输。

第一步是准备内存区。如果是输入操作,例如从磁盘读数据到主存,驱动程序要先在主存中准备好接收数据的缓冲区;如果是输出操作,例如把主存中的一块数据写到外设,驱动程序要先把待输出数据放到内存缓冲区中。也就是说,DMA 传输前必须先明确:数据要从哪里来、要到哪里去。

第二步是设置传送参数。驱动程序通过 I/O 指令访问 DMA 控制器的端口,先测试外设状态,再把关键参数写入 DMA 控制器内部寄存器:

参数 写入位置 作用
内存首址 地址寄存器 指出 DMA 传输在主存中的起始地址
字计数值 字计数器 指出本次要传送多少个字、字节或数据单位
传送方向 控制寄存器 指出是外设到主存,还是主存到外设
设备地址 设备地址寄存器 指出要与哪个外设或哪个设备端口交换数据

这些参数对应 DMA 控制器后续硬件动作:地址寄存器决定每次访问主存的位置,字计数器决定何时结束,控制寄存器决定发读命令还是写命令,设备地址寄存器决定连接哪个外设。

第三步是启动外设。驱动程序向设备或 DMA 控制器发送启动命令后,CPU 不再逐字搬运数据,而是可以去执行其他程序。之后等外设准备好数据,DMA 控制器就会进入“DMA 请求、总线请求、总线响应、DMA 传送”的硬件流程。

7.6 DMA 传输过程细化

image-20260615154854456

DMA 传输过程可整理为:

  1. 外设准备好数据或准备好接收数据,发出选通信号,使数据进入数据缓冲寄存器,同时 DMA 请求触发器置 1。
  2. DMA 请求触发器向控制/状态端口发 Ready 信号,并向 DMA 控制器发 DMA 请求。
  3. DMA 控制器向 CPU 发总线请求。
  4. CPU 完成当前机器周期后响应 DMA 请求,发出总线响应。DMA 控制器发 DMA 响应,使请求触发器复位,CPU 浮动总线并让出控制权。
  5. DMA 控制器给出内存地址和读写命令,在数据总线上完成数据传输。
  6. DMA 控制器修改主存地址、计数值减 1。若采用 CPU 停止法,则循环传到计数为 0;若采用周期挪用法,则传一个数据后释放总线,下一次再重新请求。

7.7 DMA 与中断方式的区别

对比点 中断方式 DMA 方式
数据传送者 CPU 执行中断服务程序,用软件传送 DMA 控制器用硬件传送
请求含义 请求 CPU 暂停当前程序并执行服务程序 请求总线控制权或主存访问权
是否中止现行程序 需要保存断点和现场 数据传送期间通常不需中止程序
能否处理异常 可以处理外设事件和异常情况 不能处理异常,只负责数据搬运
响应时点 一条指令周期结束后 一个总线周期或机器周期后
适用设备 低速、慢速或中速设备 高速块设备
并行度 外设与 CPU 有一定并行性,但数据传送仍由 CPU 做 外设与 CPU 并行度高,CPU 开销小

7.8 中断与 DMA 的 CPU 开销示例

题设:CPU 频率 \(500\text{ MHz}\),硬盘控制器数据缓存 \(16\text{ B}\),磁盘传输率 \(4\text{ MB/s}\),忽略 CPU 访存和 DMA 访存冲突。

7.8.1 中断方式

硬盘每次中断传 \(16\text{ B}\),若磁盘以 \(4\text{ MB/s}\) 传输,则每秒中断次数为:

\[ 4\text{ MB/s}/16\text{ B}=250\text{ k 次/s} \]

每次中断开销 500 个时钟周期,则每秒用于中断的时钟周期数为:

\[ 250\text{ k}\times 500=125\times 10^6 \]

CPU 每秒总时钟周期为:

\[ 500\times 10^6 \]

若硬盘一直传输,则 CPU 用在 I/O 上的比例为:

\[ \frac{125\times 10^6}{500\times 10^6}=25\% \]

若硬盘只有 5% 时间在传输,则 CPU 用在 I/O 上的比例为:

\[ 25\%\times 5\%=1.25\% \]

7.8.2 DMA 方式

每次 DMA 传送 \(8000\text{ B}\),传输时间为:

\[ 8000\text{ B}/(4\text{ MB/s})\approx 2\times 10^{-3}\text{ s} \]

所以每秒约有:

\[ 1/(2\times 10^{-3})=500 \]

次 DMA 传送。每次 DMA 初始化 1000 个时钟,结束中断处理 500 个时钟,每秒 CPU 开销为:

\[ (1000+500)\times 500=750\times 10^3 \]

CPU 占用率为:

\[ \frac{750\times 10^3}{500\times 10^6}=1.5\times 10^{-3}=0.15\% \]

这个例子说明:DMA 的核心优势不是让设备本身变快,而是显著减少 CPU 为 I/O 付出的时间

8 I/O 子系统的软件层次与驱动程序

8.1 I/O 子系统的层次结构

高级语言运行时通常提供 I/O 函数,例如 C 的 printf()scanf(),C++ 的输入输出操作符。用户程序通过这些函数提出 I/O 请求,但真正完成 I/O 需要多层软件和硬件协同。

I/O 软件从高到低可分为四层:

  1. 用户层 I/O 软件:如标准库函数、运行时库。
  2. 与设备无关的操作系统 I/O 软件:提供统一文件、缓冲、权限、调度等抽象。
  3. 设备驱动程序:直接控制具体设备控制器,访问 I/O 端口。
  4. I/O 中断处理程序:响应外设中断或 DMA 完成中断。

层次越低,越接近设备,越远离用户程序。大部分 I/O 软件属于操作系统内核态程序,但最初 I/O 请求来自用户态。

从用户态切换到内核态的关键机制是异常机制中的系统调用或自陷。例如 Linux 中,printf() 最终会调用 write(),再通过系统调用入口进入内核,找到 sys_write() 服务例程执行。系统调用处理程序根据系统调用号决定转向哪个内核服务例程。

image-20260615155332406

8.2 三种方式在驱动程序中的体现

程序查询方式下,驱动程序把用户数据复制到内核缓冲区后,对每个字符循环执行:读状态端口,等待设备 Ready;写数据端口;写控制端口启动设备。当前进程在内核态“干等”,CPU 被持续占用。

image-20260615155447325

中断方式下,驱动程序启动第一次 I/O 后阻塞当前用户进程,调度其他进程运行。设备完成一个字符或一段任务后发中断,中断服务程序继续送下一个字符或做相应处理。CPU 与外设可并行工作。

image-20260615155559351

DMA 方式下,驱动程序初始化 DMA 控制器,设置缓冲区地址、长度、方向等参数,然后启动 DMA 传送并阻塞当前进程。DMA 控制器完成全部数据传输后发 DMA 结束中断,中断服务程序做校验、清除中断、唤醒进程等后处理。

image-20260615155642477

image-20260615155832126

8.3 中断服务程序在不同方式中的任务

中断控制方式和 DMA 控制方式都需要中断服务程序,但任务不同:

  • 在中断 I/O 中,中断服务程序通常要执行实际数据传送,例如从数据缓冲器取数或把数据写入数据缓冲器,并再次启动外设。
  • 在 DMA I/O 中,中断服务程序主要做结束处理,例如数据校验、清除中断请求、唤醒等待进程;实际数据搬运已经由 DMA 控制器完成。

I/O 指令、开中断、关中断等都是特权指令,只能在操作系统内核程序中使用。这也是用户程序不能随意直接控制硬件设备的重要原因。

9 总结

9.1 本章核心概念

  • I/O 系统性能:吞吐率看单位时间传多少,响应时间看一次请求等多久。
  • I/O 系统任务:建立通路、设备寻址、发送命令、读取状态、传输数据。
  • 外设通用模型:控制信息、状态信息、数据信息三类信号。
  • 磁盘访问时间:寻道时间 + 旋转等待时间 + 数据传输时间。
  • RAID:多个物理盘组成一个逻辑盘,通过条带化提高性能,通过冗余提高可靠性。
  • 总线组成:数据线、地址线、控制线。
  • 总线趋势:点对点、异步、串行。
  • I/O 控制器:主机与外设之间的缓冲、控制、状态检测、格式转换部件。
  • I/O 端口:I/O 控制器中 CPU 可访问的寄存器。
  • I/O 寻址:统一编址用普通访存指令,独立编址用专门 I/O 指令。
  • 三种 I/O 传输方式:轮询靠 CPU 查,中断靠外设通知,DMA 靠硬件搬数据。

9.2 概念对比

易混概念 区别
I/O 总线 vs 通信总线 I/O 总线通常在主板内部连接 I/O 控制器;通信总线常连接 I/O 控制器和外部设备
I/O 控制器 vs I/O 接口 有些语境会把控制器和插座合称 I/O 接口;严格说控制器偏逻辑,接口还包括连接器、电气规范等
响应优先级 vs 处理优先级 响应优先级决定多个请求同时来时先响应谁;处理优先级由屏蔽字动态决定谁能打断谁
中断方式 vs DMA 方式 中断方式由 CPU 执行服务程序传数据;DMA 方式由 DMA 控制器硬件传数据
DMA 请求 vs 中断请求 DMA 请求要总线或主存访问权;中断请求要 CPU 转去执行服务程序
RAID 4 vs RAID 5 RAID 4 有专门校验盘,写时易成瓶颈;RAID 5 校验块分布在各盘

9.3 常考公式与计算

磁盘平均访问时间:

\[ T = T_{\text{seek}} + T_{\text{rotation}} + T_{\text{transfer}} + T_{\text{controller}} + T_{\text{queue}} \]

平均旋转等待时间:

\[ T_{\text{rotation}}=\frac{0.5}{\text{RPS}} \]

同步总线带宽:

\[ B=W\times F/N \]

PCIe 1.0 \(\times n\) 双向带宽:

\[ B=2.5\text{ Gb/s}\times 2\times n/10=0.5\text{ GB/s}\times n \]

RAID 4 少量写校验更新:

\[ p'(i)=p(i)\oplus X_0(i)\oplus X'_0(i) \]

CPU 占用率常用思路:

\[ \text{CPU 占用率}=\frac{\text{单位时间用于 I/O 的 CPU 周期数}}{\text{单位时间 CPU 总周期数}} \]

9.4 学习建议

学习本章时,可以按“谁控制数据传输”来串起来:

  1. 轮询:CPU 一直主动查状态,最简单但最浪费 CPU。
  2. 中断:外设完成后通知 CPU,CPU 通过服务程序处理,减少等待。
  3. DMA:CPU 设置参数,DMA 控制器直接在外设和主存间搬数据,CPU 开销最低。

再按“设备如何被找到”理解 I/O 端口和编址:CPU 并不是直接“找到打印机”,而是访问打印机控制器中的数据端口、状态端口、控制端口。统一编址把这些端口放进主存地址空间,独立编址则给它们单独的 I/O 地址空间。

最后按“通路如何构成”理解总线:CPU、主存、I/O 控制器通过不同层次的总线和桥接器连接;高速互连越来越倾向于点对点、串行、异步;低层设备还会通过 USB、SATA、PS/2、网线等通信接口连接到具体外设。