Appearance
设备驱动程序接口
2026 大纲 五(二)4 设备驱动程序接口,属「设备独立软件」层。
上面统一了,下面的差异总得有人吃掉
软件层次说驱动程序是唯一真正碰硬件细节的一层, 应用程序接口说上层要给应用一套统一的调用形式。 把这两句放在一起,驱动程序的职责就自己浮出来了:
上面要统一,下面各不相同,中间这层就得把差异全吃掉。
具体到一次操作:设备独立软件递下来的是一个抽象请求—— "把这 512 字节写到第 3800 号逻辑块"。驱动要做的是把它翻译成 对这一款控制器的具体操作:算出柱面/磁头/扇区、往哪几个端口写什么值、 按什么顺序写、写完怎么判断成功。换一款控制器,这套翻译全部作废。
所以驱动的"接口统一"统一的是函数签名与调用约定(内核规定"你必须提供一个 名叫 read 的函数、参数长这样"),差异被封在函数体里面。 这与 VFS 用函数指针适配不同文件系统,是同一个手法。
有一条推论容易被忽略,但真题正好考它:驱动程序与 I/O 控制方式紧密相关。 同一款设备,用轮询写、用中断写、用 DMA 写,驱动的代码结构完全不同—— 轮询要循环读状态位,中断要注册处理程序并在启动后阻塞自己, DMA 还要额外配置 DMA 控制器的那几个寄存器。 "驱动只管翻译、与控制方式无关"这句话是错的。
一、统一驱动程序接口
为了让添加一个新驱动变得容易,OS 要求每个驱动与内核之间的接口相同或相近,并把抽象设备名映射到相应驱动的入口。落到实现上就是一组同名函数:
| 接口函数 | 功能 |
|---|---|
open | 初始化设备,准备使用 |
close | 关闭设备,释放资源 |
read | 从设备读数据 |
write | 向设备写数据 |
ioctl | 设备特定的控制命令 |
| 中断处理入口 | 供中断发生时回调 |
设备独立软件手里拿的是一张表,表里第几项是 read 是固定的;至于这个 read 指向哪个驱动的哪段代码,由设备名映射的结果决定。
二、驱动程序的处理过程
驱动程序的主要任务是启动指定设备完成上层的 I/O 工作,但启动之前必须先做完准备工作。五个步骤,顺序不能乱:
| 步骤 | 做什么 | 为什么不能省 |
|---|---|---|
| ① 将抽象要求转换为具体要求 | 把上层给的盘块号换算成盘面号、磁道号、扇区号;确定命令、数据、参数分别送往控制器的哪个寄存器 | 上层根本不了解控制器的寄存器情况,只能发抽象命令;OS 中只有驱动同时了解抽象要求和寄存器布局 |
| ② 对服务请求进行校验 | 检查这个请求该设备能不能执行(向打印机发读请求、对以只读方式打开的设备发写请求,都是非法的) | 不校验就会把非法命令写进控制器,行为不可预知;校验出错要向 I/O 系统报告,由它决定终止进程还是只通知 |
| ③ 检查设备的状态 | 读控制器的状态寄存器到 CPU 寄存器,测试其中的状态位,确认设备处于就绪(接收就绪/发送就绪) | 只有设备就绪时启动才有意义;设备忙时启动会丢命令或丢数据 |
| ④ 传送必要的参数 | 向控制器的各寄存器写入数据与控制参数:命令寄存器(本次是收还是发)、方式寄存器(传送速率、字符长度、奇偶校验、停止位数)等 | 参数不齐全,控制器不知道按什么规格传;块设备需要传的参数更多 |
| ⑤ 启动 I/O 设备 | 向命令寄存器写入控制命令。字符设备写命令时把一个字符送给控制器;读命令则等待接收,通过反复读状态寄存器判断数据是否到达 | 前四步都是准备,这一步才真正让设备动起来 |
三、驱动程序与 I/O 控制方式紧密相关
这是驱动程序区别于一般程序的一条重要特点:同一台设备,采用不同的 I/O 控制方式,驱动程序的写法完全不同。
| I/O 控制方式 | 驱动程序里第 ⑤ 步之后长什么样 | 中断入口做什么 |
|---|---|---|
| 轮询方式 | 启动后驱动自己循环读状态寄存器,busy 变 0 就搬一个字,搬完再启动下一次 | 无中断入口 |
| 中断方式 | 启动后立刻阻塞返回;每传一个字来一次中断 | 从数据寄存器取一个字送内存,若未传完则再启动,传完则唤醒进程 |
| DMA 方式 | 第 ④ 步要多写三个寄存器(MAR、DC、命令),启动的是 DMA 控制器而不是逐字传送 | 整块传完才来一次中断,做数据校验与唤醒进程 |
四、驱动程序的其余特点
| 特点 | 说明 | 由此推出什么 |
|---|---|---|
| 设备特定 | 与控制器和设备的硬件特性紧密相关,不同类型设备配不同驱动;但多个相同的终端可共用一个终端驱动 | 驱动数量按"设备类型"计,不按"设备台数"计 |
| 运行在内核态 | 要直接读写控制器寄存器,还要被中断处理程序回调 | 驱动出错会拖垮整个内核,因此必须严格管理 |
| 部分用汇编书写、可固化在 ROM 中 | 与硬件紧密相关的那部分难以用高级语言表达 | 解释了为什么驱动难写、难移植 |
| 必须允许可重入 | 一个正在运行的驱动常会在一次调用完成前被再次调用 | 驱动内不能用全局变量保存单次请求的状态 |
| 可动态加载卸载 | 现代 OS 支持运行时加载新驱动 | 新增设备不必重新编译内核 |
设备处理方式的三种安排
教材按"处理设备时是否设置进程"把设备处理方式分三类:① 为每一类设备设置一个进程(适合较大的系统);② 全系统设置一个 I/O 进程(或分设输入进程与输出进程);③ 不设专门进程,只为各类设备提供驱动程序供用户或系统进程调用。第三种目前用得最多,也是我们默认讨论的那种。
五、驱动程序与中断处理的配合
- 驱动程序完成五步处理,设置好控制器寄存器,启动 I/O
- 驱动把控制权交回 I/O 系统并把自己阻塞,请求 I/O 的进程也被阻塞,CPU 转去执行其他进程
- I/O 完成后设备发出中断
- 中断处理程序响应中断:保存现场、判断中断原因与设备状态
- 驱动程序被唤醒,完成后续处理:把数据从控制器搬走、检查本次 I/O 是否出错、向上层报告执行情况、唤醒等待该 I/O 的进程
考点速记
- 驱动程序把抽象 I/O 请求翻译成对控制器的具体操作,是硬件与操作系统之间的接口程序,需根据硬件特性定制开发。
- 接口统一的是函数签名与调用约定,差异被封在驱动内部——这与 VFS 用函数指针适配不同文件系统是同一个手法。⚠️ 这组名字与应用程序 I/O 接口同名但分属两条边界。
- 处理过程五步:转换抽象要求 → 校验服务请求 → 检查设备状态 → 传送必要参数 → 启动 I/O 设备。次序由"从最便宜的检查到最不可逆的动作"决定。
- 启动后驱动把自己阻塞起来,等设备完成后由中断处理程序唤醒——处理机与设备的并行由此实现。所以进程在执行驱动程序时可能进入阻塞态。
- ⚠️驱动程序与 I/O 控制方式紧密相关:同一款设备用轮询、中断、DMA 写出来的驱动代码结构完全不同——轮询要循环读状态位,中断要注册处理程序并在启动后阻塞自己,DMA 还要配置 DMA 控制器的寄存器。"驱动与 I/O 控制方式无关"是错的。
- 初始化设备、读/写设备的操作都由驱动程序控制完成。
- 驱动必须运行在内核态(要执行 I/O 指令、访问设备寄存器),必须可重入(同一驱动可能被多个进程同时进入)。
- 字符设备与块设备不是同一种 I/O 方式:块设备可寻址、按块传输、走磁盘调度;字符设备不可寻址、按字符顺序收发。两者的驱动模型从根上就不同。
这一节在真题里被考过的形式:
两道题都是"判断关于驱动程序的四条叙述、选不正确的",而且两次的错项各踩一处。
- 判断驱动程序的四条叙述,选不正确的(2022-32)。错项是"驱动程序与 I/O 控制方式无关"。⚠️ 这正是速记第五条——轮询、中断、DMA 三种方式下驱动的写法完全不同。另三条都对:初始化设备由驱动控制完成、进程执行驱动程序时可能进入阻塞态(启动设备后就阻塞自己等中断,速记第四条)、读写设备的操作由驱动控制完成。
- 判断驱动程序的四条描述,选错误的(2026-31,与设备的基本概念共享)。错项是"字符设备、块设备都是同一种 I/O 方式"。另三条都对,其中"驱动程序需要设置统一的接口"与"需根据硬件特性定制开发"看似矛盾、实则正是速记第二条那句话的两半——签名统一、实现各异。
复习优先级:必须拿满,两道题各记一句话即可——驱动与 I/O 控制方式有关、 字符设备与块设备不是同一种 I/O 方式。速记第三条那五步的次序理由 (从最便宜的检查到最不可逆的动作)读懂即可,至今没单独考过; 第四条(驱动会阻塞自己)在 2022-32 里作为正确项出现过,也要记。
易错:认为驱动程序与 I/O 控制方式无关。同一款设备用轮询/中断/DMA 写出来的驱动完全不同。
易错:认为进程执行驱动程序时不会阻塞。启动设备后驱动就把自己阻塞了,等中断处理程序唤醒。
易错:认为"接口统一"和"按硬件定制"互相矛盾。统一的是函数签名与调用约定,差异封在函数体里。
易错:认为字符设备和块设备用同一种 I/O 方式。两者可否寻址、传输单位、驱动模型都不同。
易错:认为驱动程序可以运行在用户态。它要执行 I/O 指令、访问设备寄存器,必须在内核态。
教材出处
- 设备驱动程序的功能、五条特点(含"与 I/O 控制方式紧密相关""应允许可重入")与三类设备处理方式:汤小丹《计算机操作系统》6.4.1 节,印刷 p192–193
- 驱动程序处理过程的五个步骤(转换抽象要求、校验服务请求、检查设备状态、传送必要参数、启动 I/O 设备):同书 6.4.2 节,印刷 p193–194
- 驱动程序发出 I/O 命令后把控制返回 I/O 系统并阻塞自己,直到中断到来再被唤醒:同书 6.4 节,印刷 p195
相关知识
I/O 软件层次结构|输入输出应用程序接口|I/O 控制方式|设备的基本概念与分类|磁盘结构与调度