简介

从最高层面来看,设备驱动程序的工作是为特定设备提供统一的接口,同时隐藏特定于设备实现的细节。

例如,两个不同的以太网驱动程序都允许客户端使用完全相同的 C 语言函数通过接口发送数据包。每个驱动程序都负责以使客户端接口相同的方式管理自己的硬件,即使硬件不同也是如此。

请注意,驱动程序提供的接口可能是“中间”接口,也就是说,它们不一定代表链中的“最终”设备。

考虑使用基于 PCI 的以太网设备。 首先,需要一个了解如何与 PCI 总线本身通信的基本 PCI 驱动程序。此驱动程序不了解以太网,但知道如何处理机器上存在的特定 PCI 芯片组。

它会枚举总线上的设备,从每个设备上的各种寄存器收集信息,并提供一些函数,让其客户端(例如基于 PCI 的以太网驱动程序)能够执行 PCI 操作,例如分配中断或 DMA 通道。

因此,此基本 PCI 驱动程序可为以太网驱动程序提供服务,从而使以太网驱动程序能够管理其关联的硬件。

与此同时,其他设备(例如显卡)也可以类似的方式使用基本 PCI 驱动程序来管理其硬件。

Fuchsia 模型

为了提供最大的灵活性,Fuchsia 世界中的驱动程序可以绑定到匹配的“父”设备,并发布自己的“子”设备。此层次结构可根据需要进行扩展:一个驱动程序可能会发布一个子级,但另一个驱动程序可能会将该子级视为其父级,而第二个驱动程序会发布自己的子级,依此类推。

为了了解其运作方式,我们来参考基于 PCI 的以太网示例。

系统首先会提供一个特殊的“PCI 根”父级。 实际上,它是在说“我知道此系统上有一个 PCI 总线,当您找到它时,请将其绑定到此处。”

系统会评估驱动程序(搜索目录),并自动绑定匹配的驱动程序。

在这种情况下,系统会找到并绑定到“PCI 根”父级的驱动程序。

这是基本 PCI 驱动程序。 其作用是配置 PCI 总线,并枚举总线上的外围设备。

PCI 总线具有用于识别外围设备的特定惯例:供应商 ID (VID) 和设备 ID (DID) 的组合可唯一标识所有可能的 PCI 设备。 在枚举期间,这些值会从外围设备读取,并发布包含检测到的 VID 和 DID(以及大量其他信息)的新父节点。

每次发布新设备时,都会重复上述(针对初始 PCI 根设备发布)的相同流程;也就是说,系统会评估驱动程序,搜索与新父级的特征相匹配的驱动程序。

而对于 PCI 根设备,我们搜索的是与某种功能(称为“协议”,我们很快就会看到)匹配的驱动程序;但在本例中,我们搜索的是与另一种协议匹配的驱动程序,即满足“是 PCI 设备且具有给定的 VID 和 DID”要求的驱动程序。

如果找到合适的驱动程序(符合所需协议、VID 和 DID),则将其绑定到父级。

作为绑定的一部分,我们会初始化驱动程序,这涉及设置卡以进行操作、启动接口以及发布此设备的子设备等操作。 对于 PCI 以太网驱动程序,它会发布“以太网”接口,该接口符合另一项称为“以太网实现”协议的协议。此协议代表一种接近于客户端所用函数的常见协议(但会移除一个步骤;我们稍后会回到这一点)。