系统互连及输入输出组织
外部设备的分类与特点
外设的分类
- 按信息的传输方向来分:
- 输入设备:键盘、鼠标、扫描仪等
- 输出设备:打印机、显示器等
- 输入/输出设备:磁盘驱动器、光盘驱动器、CRT 终端、网卡之类的通信设备等
- 按功能来分:
- 人机交互设备:用于用户和计算机之间交互通信的设备。
- 如:键盘、鼠标、扫描仪、打印机、显示器等
- 存储设备:用于存储大容量数据,作为计算机的外存储器使用。
- 如:磁盘驱动器、光盘驱动器等
- 机-机通信设备:用于计算机及和计算机之间的通信。
- 如:网卡、调制解调器、数/模和模/数转化设备等
- 人机交互设备:用于用户和计算机之间交互通信的设备。
外设的特点
- 异步性:外设与 CPU 之间是完全异步的工作方式,两者之间无统一的时钟。
- 实时性:CPU 必须及时按不同的传输速率和不同的传输方式接收来自多个
外设的信息或向多个外设发送信息,否则高速设备可能丢失信息。 - 多样性:外设的多样性造成了主机与外设之间连接的复杂性。为简化控制,计算机系统往往提供标准接口,以便各类外设通过自己的设备控制器与标准接口相连。
常用输入输出设备
键盘
通过键盘输入字符,并在显示器上显示。
信息交换的基本单位是字符。
普遍使用的代码是 ASCII 码(American Standard Code for Information Interchange)。
- 128 个字符:
- 不可打印
- 32 个通用控制字符
- 可打印
- 10 个十进制数码
- 52 个英文字母
- 34 个专用符号
- 不可打印
通常在 7 位代码后跟一位奇偶校验位,组成一个字节。
记得各国有利用这个「闲置」的位进行扩展的。
按键位置识别法之一:列扫描法。基本做法:按列扫描、接地检查。
记得看过视频,键盘按键识别还是挺复杂的,这里这个就懒得附图了。
打印机
分类:
- 击打式打印机:最早研制成功的计算机打印设备,以机械力量击打字锤从而使字模隔着色带在纸上打印出字来。
- 整字形打印设备
- 点阵打印设备(针式打印机):利用打印头中的多根印针经色带在纸上打印出点阵字符的印字设备。
- 非击打式打印机:
- 激光打印机:由打印机控制器和打印装置两部分组成,是目前应用最广泛的一种非击打式打印机。
- 喷墨打印机:利用喷墨头喷射出可控的墨滴,在打印纸上形成文字或图片,是目前应用较多的一种打印输出设备。
打印机通过打印控制器或打印适配器与主机连接,打印控制器由以下基本部件组成:
- 数据锁存器:用于暂存 CPU 送来的打印数据。
- 命令译码器:对 CPU 送来的命令进行译码,产生打印控制器内部使用的命令。
- 控制锁存器:锁存 CPU 送来的控制命令。
- 状态锁存器:保存打印机送来的状态信息。
显示器
分类:
- 按显示器件分:
- 阴极射线管(Cathode Ray Tube, 简称 CRT)显示器
- 液晶显示器(Liquid Crystal Display, 简称 LCD)
- 等离子显示器等
- 按显示内容分:
- 字符显示器、图形显示器和图像显示器
- 按功能分:
- 普通显示器 、终端设备显示器
- 按扫描方式分:
- 光栅扫描显示器 、随机扫描显示器
- 按分辨率高低分:
- 高分辨率显示器、低分辨率显示器
CRT 显示器
CRT(Cathode-Ray Tube)是图形显示器的核心。电视机中的显像管就是 CRT。
基本工作原理:由电子枪发出的电子束(阴极射线),通过聚焦系统和偏转系统,射向涂覆荧光层的屏幕上的指定位置。在电子束冲击的每个位置,荧光层发出一个小的亮点,由这些小亮点构成所需的字符、图形和图像。
对彩色 CRT 而言,通常用三个电子枪发射电子束,经定色机构,分别触发红、绿、蓝三种颜色的荧光粉发光,按三元色叠加原理形成彩色图像。
CRT 荧光屏在水平方向和垂直方向单位长度上能识别的最大光点数称为分辨率。也即:CRT 的分辨率是可以无重叠显示的最多点数。
通常称分辨率为水平和垂直方向的总点数,但更精确的分辨率定义是在 x 和 y 方向上每厘米可绘制的点数(水平分辨率和垂直分辨率)
灰度级是指像素点的亮度级差,在彩色显示器中表现为色彩的差别,即颜色数。真彩色显示器的颜色位数为:24 位=8 位(红)+ 8 位(绿)+ 8 位(蓝),所以颜色数为 。
纵横比指在屏幕两个方向生成同等长度的线段所需垂直点数对水平点数的比值(有时,纵横比解释为水平点数对垂直点数的比值)。
例如纵横比为 3/4 则意味着垂直方向上画三点的长度与水平方向上画四点的长度相同。
物理尺寸是指显示器屏幕的对角线长度。
光栅扫描
- 光栅扫描方式中,电子束总是不断地从左到右、从上到下反复扫描整个屏幕
- 电子束从左到右(横向)扫描一次称为一条扫描线,从屏幕顶部到屏幕底部的所有扫描线构成一帧图像。也就是说,一帧图像是光栅显示系统执行一次循环或屏幕刷新一次所产生的图像。
- 为了产生无明显闪烁的图像,每秒钟至少执行 30 次循环。
- 一般刷新是按每秒 60 到 80 帧的速率进行的,但有些系统设计成更高的刷新速率。每秒 60 帧的刷新频率为 60HZ 。
- 可分为逐行扫描和隔行扫描两种,一般都采用「隔行」方式。每帧显示分为先后扫描奇数场和偶数场两趟。
LCD 液晶显示器
具有体积小、耗电低、不闪烁等优点和良好的综合性能,广泛应用于各类计算设备中。
基本原理:液晶通电时会改变其排列次序,从而影响光线的通过。
工作模式:
- 字符模式:显示存储器中存放字符编码及其属性,字形信息存放在字符发生器中。
- 图形模式:字符的点阵信息直接存储在显示存储器中,可显示彩色或单色多级灰度图像,能够实现画图功能。
显卡:核心是绘图处理器。早期的绘图功能由 CPU 在内存中完成,再将生成的图像从内存传到显存。目前显卡中的 GPU 专门用来绘图,减轻了 CPU 的负担。
外设与 CPU 和主存的互连
总线基本概念
总线是计算机内数据传输的公共路径,用于实现两个或两个以上部件之间的信息交换。
系统总线指连接处理器芯片、存储器芯片和各种 I/O 模块等主要部件的总线。
系统总线通常由一组控制线、一组数据线和一组地址线构成。也有些总线没有单独的地址线,地址信息通过数据线来传送,这种情况称为数据/地址复用。
- 数据线(Data Bus):承载在源和目部件之间传输的信息。数据线的宽度反映一次能传送的数据的位数。
- 地址线(Address Bus) :给出源数据或目的数据所在的主存单元或 I/O 端口的地址。地址线的宽度反映最大的寻址空间。
- 控制线(Control Bus) :控制对数据线和地址线的访问和使用。用来传输定时信号和命令信息。
总线性能指标
总线宽度:总线中数据线的条数,决定了每次能同时传输的信息位数。
总线工作频率:早期的总线通常一个时钟周期传送一次数据,此时,工作频率等于总线时钟频率;现在有些总线一个时钟周期可以传送 2 次或 4 次数据,因此,工作频率是时钟频率的 2 倍或 4 倍。
总线带宽:总线的最大数据传输率
- 对于同步总线,总线带宽计算公式:
- :总线宽度
- :总线时钟频率
- :完成一次数据传送所用时钟周期数
- 实际上就是总线工作频率
总线寻址能力:由地址线位数所确定的可寻址地址空间的大小。
总线定时方式:
- 同步通信:由时钟信号同步
- 异步通信:前一个信号的结束就是下一个信号的开始,信息的改变是顺序的
- 半同步通信:同步和异步两种总线定时方式的结合
总线传送方式:
- 非突发传送:每个总线事务都传送地址,一个地址对应一次数据传送。
- 突发传送:即为成块数据传送。突发传送总线事务中,先传送一个地址,后传送多次数据,后续数据的地址默认为前面地址自动增量。
总线负载能力:总线上所能挂接的遵循总线电气规范的总线设备的数目(一般指总线上扩展槽的个数)
基于总线的互连结构:
在上面这个互连结构中,除了 CPU、主存储器以及各种接插在主板扩展槽上的 I/O 控制卡(如声卡、视频卡)外,还有北桥芯片和南桥芯片。这两块超大规模集成电路芯片组成一个「芯片组」,是计算机中各个组成部分相互连接和通信的枢纽。主板上所有的存储器控制功能和 I/O 控制功能几乎都集成在该芯片组内,它既实现了总线的功能,又提供了各种 I/O 接口及相关的控制功能:
- 北桥是一个主存控制器集线器(memory controller hub, MCH)芯片,本质上是一个 DMA(direct memory access)控制器,因此,可通过 MCH 芯片直接访问主存和显卡中的显存。
- 南桥是一个 I/O 控制器集线器(I/O controller hub, ICH)芯片,其中可以集成 USB 控制器、磁盘控制器、以太网络控制器等各种外设控制器,也可以通过南桥芯片引出若干主板扩展槽,用以接插一些 I/O 控制卡。
I/O 接口
I/O 接口:I/O 设备控制器(如网卡、显卡、键盘适配器、磁盘控制器)包括:插头/插座的形式、通讯规程和电器特性等。
分类:
- 从数据传输方式来分:
- 串行(一次只传输 1 位)
- 并行(多位一起进行传输)
- 从是否能连接多个设备来分:
- 总线式(可连接多个设备)
- 独占式(只能连接 1 个设备)
- 从是否符合标准来分:
- 标准接口(通用接口)
- 专用接口(专用接口)
- 按功能选择的灵活性来分:
- 可编程接口
- 不可编程接口
I/O 接口的通用结构:
- 通过发送命令字到 I/O 控制寄存器来向设备发送命令
- 通过从状态寄存器读取状态字来获取外设或 I/O 控制器的状态信息
- 通过向 I/O 控制器发送或读取数据来和外设进行数据交换
职能:
- 数据缓冲:提供数据缓冲寄存器,以达到主机和外设工作速度的匹配。
- 错误或状态检测:提供状态寄存器,以保存各种错误或状态信息供CPU查用。
- 控制和定时:提供控制和定时逻辑,以接受从系统总线来的控制定时信号。
- 数据格式转换:提供数据格式转换部件使通过外部接口得到的数据转换为内部接口需要的格式,或在相反的方向进行数据格式转换。
- 与主机和设备通信:上述功能通过 I/O 接口与主机之间、I/O 接口与设备之间的通信来完成。
编址方式:
- 统一编址方式(内存映射方式):与主存空间统一编址,将主存空间分出一部分地址给 I/O 端口进行编号。
- 该方法是将 I/O 端口映射到某主存区域,故也称为「存储器映射方式」
- 例如,RISC 架构(如 MIPS、RISC-V 等)、Motorola 公司的处理器等采用该方案
- 独立编址方式(特殊 I/O 指令方式):不和主存单元一起编号,而是单独编号,使成为一个独立的 I/O 地址空间
- 因需专门 I/O 指令,故也称为「特殊 I/O 指令方式」
- 例如,Intel 公司和 Zilog 公司的处理器就是独立编址方式
独立编址方式:
独立编址方式通过不同的读写控制信号 IOR
, IOW
, MEMR
, MEMW
来控制对 I/O 端口和存储器的读写。
MEMR
, MEMW
命令由访存指令发出;IOR
, IOW
命令由专门的 I/O 指令发出,指令中给出的地址可能相同,但操作命令不同。因此指令系统必须设计专门的 I/O 指令。
统一编址方式:
CPU 不直接通过读写控制信号 IOR
, IOW
对 I/O 端口读写,而是根据 I/O 端口在地址空间的位置,通过地址译码来实现。
MEMR
, MEMW
命令由访存指令发出;IOR
, IOW
也由访存指令发出,只是访问的地址范围不同。因此无需设置专门的 I/O 指令,只要用一般的访存指令就可存取 I/O 接口。
I/O 数据传送控制方式
I/O 数据传送控制方式:
- 程序直接控制方式(最简单的 I/O 方式)
- 无条件传送:对简单外设定时(同步)进行数据传送
- 条件传送:Polling(轮询,查询):OS 主动查询,也称为程序查询方式
- I/O 设备(包括 I/O 接口)将自己的状态放到一个状态寄存器中
- OS 阶段性地查询状态寄存器中的特定状态,以决定下一步动作
- I/O Interrupt(中断 I/O 方式):几乎所有系统都支持的中断 I/O 方式
- 若一个 I/O 设备需要 CPU 干预,它就通过中断请求通知 CPU
- CPU 中止当前程序的执行,调出 OS(中断处理程序)来执行
- 处理结束后,再返回到被中止的程序继续执行
- OS 是被动调出的,也称为中断驱动 I/O 方式
- 直接存储器存取(DMA 方式):磁盘等高速外设特有的 I/O 方式
- 磁盘等高速外设成批地直接和主存进行数据交换
- 需要专门的 DMA 控制器控制总线,完成数据传送
- 当外设准备好数据后,向 DMA 控制器发 DMA 请求信号,DMA 控制器再向 CPU 发总线请求,
CPU 让出总线后,由 DMA 控制器控制总线进行传输,无需 CPU 干涉
程序直接控制方式
无条件传送方式:
条件传送方式:
中断 I/O 方式
中断系统
基本思想:当外设准备好时,便向 CPU 发中断请求,CPU 响应后,中止现行程序的执行,转入一个「中断服务程序」进行输入/出操作,实现主机和外设接口之间的数据传送,并启动外设工作。 「中断服务程序」执行完后,返回原被中止的程序断点处继续执行。此时,外设和 CPU 并行工作。
中断 I/O 方式的基本过程:
中断系统的基本职能:
- 及时记录各种中断请求信号:通常用一个中断请求寄存器来保存。
- 自动响应中断请求:CPU在每条指令执行完、下条指令取出前,自动检测中断,并根据情况决定是否响应和响应哪个中断。
- 自动判优:判断中断优先级,选择优先级最高的中断先响应。
- 保护被中断程序的断点和现场:原程序被中止处的指令地址和原程序的程序状态和各寄存器的内容等必须被保存,以便能正确回到原被中止处继续执行。
- 中断屏蔽:通过中断屏蔽实现多重中断的嵌套执行,中断屏蔽功能通过一个中断屏蔽字寄存器来实现。
中断控制器的基本结构:
中断处理过程
中断过程:中断响应 + 中断处理
- 中断响应:调出相应的中断服务程序(处在「禁止中断」状态)
- 中断处理:执行相应中断服务程序的过程
- 不同的中断源其对应的中断服务程序不同
典型的多重中断处理(中断服务程序)分为三个阶段:
- 先行段(准备阶段)
- 保护现场及旧屏蔽字
- 查明原因(软件识别中断时)
- 设置新屏蔽字
- 开中断
- 注:前三个步骤处于「禁止中断」状态,不允许被打断
- 本体段(具体的中断处理阶段)
- 注:处于「允许中断」状态,可被新的处理优先级更高的中断打断
- 结束段(恢复阶段)
- 关中断
- 恢复现场及旧屏蔽字
- 清「中断请求」
- 开中断
- 中断返回
- 注:处在「禁止中断」状态,不允许被打断
「单重中断」不允许在中断处理时被新的中断打断,因而直到中断返回前才会开中断。单重中断系统无需设置中断屏蔽字。
多重中断
在一个中断处理(即执行中断服务程序)过程中,若又有新的中断请求发生,而新中断优先级高于正在执行的中断,则应立即中止正在执行的中断服务程序,转去处理新的中断。这种情况为多重中断,也称中断嵌套。
中断优先权的动态分配:
- 中断响应优先级:由查询程序或硬联排队线路决定的优先权,反映多个中断同时请求时选择哪个响应。
- 中断处理优先级:由各自的中断屏蔽字来动态设定,反映本中断与其它中断间的关系。
多重中断嵌套:
解答
中断屏蔽位:
程序运行过程示意图:
初学的 Typst 源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77#import "@preview/fletcher:0.5.3": *
#table(
rows: 7,
columns: 6,
align: center + horizon,
table.cell(rowspan: 2, "中断程序级别"),
table.cell(colspan: 5, "中断屏蔽字"),
[1 级], [2 级], [3 级], [4 级], [5 级],
[第 1 级], [1], [0], [0], [0], [0],
[第 2 级], [1], [1], [0], [1], [1],
[第 3 级], [1], [1], [1], [1], [1],
[第 4 级], [1], [0], [0], [1], [0],
[第 5 级], [1], [0], [0], [1], [1],
)
#let c = (orange, red, green, blue, yellow, purple).map(x => x.lighten(50%))
#let back = arguments("dashed", stroke: 1pt + black.lighten(50%))
#let main = arguments(stroke: 2pt)
#let hor = arguments("dashed", stroke: 1.2pt)
#let e1 = (p1, p2) => edge(p1, p2, …main)
#let e2 = (p1, p2) => edge(p1, p2, …hor)
#diagram(
// debug: 2,
spacing: 10pt,
node-corner-radius: 3pt,
axes: (ltr, btt),
cell-size: 2mm,
node((0, 0), [主程序], fill: c.at(0), width: 30mm, height: 5mm),
node((0, 1), [中断服务 1], fill: c.at(1), width: 30mm, height: 5mm),
node((0, 2), [中断服务 2], fill: c.at(2), width: 30mm, height: 5mm),
node((0, 3), [中断服务 3], fill: c.at(3), width: 30mm, height: 5mm),
node((0, 4), [中断服务 4], fill: c.at(4), width: 30mm, height: 5mm),
node((0, 5), [中断服务 5], fill: c.at(5), width: 30mm, height: 5mm),
edge((0, 0), (25, 0), …back),
edge((0, 1), (25, 1), …back),
edge((0, 2), (25, 2), …back),
edge((0, 3), (25, 3), …back),
edge((0, 4), (25, 4), …back),
edge((0, 5), (25, 5), …back),
e1((0, 0), (3, 0)),
e2((3, 0), (3, 2)),
e1((3, 2), (4, 2)),
e2((4, 2), (4, 4)),
e1((4, 4), (7, 4)),
e2((7, 4), (7, 2)),
e1((7, 2), (8, 2)),
e2((8, 2), (8, 1)),
e1((8, 1), (11, 1)),
e2((11, 1), (11, 2)),
e1((11, 2), (12, 2)),
e2((12, 2), (12, 5)),
e1((12, 5), (15, 5)),
e2((15, 5), (15, 2)),
e1((15, 2), (18, 2)),
e2((18, 2), (18, 0)),
e1((18, 0), (19, 0)),
e2((19, 0), (19, 3)),
e1((19, 3), (22, 3)),
e2((22, 3), (22, 0)),
e1((22, 0), (25, 0)),
)
程序控制方式和中断方式的比较
- 对主机占用率:在进行 I/O 操作过程中,处理器有多少时间花费在输入/出操作上。
- 数据传送速度(吞吐量、I/O 带宽):单位时间内传送的数据量。
中断响应过程
中断过程:
- 中断检测(硬件实现)
- 中断响应(硬件实现)
- 中断处理(软件实现)
中断识别和判优方法
- 软件方法:轮询
- 硬件方法:向量中断
DMA 方式
DMA,即直接存储器存取(Direct Memory Access),是一种无需 CPU 参与的数据传送方式。
为什么要引入 DMA?
- 程序直接控制方式受「踏步」现象的限制,效率低下,不适合高速设备和主机间的数据传送。
- 中断控制方式虽比程序直接控制方式有效,CPU 和外设有一定的并行度,但由于下列原因也不适合高速设备和主机间的数据传送。
- 对 I/O 请求响应慢:每传送一个数据都要等待外设的中断请求,并增加许多中断响应和中断处理前、后的附加开销(保护断点、现场等),不能及时响应 I/O 请求。
- 数据传送速度慢:数据传送由软件完成(由 CPU 执行相应的中断服务程序来完成),速度慢 。
DMA 方法的基本思想:在高速外设和主存间直接传送数据。由专门硬件(即:DMA 接口)控制总线进行传输
适用场合:高速设备(如:磁盘、光盘等);成批数据交换,且数据间间隔时间短,一旦启动,数据连续读写。
DMA 方式采用「请求-响应」方式:每当高速设备准备好数据,就进行一次「DMA 请求」,DMA 控制器接受到 DMA 请求后,申请总线使用权。
DMA 控制器的总线使用优先级比 CPU 高。
与中断控制方式结合使用
- DMA 传送前,寻道、旋转等操作结束时,通过「中断」告知 CPU
- 在 DMA 控制器控制总线进行数据传送时,CPU 执行其他程序
- DMA 传送结束时,要通过「DMA 结束中断」告知 CPU
由于 DMA 接口和 CPU 共享主存,所以可能出现两者争用主存的现象,为使两者协调使用主存,DMA 通常采用以下三种方式进行数据传送:
- CPU 停止法(成组传送)
- DMA 传输时,CPU 脱离总线,停止访问主存,直到 DMA 传送一块数据结束。
- 周期挪用(窃取)法(单字传送)
- DMA 传输时,CPU 让出一个总线事务周期,由 DMA 控制总线来访问主存,传送完一个数据后立即释放总线。
- 交替分时访问法
- 每个存储周期分成两个时间片,一个给 CPU,一个给 DMA,这样在每个存储周期内,CPU 和 DMA 都可访问存储器。
CPU 停止法
优点:控制简单、适用于传输率很高的外设实现成组数据传送。
缺点:
- CPU 工作受影响:DMA 访存时 CPU 基本上处于停止状态。
- 主存周期没有被充分利用:即使 I/O 设备高速运行,但两个数据之间的准备间隔时间也总大于一个存储周期,所以主存周期没有被充分利用。
弥补缺点的做法:
- 在 DMA 接口中引入缓冲器
- 在 DMA 接口中采用一个小容量的半导体存储器,使 I/O 设备先和这个小容量存储器交换数据,然后再使用总线由小容量存储器与主存进行数据交换。这样可减少 DMA 传送数据时占用总线的时间,也就减少了 CPU 的等待时间。
- 采用周期挪用(窃取)法
- 挪用一个存储周期进行外设和主存的一个数据交换。
- 每次 DMA 传送完一个数据就释放总线,使在外设准备下一数据时,CPU 能插空访问主存。
周期挪用(窃取)法
优点:既能及时响应 I/O 请求,又能较好地发挥 CPU 和主存的效率。
- 这种方式下,在下一数据的准备阶段,主存周期被 CPU 充分利用。因此适合于 I/O 设备的读写周期大于主存周期的情况。
缺点:每次 DMA 访存都要申请总线控制权、占用总线进行传送、释放总线,因此,会增加传输开销。
I/O 设备要求 DMA 传送时可能会遇到以下三种情况之一:
- CPU 不需访问主存
- 此时,不会发生冲突,两者并行。
- 如: CPU 正在执行乘法指令,要花很长时间而不需马上访存。
- CPU 正在访问主存
- 此时须等到存储周期结束,CPU 让出总线,DMA 才能访存。
- CPU 也同时要访问主存
- 此时出现访存冲突。因为不马上响应 DMA 请求的话,高速设备可能会发生数据丢失,所以,DMA 的总线优先权比 CPU 高。这时,先让 DMA 占用总线,窃取一个主存周期,完成一个数据的交换。这样,CPU 便要延迟一段时间才能访存。
DMA 方式下的系统逻辑结构:
DMA 控制器的功能
DMA 数据传送过程由 DMA 接口的控制逻辑完成,所以 DMA 接口也称 DMA 控制器。其功能为:
- 请求:能接收外设发来的「DMA 请求」信号,并能向 CPU 发「总线请求」信号。
- 响应:当 CPU 发出「总线响应」信号响应请求后,能接管对总线的控制。
- 修改主存地址:能在地址线上给出主存地址,并自动修改主存地址。
- 识别传送方向:能识别传送方向以在控制线上给出正确的读写控制信息。
- 确定传送数据个数。
- 能发出 DMA 结束信号:引起一次 DMA 中断,进行数据校验等一些后处理。
DMA 操作步骤:
- DMA 控制器的预置(初始化):软件实现
- 准备内存
- 设置参数
- 启动外设
- DMA 数据传送:硬件实现
- DMA 请求:选通 -> DMA 请求 -> 总线请求
- DMA 响应:总线响应(CPU 让出总线) -> DMA 响应
- DMA 传送:DMA 控制总线进行数据传送
- DMA 结束处理:软件实现
- 根据计数值为「0」,发出 DMA 结束信号去接口控制产生 DMA 中断请求信号,转入中断服务程序,做一些数据校验等后处理工作。
具体略了。
DMA 方式和中断方式的区别
- DMA 方式下数据传送由硬件(DMA 控制器)完成;中断方式下,数据传送由软件(CPU 执行中断服务程序)完成。
- DMA 请求的是对存储器访问,也即对总线控制权的请求,没有中止现行程序的必要;而中断请求要处理器转去执行中断服务程序,因此要中止现行程序,保存断点、现场等。
- 中断除了能完成外设和主机的数据交换,还能处理异常事件;而 DMA 方式下不能处理异常事件。
- 中断响应在一个指令周期结束后;而 DMA 响应是在一个总线周期后。
- DMA 方式用于高速设备;而中断方式用于低、慢速设备。
- DMA 方式下,外设与 CPU 并行度高;而中断方式下,外设与 CPU 并行度低。(体现在数据传送时的并行性)
内核空间 I/O 软件
I/O 子系统
所有高级语言的运行时(runtime)都提供了执行 I/O 功能的机制。例如 C 中的 printf
, scanf
等标准 I/O 库函数。
从高级语言程序中通过 I/O 函数或 I/O 操作符提出 I/O 请求,到设备响应并完成 I/O 请求,涉及到多层次 I/O 软件和 I/O 硬件的协作:
- 用户空间 I/O 软件:提出 I/O 请求
- 内核空间 I/O 软件:在底层操作系统中对 I/O 进行具体管理和控制
- I/O 硬件:在操作系统内核空间 I/O 软件的控制下完成具体的 I/O 操作。
从用户 I/O 软件切换到内核 I/O 软件的唯一办法是「异常」机制:系统调用(自陷)。
各类用户的 I/O 请求需要通过某种方式传给 OS:
- 最终用户:键盘、鼠标通过操作界面传递给 OS
- 用户程序:通过函数(高级语言)转换为系统调用传递给 OS
I/O 软件被组织成从高到低四个层次:
- 用户层 I/O 软件(I/O 函数调用系统调用)
- 与设备无关的操作系统 I/O 软件
- 设备驱动程序
- I/O 中断处理程序
后面三个是内核空间的 I/O 软件,即操作系统(Operating System, OS)。
大部分 I/O 软件都属于操作系统内核态程序,最初的 I/O 请求在用户程序中提出。
OS 的职责由 I/O 系统的三个特性决定:
- 共享性:I/O 系统被处理器执行的多个程序共享,由 OS 统一调度管理
- 复杂性:I/O 设备控制的细节比较复杂,不能由上层用户程序来实现,需 OS 提供专门的驱动程序
- 采用中断 I/O 方式:I/O 系统通常使用外部中断请求来要求处理器执行专门的输入/出程序。中断导致向内核态转移,故必须由 OS 来处理
OS 在 I/O 中的职能:
- 保证用户程序只能访问自己有权访问的那部分 I/O 设备
- 为用户程序提供设备驱动程序以屏蔽设备控制的细节
- 处理外部 I/O 中断,提供中断服务程序
- 对共享的 I/O 资源提供合理的调度管理,使系统的吞吐率达到最佳
主机必须和 I/O 设备进行以下三类信息的通信:
- OS 必须能向 I/O 设备提供命令,如:磁盘寻道
- 需要知道:何时 I/O 设备能完成操作?何时遇到什么异常问题?
- 数据必须能在主机(主存或 CPU)和 I/O 设备之间进行传输
用户程序总是通过某种 I/O 函数或 I/O 操作符请求 I/O 操作。
例如读一个磁盘文件记录时,可调用 C 标准 I/O 库函数 fread()
,也可直接调用系统调用封装函数 read()
来提出 I/O 请求。
不管是 C 库函数、API 函数还是系统调用封装函数,最终都通过操作系统内核提供的系统调用来实现 I/O。
Linux 系统中 printf
函数调用过程:
执行过程:
设备无关 I/O 软件
操作系统为所有外设的设备驱动程序规定一个统一接口,这样,新设备的驱动程序只要按统一接口规范来编制,就可在不修改操作系统的情况下,添加新设备驱动程序并使用新的外设进行I/O。
所有设备都抽象成文件,设备名和文件名在形式上没有差别,设备和文件具有统一的接口,不同设备名和文件名被映射到对应设备驱动程序。
每个设备的 I/O 都需使用内核缓冲区,因而缓冲区的申请和管理等处理是所有设备公共的,可包含在与设备无关的 I/O 软件部分。
错误报告:
- I/O 操作在内核态执行时所发生的错误信息,都通过与设备无关的 I/O 软件返回给用户进程,也即:错误处理框架与设备无关。
- 直接返回编程等错误,无需设备驱动程序处理,如,请求了不可能的 I/O 操作;写信息到一个输入设备或从一个输出设备读信息;指定了一个无效缓冲区地址或者参数;指定了不存在的设备等。
- 有些错误由设备驱动程序检测出来并处理,若驱动程序无法处理,则将错误信息返回给设备无关 I/O 软件,再由设备无关 I/O 软件返回给用户进程,如写一个已被破坏的磁盘扇区;打印机缺纸;读一个已关闭的设备等。
设备驱动程序
每个外设具体的 I/O 操作需通过执行设备驱动程序来完成
外设种类繁多、其控制接口不一,导致不同外设的设备驱动程序千差万别,因而设备驱动程序与设备相关。
每个外设或每类外设都有一个设备控制器,其中包含各种 I/O 端口。 CPU 通过执行设备驱动程序中的 I/O 指令访问个各种 I/O 端口
设备所采用的 I/O 控制方式不同,驱动程序的实现方式也不同
- 程序直接控制:驱动程序完成用户程序的 I/O 请求后才结束。
- 这种情况下,用户进程在 I/O 过程中不会被阻塞,内核空间的 I/O 软件一直代表用户进程在内核态进行 I/O 处理。
- 中断控制:驱动程序启动第一次 I/O 操作后,将调出其他进程执行,而当前用户进程被阻塞。
- 在 CPU 执行其他进程的同时,外设进行 I/O 操作,此时,CPU 和外设并行工作。外设完成 I/O 时,向 CPU 发中断请求,然后 CPU 调出相应中断服务程序执行。在中断服务程序中再次启动 I/O 操作。
- DMA 控制:
- 驱动程序对 DMA 控制器初始化后,便发送「启动 DMA 传送」命令,外设开始进行 I/O 操作并在外设和主存间传送数据。
- 同时 CPU 执行处理器调度程序,转其他进程执行,当前用户进程被阻塞。
- DMA 控制器完成所有 I/O 任务后,向 CPU 发送一个「DMA 完成」中断请求信号。
中断服务程序
中断控制和 DMA 控制两种方式下都需进行中断处理
- 中断控制方式:中断服务程序主要进行从数缓器取数或写数据到数缓器,然后启动外设工作
- DMA 控制方式:中断服务程序进行数据校验等后处理工作
在内核 I/O 软件中用到的 I/O 指令、「开中断」和「关中断」等指令都是特权指令,只能在操作系统内核程序中使用。