> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/4.3-bsd-unix-cao-zuo-xi-tong-she-ji-yu-shi-xian/di-san-bu-fen-io-xi-tong/8.2.-she-bei-qu-dong.md).

# 8.2 设备驱动

设备驱动分为三大部分：

1. 自动配置与初始化例程
2. 服务 I/O 请求的例程（上半部）
3. 中断服务例程（下半部）

驱动的自动配置部分负责 **探测**（probe）硬件设备是否存在，并初始化设备以及驱动所需的关联软件状态。驱动的这一部分通常只在系统初始化时调用一次。

驱动中服务系统 I/O 请求的部分，因系统调用或代表虚拟内存系统的操作而被调用，在内核上半部同步执行，允许调用 `sleep()` 阻塞。我们通常把这部分代码称为设备驱动的上半部（top half）。

中断服务例程在系统接到设备中断时被调用，因此不能依赖任何每进程状态，也不能阻塞。VAX 上中断例程在中断栈上执行。我们通常把设备驱动的中断服务例程称为驱动的下半部（bottom half）。

除这三大部分外，还可提供可选的崩溃转储（crash-dump）例程：系统发现不可恢复错误、想把物理内存内容记下来供事后分析时调用它。多数磁盘控制器的设备驱动和一些磁带控制器的驱动提供崩溃转储例程，其使用见第 13 章。

**I/O 排队**

设备驱动正常运行时通常管理一条或多条 I/O 请求队列。驱动的上半部收到输入或输出请求时，把它记入一个数据结构，放到每设备队列中等待处理。输入或输出操作完成时，设备驱动收到控制器的中断；中断服务例程从设备队列摘下相应请求，通知请求方命令已完成，再从队列发起下一个请求。I/O 队列是设备驱动上下两半之间通信的主要手段。面向块的设备用 `buf` 结构构造 I/O 队列，面向字符的设备用 C 链表结构。

I/O 队列在异步例程之间共享，访问必须同步。上半部例程操纵 I/O 队列时，必须提升处理器优先级（用 `splbio()`、`spltty()` 等），以防队列操纵期间因中断进入下半部。发起 I/O 请求的多个进程之间也必须同步，用的是第 4 章末尾描述的机制。

除每设备 I/O 排队外，VAX 上设备驱动还必须与设备所在总线适配器的支持例程互动。例如 UNIBUS 磁盘控制器的驱动必须经 UNIBUS 适配器支持例程调度对 UNIBUS 的访问，因为每个适配器中做 I/O 操作的资源有限，而且某些 I/O 设备要求独占总线才能可靠工作。为处理这些问题，设备驱动把每个 I/O 请求打包后交给安排 I/O 操作的总线适配器例程；操作所需的资源可得时，回调设备驱动，由它启动 I/O 操作。这一调度可能带来设备驱动排队之外的又一层排队。

**中断处理**

设备产生中断以通报操作完成或状态变化。系统收到设备中断后，带着一个或多个唯一标识需要服务的设备的参数调用相应驱动的中断服务例程。需要这些参数是因为设备驱动通常支持同型设备的多个实例；中断不带设备身份，驱动就得轮询所有可能设备来确定中断源。

UNIBUS 设备的中断例程收到一个系统配置时定义的物理部件号（physical unit number）。MASSBUS 设备的中断例程实际由 MASSBUS 适配器中断服务例程间接调用，后者收到配置时定义的 MASSBUS 部件号（MASSBUS unit number）。系统靠在中断向量表中安装辅助胶合例程的地址，为每种设备把适当参数传给中断服务例程。被调来服务中断的是胶合例程而不是真正的中断服务例程；它依次做以下动作：

1. 保存全部易失寄存器
2. 更新设备中断的统计
3. 带适当的部件号参数调用中断服务例程
4. 恢复第 1 步保存的易失寄存器
5. 从中断返回

中断向量表与中断服务例程之间插有胶合例程，设备驱动便不必操心机器状态的保存与恢复。此外，硬件支持中断所需而无法由 C 生成的专用指令也可以不进设备驱动——设备驱动因此可以完全不用汇编语言编写。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://book.bsdcn.org/4.3-bsd-unix-cao-zuo-xi-tong-she-ji-yu-shi-xian/di-san-bu-fen-io-xi-tong/8.2.-she-bei-qu-dong.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
