第 1 部分针对 Oracle Solaris 平台设计设备驱动程序
直接内存访问 (Direct Memory Access, DMA)
9. 直接内存访问 (Direct Memory Access, DMA)
14. 分层驱动程序接口 (Layered Driver Interface, LDI)
本节提供以下类别的入口点列表:
有些操作可由任何类型的驱动程序执行,如装入模块所需的函数以及必需的自动配置入口点所需的函数。本节介绍通用于所有驱动程序的入口点类型。通用入口点汇总中列出了通用入口点,并包含指向手册页以及其他相关讨论的链接。
字符设备和块设备的驱动程序导出 cb_ops(9S) 结构,该结构定义用于块设备访问和字符设备访问的驱动程序入口点。这两种类型的驱动程序都需要支持 open(9E) 和 close(9E) 入口点。块驱动程序需要支持 strategy(9E),而字符驱动程序可选择实现适用于设备类型的 read(9E)、write(9E)、ioctl(9E)、mmap(9E) 或 devmap(9E) 入口点的任意组合。字符驱动程序还可通过 chpoll(9E) 支持轮询接口。块驱动程序以及那些可使用块文件系统和字符文件系统的驱动程序可通过 aread(9E) 和 awrite(9E) 支持异步 I/O。
所有驱动程序都需要实现可装入模块入口点 _init(9E)、_fini(9E) 和 _info(9E),以便装入、卸载和报告有关驱动程序模块的信息。
驱动程序应在 _init(9E) 中分配并初始化所有全局资源,驱动程序应在 _fini(9E) 中释放其资源。
注 - 在 Oracle Solaris OS 中,只有可装入模块例程必须在驱动程序对象模块的外部可见。其他例程可具有存储类 static。
对于设备自动配置,驱动程序需要实现 attach(9E)、detach(9E) 和 getinfo(9E) 入口点。设备(如 SCSI 目标设备)在引导过程中无法标识自己时,驱动程序还可以实现可选入口点 probe(9E)。有关这些例程的更多信息,请参见第 6 章。
Oracle Solaris 平台提供了一组丰富的接口来维护和导出内核级统计信息(也称为 kstat)。驱动程序可以自由使用这些接口导出驱动程序和设备的统计信息,用户应用程序可使用这些统计信息来查看驱动程序的内部状态。提供了两个入口点来处理内核统计信息:
ks_snapshot(9E),可在特定时间捕获 kstat。
ks_update(9E),可用于根据需要更新 kstat 数据。在设置设备来跟踪内核数据但是提取该数据很耗时的情况下,ks_update() 非常有用。
有关详细信息,请参见 kstat_create(9F) 和 kstat(9S) 手册页。另请参见内核统计信息。
提供电源管理功能的硬件设备的驱动程序可支持可选的 power(9E) 入口点。有关此入口点的详细信息,请参见第 12 章。
对设备进行管理的驱动程序必须实现 quiesce(9E) 入口点。不管理设备的驱动程序可以将 dev_ops 结构中的 devo_quiesce 字段设置为 ddi_quiesce_not_needed ()。只有当处于高 PIL(priority interrupt level,优先中断级别)且禁用了抢占的系统是单线程时,才可以调用 quiesce() 函数。因此,该函数不得阻塞。如果设备有一个已定义的重置状态配置,则作为停止操作的一部分,驱动程序应当将该设备返回为相应的重置状态。此类情况的一个示例是快速重新引导,在这种情况下,当引导到新的操作系统映像时将绕过固件。
下表列出了所有类型驱动程序都可使用的入口点。
表 1-1 用于所有驱动程序类型的入口点
|
支持文件系统的设备称为块设备。为这些设备编写的驱动程序称为块设备驱动程序。块设备驱动程序接受 buf(9S) 结构形式的文件系统请求,并向磁盘发出 I/O 操作以传送指定的块。文件系统的主接口为 strategy(9E) 例程。有关更多信息,请参见第 16 章。
块设备驱动程序还可以提供字符驱动程序接口,以使实用程序能够绕过文件系统并直接访问设备。这种设备访问通常称为块设备的原始接口。
下表列出了块设备驱动程序可使用的其他入口点。另请参见通用于所有驱动程序的入口点。
表 1-2 用于块驱动程序的其他入口点
|
字符设备驱动程序通常以字节流的形式执行 I/O 操作。使用字符驱动程序的设备包括磁带机和串行端口。字符设备驱动程序还可以提供块驱动程序中不存在的其他接口,如 I/O 控制 (ioctl) 命令、内存映射以及设备轮询。有关更多信息,请参见第 15 章。
任何设备驱动程序的主要任务都是执行 I/O,并且许多字符设备驱动程序执行称为字节流或字符的 I/O。驱动程序可在设备上来回传送数据,而无需使用特定设备地址。此类型的传送与块设备驱动程序中的相反,后者部分文件系统请求会标识设备上的特定位置。
read(9E) 和 write(9E) 入口点可处理标准字符驱动程序的字节流 I/O。有关更多信息,请参见I/O 请求处理。
下表列出了字符设备驱动程序可使用的其他入口点。有关其他入口点的信息,请参见通用于所有驱动程序的入口点。
表 1-3 用于字符驱动程序的其他入口点
|
STREAMS 是一个独立的编程模型,用于编写字符驱动程序。异步接收数据的设备(如终端设备和网络设备)适合实现 STREAMS。STREAMS 设备驱动程序必须提供第 6 章中介绍的装入和自动配置支持。有关如何编写 STREAMS 驱动程序的其他信息,请参见《STREAMS Programming Guide》。
下表列出了 STREAMS 设备驱动程序可使用的其他入口点。有关其他入口点的信息,请参见通用于所有驱动程序的入口点和用于字符设备驱动程序的入口点。
表 1-4 用于 STREAMS 驱动程序的入口点
|
对于某些设备(如帧缓存器),提供直接访问设备内存的应用程序比字节流 I/O 更高效。应用程序使用 mmap(2) 系统调用可将设备内存映射到其地址空间。要支持内存映射,设备驱动程序需要实现 segmap(9E) 和 devmap(9E) 入口点。有关 devmap(9E) 的信息,请参见第 10 章。有关 segmap(9E) 的信息,请参见第 15 章。
定义 devmap(9E) 入口点的驱动程序通常不会定义read(9E) 和 write(9E) 入口点,因为应用程序在调用 mmap(2) 之后会直接对设备执行 I/O 操作。
下表列出了使用 devmap 框架执行内存映射的字符设备驱动程序可以使用的其他入口点。有关其他入口点的信息,请参见通用于所有驱动程序的入口点和用于字符设备驱动程序的入口点。
表 1-5 使用 devmap 进行内存映射的字符驱动程序的入口点
|
有关使用 Generic LAN Driver v3 (GLDv3) 框架的网络设备驱动程序的入口点列表,请参见表 19-1。有关更多信息,请参见第 19 章中的GLDv3 网络设备驱动程序框架和GLDv3 MAC 注册函数。
下表列出了 SCSI HBA 设备驱动程序可使用的其他入口点。有关 SCSI HBA 传输结构的信息,请参见 scsi_hba_tran(9S)。有关其他入口点的信息,请参见通用于所有驱动程序的入口点和用于字符设备驱动程序的入口点。
表 1-6 用于 SCSI HBA 驱动程序的其他入口点
|
下表列出了 PC 卡设备驱动程序可使用的其他入口点。有关其他入口点的信息,请参见通用于所有驱动程序的入口点和用于字符设备驱动程序的入口点。
表 1-7 仅适用于 PC 卡驱动程序的入口点
|