# 设备管理概述
# 设备管理的功能与目标
操作系统中的 I/O 子系统负责管理计算机的所有输入输出设备,是操作系统的核心功能之一。其主要功能和目标包括:
- 控制设备操作:按照用户的请求,控制设备的各种操作,完成 I/O 设备与内存之间的数据交换。
- 提供统一接口:在设备和系统的其他部分之间提供一个简单、统一且易于使用的接口,使用户能够方便地使用外部设备,摆脱繁琐的底层编程。
- 实现设备无关性(设备独立性):允许用户在编程时使用逻辑设备名,由操作系统负责实现从逻辑设备到物理设备的转换和映射。这意味着用户的程序可以独立于具体的物理设备运行。
- 提高处理效率:充分利用中断、DMA、缓冲、通道等技术,提高 CPU 与设备、设备与设备之间的并行工作能力,充分利用系统资源。
- 设备分配与管理:在多道程序环境下,当多个进程竞争使用设备时,按照特定的策略对设备进行分配和回收,确保系统工作井然有序。
- 错误处理与数据保护:设备管理应能处理 I/O 操作中出现的错误,并确保数据在传输和管理过程中的安全性、完整性和保密性。
# 设备管理的特点
设备管理是操作系统设计中庞大而复杂的一部分,其主要特点如下:
- 速度差异巨大:CPU 与 I/O 设备的速度存在巨大差异,I/O 设备的性能常常成为整个系统的瓶颈。操作系统必须有效协调这种速度不匹配。
- 资源繁杂:I/O 设备种类繁多,特性各异,管理复杂。
- 并发性强:多个进程可能同时请求 I/O 操作,导致对设备和资源的激烈竞争。
- 关联性强:设备管理与其他子系统(尤其是文件系统)联系紧密。理解 I/O 的工作原理是理解整个操作系统工作流程的关键。
# I/O 硬件原理
# I/O 设备的分类
I/O 设备可以根据不同的标准进行分类:
-
按数据组织分类
- 块设备:以数据块为单位存储和传输信息,如硬盘、SSD。
- 字符设备:以字符为单位存储和传输信息,如键盘、鼠标、打印机。
- 其他设备:如时钟、定时器,它们既不是块设备也不是字符设备。
-
按功能特性分类
- 存储型设备:用于数据的长期存储,如磁盘、磁带。
- 输入输出型设备(交互型设备):用于人机交互,如键盘、显示器。
- 数据通信设备:用于设备间的数据传输,如网卡、调制解调器。
-
从资源分配角度分类
- 独占设备:在一段时间内只能由一个进程使用的设备,如打印机、磁带机。
- 共享设备:在一段时间内可由多个进程交叉共同使用的设备,如硬盘。
# I/O 设备的组成
I/O 设备通常由两部分组成,这种分离设计提供了更好的模块化和通用性。
- 机械部分:设备本身的物理装置。
- 电子部分:即设备控制器或适配器,负责实现设备与主机间的连接和通信。

# 设备控制器
设备控制器是连接设备与计算机总线的核心部件,它通过内部的寄存器与 CPU 进行通信。
功能:
- 地址译码:识别 CPU 发送给其端口的地址信号。
- 数据与信号转换:接收主机发来的数据和控制信号,并将其转换为设备能识别的格式(如数字信号转模拟信号);反之,将设备的状态和数据转换后发送给主机。
- 数据缓冲与加工:内置硬件缓冲区,用于临时存放数据,以协调主机与设备之间的速度差异。
- 状态报告:向 CPU 报告设备的工作状态。
# 设备接口与端口编址
操作系统通过读写设备控制器中的寄存器(I/O 端口)来控制设备。这些寄存器主要包括控制寄存器、状态寄存器和数据缓冲区。
# 端口编址方法
为 I/O 端口分配地址主要有以下几种方式:
-
I/O 独立编址(I/O-Mapped I/O)
- 为 I/O 端口分配独立的地址空间,与内存地址空间无关。
- 主机必须使用专门的 I/O 指令(如
IN,OUT)来访问这些端口。
-
内存映射编址(Memory-Mapped I/O)
- 将 I/O 端口地址映射到内存地址空间中,使之成为内存地址的一部分。
- 主机可以像访问普通内存单元一样,使用标准的内存读写指令来访问 I/O 端口。大部分现代处理器采用此方式。
- 优点:
- 无需专用 I/O 指令,C/C++ 等高级语言可以直接通过指针访问设备寄存器。
- 无需特殊的内存保护机制,只需将包含设备寄存器的地址空间从用户进程的虚拟地址空间中移除即可。
- 所有可以访问内存的指令都可以用于访问设备寄存器。
- 缺点:
- 高速缓存问题:对设备寄存器的访问不应被缓存,否则可能导致读取到旧的状态或写入命令未立即送达设备。硬件必须提供选择性禁用页面缓存的功能。
- 总线竞争:在单总线结构中,所有设备和内存模块都需要响应地址请求,影响性能。在多总线结构中,需要特殊设计来支持内存映射 I/O。

-
混合编址方案
- 结合以上两种方式,例如数据缓冲区使用内存映射 I/O,而控制/状态寄存器使用独立 I/O 端口。PC 机便采用此方案。
# I/O 控制方式
数据在内存与 I/O 设备之间的交换主要有以下几种控制方式:
- 程序控制 I/O (轮询):CPU 主动、持续地查询设备状态,直到 I/O 操作完成。此方式会长时间占用 CPU。
- 中断驱动 I/O:CPU 启动 I/O 操作后,可以转去执行其他任务。当 I/O 操作完成时,设备控制器通过发送中断信号来通知 CPU。
- 直接内存存取 (DMA):数据在内存和 I/O 设备之间直接成块传送,无需 CPU 介入,由专门的 DMA 控制器完成。
- 通道:更进一步的 I/O 控制方式,由专门的 I/O 处理器(通道)来执行 I/O 指令,将 CPU 从 I/O 事务中完全解放出来。
# 中断驱动 I/O
- 工作流程:
- CPU 启动 I/O 设备。
- 设备控制器独立执行操作。
- 操作完成后,控制器向 CPU 发送中断信号。
- CPU 暂停当前任务,保存现场(如程序计数器、寄存器值)到栈中。
- 根据中断信号查找中断向量表,找到对应的中断服务程序入口地址并执行。
- 中断处理完毕后,恢复现场,返回到被中断的程序继续执行。
- 现代 CPU 的挑战:在采用流水线和超标量技术的 CPU 上,中断发生时,已执行和未执行指令的边界可能不明确,给精确保存和恢复现场带来挑战。

# 直接内存存取 (DMA)
- 目的:解决中断驱动 I/O 中每个字符(或字)都需要中断一次,CPU 开销大的问题。DMA 允许数据在内存和设备间直接成块传输。
- 工作流程:
- CPU 向 DMA 控制器发出指令,提供源地址、目标地址、数据块大小等信息。
- CPU 转去执行其他任务。
- DMA 控制器接管总线控制权(通过周期窃取方式),直接在内存和设备间传输数据。
- 数据传输完成后,DMA 控制器向 CPU 发送一次中断信号。
- CPU 响应中断,进行后续处理。
- 与中断驱动 I/O 的区别:
- 中断次数:中断驱动方式每个数据单元(如字节)中断一次,DMA 方式整个数据块传输完才中断一次。
- 数据传送控制:中断驱动方式的数据传送由 CPU 控制,而 DMA 方式由 DMA 控制器控制,不经过 CPU。

# 通道
- 通道,又称 I/O 处理器(IOP),是一种更为强大的 I/O 控制器,它能执行自己的指令(通道程序),管理多台外设,进一步将 CPU 从 I/O 事务中解放出来。
- 工作特点:
- CPU 与通道可以并行工作。
- 通道与通道之间可以并行工作。
- 各通道上的外围设备可以并行操作。
- I/O 过程:CPU 只需向通道发出启动 I/O 的指令,通道便会执行预设的通道程序来完成整个 I/O 过程,完成后再通过中断通知 CPU。
- 通道类型:
- 字节多路通道:以分时方式同时为多个低速设备服务。
- 选择通道:一次选择一台高速设备,独占地为其传输数据。
- 数组多路通道:结合了前两者的特点,可以同时为多个高速设备服务。
# I/O 软件技术
# I/O 软件的设计目标
I/O 软件旨在向高层提供抽象、统一的接口,同时隐藏硬件的复杂性。其核心设计目标包括:
- 设备独立性 (Device Independence):用户程序应能访问任何类型的 I/O 设备而无需关心其具体物理特性。例如,一个排序程序既可以从键盘读入,也可以从文件读入,其输出既可以到屏幕,也可以到文件。
- 统一命名 (Uniform Naming):文件和设备使用相同的命名空间和寻址方式。例如,在 UNIX/Linux 系统中,设备被抽象为
/dev目录下的特殊文件。 - 错误处理 (Error Handling):错误应在尽可能低的层次上处理。许多硬件相关的错误可由设备驱动程序透明地解决(如重试操作),无法解决的再向上层报告。
- 同步与异步传输:I/O 操作本质上多为异步的(中断驱动),但操作系统通常向用户程序提供同步(阻塞式)的接口,因为这更易于编程。操作系统负责在底层将异步操作封装成同步接口。
- 缓冲 (Buffering):在设备和内存之间引入缓冲区,以缓和 CPU 与 I/O 设备之间巨大的速度差异,提高系统并行度和吞吐量。
- 共享与独占设备的管理:为不同类型的设备提供合理的分配和访问控制策略。
# 缓冲技术
缓冲是提高 I/O 性能的关键技术。
-
无缓冲:CPU 计算和 I/O 传输完全串行,CPU 需等待 I/O 完成,效率低下。

-
单缓冲:引入一个缓冲区。当 CPU 将数据送入缓冲区后,即可进行下一次计算,与 I/O 设备的传输并行进行。

-
双缓冲(多缓冲):使用两个或多个缓冲区。CPU 向一个缓冲区写入数据时,设备可以从另一个缓冲区读取数据,进一步提高了并行度。

# SPOOLing 技术 (假脱机技术)
SPOOLing (Simultaneous Peripheral Operation On-Line) 是一种将独占设备(如打印机)虚拟为共享设备的技术,以提高设备利用率和系统效率。
- 工作原理:
- 当用户进程请求打印时,SPOOLing 系统并不直接分配打印机,而是在磁盘上开辟一块缓冲区(打印池)。
- 用户进程的打印数据被高速地写入该磁盘缓冲区。
- SPOOLing 系统维护一个打印任务队列,一个独立的后台进程(打印进程)会从队列中取出任务,并将磁盘缓冲区中的数据真正送到打印机上打印。
- 效果:对于用户进程而言,打印请求瞬间完成(因为写入磁盘速度很快),进程无需等待慢速的打印机。系统可以将多个打印任务缓存起来,实现对独占设备的共享访问。
# I/O 软件层次结构
I/O 软件通常采用分层结构,每一层都利用其下层提供的服务,并向其上层提供更高级、更抽象的服务。

# 硬件层
最底层,负责执行实际的物理 I/O 操作。
# 中断处理程序
- 作为 I/O 操作完成的入口,深深隐藏在操作系统内部。
- 当 I/O 完成时,硬件产生中断,中断处理程序被激活。
- 主要任务是保存现场,分析中断原因,并唤醒因等待该 I/O 而被阻塞的设备驱动程序进程(例如通过 V 操作、signal 或 send 消息)。
# 设备驱动程序
- 与硬件直接交互的软件层,每种类型的设备都有其对应的驱动程序。
- 主要任务:
- 接收上层(与设备无关的软件)发出的抽象请求(如
read,write)。 - 将抽象请求转换为对设备控制器的具体操作(如向寄存器写入命令和参数)。
- 启动设备,并通常会阻塞自身,等待 I/O 操作完成的中断。
- 处理设备特有的错误。
- 接收上层(与设备无关的软件)发出的抽象请求(如

# 与设备无关的 I/O 软件
- 该层为所有设备提供统一的接口,并执行所有设备共有的功能。
- 主要功能:
- 统一驱动接口:为上层提供统一的函数调用接口(如
read,write)。 - 设备命名:将符号化的设备名(如
/dev/disk0)映射到对应的驱动程序。 - 设备保护:检查用户是否有权访问所请求的设备。
- 缓冲管理:管理和调度系统中的缓冲区。
- 提供与设备无关的块大小:隐藏不同设备物理块大小的差异。
- 分配与释放独占设备:管理独占设备的分配。
- 错误报告:向更高层报告设备驱动无法处理的错误。
- 统一驱动接口:为上层提供统一的函数调用接口(如
# 用户空间的 I/O 软件
- 一部分 I/O 功能由运行在用户空间的库函数和应用程序提供。
- 库函数:标准 I/O 库(如 C 语言的
printf,scanf)将用户的请求进行格式化,并最终通过系统调用陷入内核。 - 假脱机系统 (SPOOLing):如打印后台服务,通常作为守护进程在用户空间运行。
# 典型 I/O 设备
# 时钟 (Clock/Timer)
时钟是计算机系统的脉搏,负责计时和提供定时中断,它既不是块设备也不是字符设备。
- 时钟硬件:通常由晶体振荡器、计数器和存储寄存器组成。晶体振荡器产生精确的脉冲信号,使计数器递减,当计数器为 0 时产生中断。
- 操作模式:
- 一次完成模式:产生一次中断后即停止,需软件重新启动。
- 方波模式:周期性地产生中断,也称为时钟滴答 (clock tick)。
- 时钟软件 (时钟驱动程序):
- 维护日历时间。
- 为进程调度提供时间片。
- 对 CPU 使用情况进行记账。
- 处理用户的
alarm系统调用。 - 为系统提供各种定时器。
# 人机交互设备
# 键盘
- 分类:主要有机械式、薄膜式、导电橡胶式和静电电容式等。
- 工作原理:
- 键盘内部控制器通过扫描矩阵检测按键的按下和松开。
- 为每个动作生成一个唯一的扫描码(Scan Code)。
- 控制器通过接口将扫描码发送给主机,并产生键盘中断。
- 主机的键盘驱动程序接收扫描码,将其转换为相应的字符编码(如 ASCII),并存入键盘缓冲区。
# 鼠标
- 分类:按结构可分为机械式和光电式;按接口可分为 PS/2、USB 等。
- 光电鼠标工作原理:
- 底部的 LED 发出光线照亮表面。
- 光学传感器高速、连续地拍摄表面图像。
- 内部的图像分析芯片(DSP)通过比较连续图像上特征点的变化,计算出鼠标的移动方向和距离。
- 将移动信息通过接口传送给主机。
# 显卡与显示器
- 显卡 (显示适配器):负责将 CPU 送来的图像数据处理成显示器能识别的信号。
- 工作流程:CPU 将数据传送到显存 -> GPU (图形处理单元) 进行 3D 建模和渲染 -> RAMDAC (数模转换器) 将数字信号转为模拟信号 -> 通过接口输出到显示器。
- 主流显示芯片厂商:NVIDIA, Intel, AMD。
- 显示器:最重要的输出设备,目前主流是 LCD(液晶)显示器。它利用电场改变液晶分子的排列,从而控制光线的通过,形成图像。
# 存储设备
# 硬盘 (Hard Disk Drive - HDD)
- 结构:
- 盘片 (Platter):存储数据的磁性圆盘,每个盘片有两个盘面。
- 磁头 (Head):每个盘面对应一个读写磁头,所有磁头固定在磁头臂上同步移动。
- 磁道 (Track):盘面上的同心圆。
- 扇区 (Sector):磁道被划分成的小段,是数据读写的最小单位(通常为 512 字节)。
- 柱面 (Cylinder):所有盘面上半径相同的磁道构成的圆柱体。硬盘读写数据优先在同一柱面内进行,以减少磁头移动。

-
磁盘寻址
- CHS (Cylinder-Head-Sector):使用 (柱面号, 磁头号, 扇区号) 三元组定位扇区。
- LBA (Logical Block Addressing):将磁盘空间视为一个线性的扇区序列,用一个逻辑块号来寻址,屏蔽了底层的物理结构。
- CHS 与 LBA 转换公式:
(其中 HPC 为每柱面磁头数,SPT 为每磁道扇区数)
-
磁盘 I/O 访问时间
访问时间 = 寻道时间 + 旋转延迟时间 + 传输时间- 寻道时间 ():磁头移动到目标磁道所需的时间,是访问时间的主要部分。
- 旋转延迟时间 ():等待目标扇区旋转到磁头下方所需的时间。
- 传输时间 ():实际读写数据所需的时间。
-
磁盘臂调度算法
为了减少平均寻道时间,操作系统采用多种调度算法来处理磁盘 I/O 请求队列。- 先来先服务 (FCFS):公平但效率低。
- 最短寻道时间优先 (SSTF):优先处理离当前磁头位置最近的请求,可能导致边缘磁道的请求“饥饿”。
- 电梯算法 (SCAN):磁头在一个方向上移动,处理所有沿途的请求,到达一端后再反向移动。解决了饥饿问题,但对两端磁道不公平。
- 单向扫描算法 (C-SCAN):只在一个方向上处理请求,到达一端后立即返回另一端,重新开始扫描。提供了更均匀的等待时间。
# 廉价磁盘冗余阵列 (RAID)
RAID (Redundant Array of Independent Disks) 通过将多个独立的磁盘组合成一个逻辑单元,来提高 I/O 性能和数据可靠性。
-
核心技术:
- 条带化 (Striping):将数据分割成条带,并行地写入多个磁盘,大幅提升读写速度。
- 冗余 (Redundancy):通过镜像或奇偶校验等方式存储额外数据,以便在某个磁盘故障时恢复数据。
-
主要 RAID 级别:
- RAID 0:纯条带化,无冗余。读写性能最佳,但无容错能力。

- RAID 1:镜像。将数据完全复制到另一个磁盘。容错性高,但磁盘利用率只有 50%。

- RAID 2/3/4:使用专门的校验盘。RAID 4 的校验盘容易成为瓶颈。



- RAID 5:分布式奇偶校验。将奇偶校验信息交错分布在所有磁盘上,解决了校验盘的瓶颈问题,是性能、容量和可靠性的良好折中。允许一块磁盘故障。

- RAID 6:双重分布式奇偶校验。提供更高的容错能力,允许两块磁盘同时故障。

- 混合 RAID (RAID 10/01):结合了 RAID 1 和 RAID 0 的特性,兼具高性能和高可靠性。


- RAID 0:纯条带化,无冗余。读写性能最佳,但无容错能力。
# 固态硬盘 (Solid State Drive - SSD)
- 核心组件:NAND 闪存(存储数据)、控制器、固件。
- 工作原理:
- 存储单元:数据存储在 NAND 闪存的浮栅晶体管中。通过在浮栅极中存储或释放电子来表示 0 或 1。
- 读写单位:读写操作以页 (Page) 为单位,通常为 4KB 或 8KB。
- 擦除单位:擦除操作以块 (Block) 为单位,一个块包含多个页。
- 写前擦除:NAND 闪存无法直接覆盖写入。要修改一个页,必须先将整个块的数据读出,在内存中修改,然后擦除整个块,最后将修改后的数据写回。这个过程称为垃圾回收 (Garbage Collection)。
- 优势 (vs. HDD):
- 速度快:无机械寻道和旋转延迟,随机读写性能极高。
- 抗震性强:无移动部件。
- 功耗低、无噪音。
- 劣势 (vs. HDD):
- 成本高:单位容量价格更高。
- 寿命限制:闪存单元有有限的擦写次数 (P/E cycles)。
- 数据恢复困难:损坏后数据难以通过物理手段恢复。