JavaScript is required to for searching.
跳过导航链接
退出打印视图
编写设备驱动程序     Oracle Solaris 11.1 Information Library (简体中文)
为本文档评分
search filter icon
search icon

文档信息

前言

第 1 部分针对 Oracle Solaris 平台设计设备驱动程序

1.  Oracle Solaris 设备驱动程序概述

2.  Oracle Solaris 内核和设备树

3.  多线程

4.  属性

5.  管理事件和排队任务

6.  驱动程序自动配置

7.  设备访问:程控 I/O

8.  中断处理程序

9.  直接内存访问 (Direct Memory Access, DMA)

10.  映射设备和内核内存

11.  设备上下文管理

12.  电源管理

13.  强化 Oracle Solaris 驱动程序

14.  分层驱动程序接口 (Layered Driver Interface, LDI)

LDI 概述

内核接口

分层标识符-内核设备使用方

分层驱动程序句柄-目标设备

打开和关闭目标设备

访问目标设备

检索目标设备信息

检索目标设备属性值

接收异步设备事件通知

LDI 内核接口示例

设备配置文件

驱动程序源文件

如何生成和装入分层驱动程序

测试分层驱动程序

用户接口

设备信息库接口

列显系统配置命令接口

设备用户命令接口

第 2 部分设计特定种类的设备驱动程序

15.  字符设备驱动程序

16.  块设备驱动程序

17.  SCSI 目标驱动程序

18.  SCSI 主机总线适配器驱动程序

19.  网络设备驱动程序

20.  USB 驱动程序

21.  SR-IOV 驱动程序

第 3 部分生成设备驱动程序

22.  编译、装入、打包和测试驱动程序

23.  调试、测试和调优设备驱动程序

24.  推荐的编码方法

第 4 部分附录

A.  硬件概述

B.  Oracle Solaris DDI/DKI 服务汇总

C.  使设备驱动程序支持 64 位

D.  控制台帧缓存器驱动程序

E.  pci.conf 文件

索引

请告诉我们如何提高我们的文档:
过于简略
不易阅读或难以理解
重要信息缺失
错误的内容
需要翻译的版本
其他
Your rating has been updated
感谢您的反馈!

您的反馈将非常有助于我们提供更好的文档。 您是否愿意参与我们的内容改进并提供进一步的意见?

用户接口

LDI 中包括用户级库和命令接口,用于报告设备分层和使用信息。设备信息库接口介绍了用于报告设备分层信息的 libdevinfo(3LIB) 接口。列显系统配置命令接口介绍了用于报告内核设备使用信息的 prtconf(1M) 接口。设备用户命令接口介绍了用于报告设备使用方信息的 fuser(1M) 接口。

设备信息库接口

LDI 中包括用于报告设备分层信息快照的 libdevinfo(3LIB) 接口。如果系统中的一个设备是同一系统中另一个设备的使用方,则会发生设备分层。仅当使用方和目标都绑定到快照中包含的设备节点时,才会报告设备分层信息。

libdevinfo(3LIB) 接口以有向图的形式报告设备分层信息。lnode 是一个抽象术语,在图中表示顶点,并被绑定到设备节点。可以使用 libdevinfo(3LIB) 接口来访问 lnode 的属性,如节点的名称和设备编号。

图中的边表示链接。链接既有表示设备使用方的源 lnode,也有表示目标设备的目标 lnode。

下面介绍了 libdevinfo(3LIB) 设备分层信息接口:

DINFOLYR

通过它来捕获设备分层信息的快照标志。

di_link_t

两个端点之间的有向链接。每个端点都是一个 di_lnode_t。属于不透明结构。

di_lnode_t

链接的端点。属于不透明结构。di_lnode_t 绑定到 di_node_t

di_node_t

表示设备节点。属于不透明结构。di_node_t 不一定绑定到 di_lnode_t

di_walk_link(3DEVINFO)

遍历快照中的所有链接。

di_walk_lnode(3DEVINFO)

遍历快照中的所有 lnode。

di_link_next_by_node(3DEVINFO)

获取以指定的 di_node_t 节点作为源节点或目标节点的下一个链接的句柄。

di_link_next_by_lnode(3DEVINFO)

获取以指定的 di_lnode_t lnode 作为源 lnode 或目标 lnode 的下一个链接的句柄。

di_link_to_lnode(3DEVINFO)

获取与 di_link_t 链接的指定端点对应的 lnode。

di_link_spectype(3DEVINFO)

获取链接的规范类型。规范类型指示如何访问目标设备。目标设备由目标 lnode 表示。

di_lnode_next(3DEVINFO)

获取与指定的 di_node_t 设备节点关联的指定 di_lnode_t lnode 的下一个实例的句柄。

di_lnode_name(3DEVINFO)

获取与指定 lnode 关联的名称。

di_lnode_devinfo(3DEVINFO)

获取与指定 lnode 关联的设备节点的句柄。

di_lnode_devt(3DEVINFO)

获取与指定 lnode 关联的设备节点的设备编号。

LDI 返回的设备分层信息可能十分复杂。因此,LDI 提供了一些接口来协助遍历设备树和设备使用情况图。通过这些接口,设备树快照的使用方可以将定制数据指针与快照中的不同结构关联。例如,应用程序遍历 lnode 时,它可以更新与每个 lnode 关联的定制指针,以标记已经识别的 lnode。

下面介绍了 libdevinfo(3LIB) 节点和链接标记接口:

di_lnode_private_set(3DEVINFO)

将指定的数据与指定的 lnode 关联。通过此关联,可以遍历快照中的 lnode。

di_lnode_private_get(3DEVINFO)

检索指向通过调用 di_lnode_private_set(3DEVINFO) 而与 lnode 关联的数据的指针。

di_link_private_set(3DEVINFO)

将指定的数据与指定的链接关联。通过此关联,可以遍历快照中的链接。

di_link_private_get(3DEVINFO)

检索指向通过调用 di_link_private_set(3DEVINFO) 而与链接关联的数据的指针。

列显系统配置命令接口

prtconf(1M) 命令已得到增强,可以显示内核设备使用信息。缺省的 prtconf(1M) 输出没有变化。如果在 prtconf(1M) 命令中指定详细选项 (-v),则会显示设备使用信息。如果在 prtconf(1M) 命令行上指定了特定设备的路径,则会显示有关该设备的使用信息。

prtconf -v

显示设备次要节点和设备使用信息。显示内核使用方和每个内核使用方当前打开的次要节点。

prtconf path

显示由 path 指定的设备的设备使用信息。

prtconf -a path

显示由 path 指定的设备的设备使用信息,以及作为 path 的祖先的所有设备节点。

prtconf -c path

显示由 path 指定的设备的设备使用信息,以及作为 path 的子节点的所有设备节点。

示例 14-6 设备使用信息

如果需要有关特定设备的使用信息,path 参数的值可以是任何有效的设备路径。

% prtconf /dev/cfg/c0
SUNW,isptwo, instance #0

示例 14-7 祖先节点使用信息

要显示有关特定设备和作为其祖先的所有设备节点的使用信息,请随 prtconf(1M) 命令指定 -a 标志。祖先包括直到设备树的根的所有节点。如果随 prtconf(1M) 命令指定了 -a 标志,则还必须指定设备的 path 名称。

% prtconf -a /dev/cfg/c0
SUNW,Sun-Fire
    ssm, instance #0
        pci, instance #0
            pci, instance #0
                SUNW,isptwo, instance #0

示例 14-8 子节点使用信息

要显示有关特定设备和作为其子节点的所有设备节点的使用信息,请随 prtconf(1M) 命令指定 -c 标志。如果随 prtconf(1M) 命令指定了 -c 标志,则还必须指定设备的 path 名称。

% prtconf -c /dev/cfg/c0
SUNW,isptwo, instance #0
    sd (driver not attached)
    st (driver not attached)
    sd, instance #1
    sd, instance #0
    sd, instance #6
    st, instance #1 (driver not attached)
    st, instance #0 (driver not attached)
    st, instance #2 (driver not attached)
    st, instance #3 (driver not attached)
    st, instance #4 (driver not attached)
    st, instance #5 (driver not attached)
    st, instance #6 (driver not attached)
    ses, instance #0 (driver not attached)
    ...

示例 14-9 分层和设备次要节点信息-键盘

要显示有关特定设备的设备分层和设备次要节点信息,请随 prtconf(1M) 命令指定 -v 标志。

% prtconf -v /dev/kbd
conskbd, instance #0
    System properties:
        ...
    Device Layered Over:
        mod=kb8042 dev=(101,0)
            dev_path=/isa/i8042@1,60/keyboard@0
    Device Minor Nodes:
        dev=(103,0)
            dev_path=/pseudo/conskbd@0:kbd
                spectype=chr type=minor
                dev_link=/dev/kbd
        dev=(103,1)
            dev_path=/pseudo/conskbd@0:conskbd
                spectype=chr type=internal
            Device Minor Layered Under:
                mod=wc accesstype=chr
                    dev_path=/pseudo/wc@0

本示例中,/dev/kbd 设备所在层位于硬件键盘设备 (/isa/i8042@1,60/keyboard@0) 之上。另外,本示例中,/dev/kbd 设备具有两个设备次要节点。第一个次要节点具有可用于访问该节点的 /dev 链接。第二个次要节点是一个无法通过文件系统访问的内部节点。wc 驱动程序(即工作站控制台)已经打开了第二个次要节点。请将本示例的输出与示例 14-12 的输出进行比较。

示例 14-10 分层和设备次要节点信息-网络设备

本示例说明哪些设备正在使用当前检测到的网络设备。

% prtconf -v /dev/iprb0
pci1028,145, instance #0
    Hardware properties:
        ...
    Interrupt Specifications:
        ...
    Device Minor Nodes:
        dev=(27,1)
            dev_path=/pci@0,0/pci8086,244e@1e/pci1028,145@c:iprb0
                spectype=chr type=minor
                alias=/dev/iprb0
        dev=(27,4098)
            dev_path=<clone>
            Device Minor Layered Under:
                mod=udp6 accesstype=chr
                    dev_path=/pseudo/udp6@0
        dev=(27,4097)
            dev_path=<clone>
            Device Minor Layered Under:
                mod=udp accesstype=chr
                    dev_path=/pseudo/udp@0
        dev=(27,4096)
            dev_path=<clone>
            Device Minor Layered Under:
                mod=udp accesstype=chr
                    dev_path=/pseudo/udp@0

本示例中,在采用 udpudp6 的情况下链接了 iprb0 设备。请注意,此处未显示指向采用 udpudp6 的次要节点的任何路径。本示例中未显示任何路径是因为次要节点是通过对 iprb 驱动程序执行 clone 打开操作创建的,因此不存在可以访问这些节点的文件系统路径。请将本示例的输出与示例 14-11 的输出进行比较。

设备用户命令接口

fuser(1M) 命令已得到增强,可以显示设备使用信息。仅当 path 表示设备次要节点时,fuser(1M) 命令才会显示设备使用信息。仅当指定了表示设备次要节点的 path 时,随 fuser(1M) 命令使用 -d 标志才有效。

fuser path

显示有关应用程序设备使用方和内核设备使用方的信息(如果 path 表示设备次要节点)。

fuser -d path

显示与 path 表示的设备次要节点关联的基础设备的所有用户。

报告内核设备使用方时采用以下四种格式之一。内核设备使用方始终用方括号 ([]) 括起来。

        [kernel_module_name]
        [kernel_module_name,dev_path=path]
        [kernel_module_name,dev=(major,minor)]
        [kernel_module_name,dev=(major,minor),dev_path=path]

如果 fuser(1M) 命令显示的是文件或设备用户,则输出由 stdout 中的进程 ID 后跟 stderr 中的字符组成。stderr 中的字符描述如何使用文件或设备。stderr 中会显示所有内核使用方信息。而 stdout 中不会显示任何内核使用方信息。

如果未使用 -d 标志,则 fuser(1M) 命令仅报告由 path 指定的设备次要节点的使用方。如果使用 -d 标志,则 fuser(1M) 命令会报告由 path 指定的次要节点的基础设备节点的使用方。以下示例说明了这两种情况下报告输出的差别。

示例 14-11 基础设备节点的使用方

大多数网络设备在打开时都会克隆其次要节点。如果请求克隆次要节点的设备使用信息,则该使用信息可能会表明没有任何进程在使用该设备。而如果请求基础设备节点的设备使用信息,则该使用信息可能会表明某个进程正在使用该设备。在本示例中,如果仅将设备 path 传递到 fuser(1M) 命令,则不会报告任何设备使用方。如果使用 -d 标志,则输出将表明正在采用 udpudp6 来访问该设备。

% fuser /dev/iprb0
/dev/iprb0:
% fuser -d /dev/iprb0
/dev/iprb0:  [udp,dev_path=/pseudo/udp@0] [udp6,dev_path=/pseudo/udp6@0]

请将本示例的输出与示例 14-10 的输出进行比较。

示例 14-12 键盘设备的使用方

在本示例中,某个内核使用方正在访问 /dev/kbd。正在访问 /dev/kbd 设备的内核使用方是工作站控制台驱动程序。

% fuser -d /dev/kbd
/dev/kbd:  [genunix] [wc,dev_path=/pseudo/wc@0]

请将本示例的输出与示例 14-9 的输出进行比较。