设备驱动程序接口
5.1.3 说驱动程序”与硬件直接相关”,这带来一个工程问题:世界上有成千上万种设备,每种都要写一个驱动程序,而这些驱动程序都要嵌进同一个操作系统里。
如果不加约束,操作系统就得为每一种设备单独适配一次。这一节讲的就是那道约束——操作系统规定一组统一的接口,谁想接进来,谁就按这组接口来实现。
机制
统一接口的两个方向
① 每个设备驱动程序与操作系统之间都有相同或相近的接口形式。 也就是说,操作系统给设备驱动程序规定了一组它必须支持的函数——open、read、write、close、中断处理入口等等。驱动程序作者只需把这组函数按自己设备的特性实现出来。
② 驱动程序与内核之间的接口相同。 内核不需要知道这是磁盘还是打印机,它只按同一张函数表去调用。
此外,操作系统还需要知道每个设备驱动程序需要提供的其他信息,例如设备类型、需要占用的中断号等。
这套机制与 4.3.4 虚拟文件系统中”下层文件系统必须提供 VFS 规定的一组函数”完全同构——都是”向上统一接口、向下规定约定”的分派模式,只是一个用于文件系统,一个用于设备。
驱动程序与普通程序的五点差异
驱动程序属于低级的系统例程,它与一般的应用程序及系统程序有明显差异:
① 它主要是请求 I/O 的进程与设备控制器之间的一个通信程序——它的职责是传递和翻译,不做业务逻辑。
② 它与设备控制器和 I/O 设备的硬件特性紧密相关——寄存器编号、命令字编码、时序要求,全都是这台设备特有的。
③ 它与 I/O 控制方式紧密相关——采用中断驱动还是 DMA,驱动程序的写法完全不同。
④ 由于与硬件紧密相关,其中一部分必须用汇编语言书写——某些寄存器操作和时序控制无法用高级语言精确表达。
⑤ 驱动程序应允许可重入。 这一条最值得解释:同一个驱动程序可能同时被多个进程调用(比如两个进程同时读磁盘),也可能在处理一个请求的过程中被中断、转而处理另一个请求。若驱动程序不可重入,这些并发调用就会互相破坏各自的中间状态。
边界
哪些工作不属于驱动程序
这一条与 5.1.3 的判据完全一致,此处只做归位:
属于驱动程序的:接收并检查针对本设备的 I/O 命令与参数、查询设备状态、把抽象要求翻译成具体要求(如逻辑块号 → 盘面/磁道/扇区)、写控制寄存器启动设备、响应本设备的中断。
不属于驱动程序的:通用的缓冲区管理、设备分配与回收、权限检查、逻辑设备名映射——这些换任何一台设备做法都一样,统统属于设备独立性软件。
判据仍然是那一句:换一台设备,这件事还成不成立。
为什么驱动程序必须可重入
这是本节唯一需要理解而非记忆的点。
可重入意味着:一个函数在执行到一半被打断、又被重新进入执行时,两次执行不会互相干扰。 做到这一点的关键是不使用全局的可变状态,所有中间结果都放在各自的栈或参数里。
驱动程序为什么会被重入,有两个来源:其一是多个进程同时请求同一台设备(磁盘尤其常见);其二是驱动程序执行期间来了本设备的中断,中断处理又要进入驱动程序的代码。
若驱动程序把中间状态存在一个全局变量里,第二次进入就会把第一次的状态覆盖掉,结果是数据读错、设备状态错乱——而且这种错误只在高并发时偶发,极难排查。
这与 2.3 同步与互斥关心的是同一类问题,只不过这里的解法不是加锁,而是从写法上就不留共享状态。
统一接口与设备独立性的关系
两者容易混,但一个面向”驱动程序的作者”,一个面向”用户程序的作者”:
设备驱动程序接口规定的是驱动程序必须向内核提供哪些函数,受益者是操作系统——它因此不必为每种设备单独适配。
设备独立性规定的是用户程序使用逻辑设备名,受益者是用户程序——它因此不必绑定具体设备。
两者一上一下,共同构成了”设备可插拔”这件事的两端。
对照速查
| 统一接口的两个方向 | |
|---|---|
| ① | 每个驱动程序与操作系统之间接口相同或相近 |
| ② | 驱动程序与内核之间接口相同(内核按同一张函数表调用) |
| 驱动程序的五点特殊性 | |
|---|---|
| ① | 是请求 I/O 的进程与设备控制器之间的通信程序 |
| ② | 与设备控制器和硬件特性紧密相关 |
| ③ | 与 I/O 控制方式紧密相关 |
| ④ | 一部分必须用汇编语言书写 |
| ⑤ | 必须可重入 |
| 是不是驱动程序的职责 | |
|---|---|
| 接收并检查 I/O 命令和参数 | 是 |
| 查询 I/O 设备状态 | 是 |
| 发出 I/O 命令、启动设备 | 是 |
| 逻辑块号译成盘面/磁道/扇区 | 是 |
| 通用缓冲区管理 | 否(设备独立性软件) |
| 设备分配与回收 | 否(设备独立性软件) |
考点
- 统一接口的两个方向:驱动与操作系统之间、驱动与内核之间
- 驱动程序的五点特殊性,尤其**“一部分必须用汇编”与”必须可重入”**
- 可重入的原因:多进程并发调用 + 执行中被本设备中断
- 缓冲区管理不属于驱动程序(高频真题)
- 驱动接口面向操作系统,设备独立性面向用户程序
链接
- 🏠 返回总览:操作系统第 5 章:输入/输出管理总览
- ⬅️ 上一节:5.2.4 SPOOLing 技术
- ➡️ 下一节:5.2.6 I/O 操作举例
- 🔗 分层判据的出处,见 5.1.3 I/O 软件层次结构
- 📖 名词库:第 5 章名词库