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

文档信息

前言

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

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

2.  Oracle Solaris 内核和设备树

3.  多线程

4.  属性

5.  管理事件和排队任务

6.  驱动程序自动配置

驱动程序的装入和卸载

驱动程序必需的数据结构

modlinkage 结构

modldrv 结构

dev_ops 结构

cb_ops 结构

可装入驱动程序接口

_init() 示例

_fini() 示例

_info() 示例

设备配置概念

设备实例和实例编号

次要节点和次要设备号

probe() 入口点

attach() 入口点

驱动程序软状态管理

锁变量和条件变量的初始化

创建从设备节点

延迟连接

detach() 入口点

getinfo() 入口点

使用设备 ID

注册设备 ID

注册设备提供的 ID

注册虚构 ID

注销设备 ID

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

8.  中断处理程序

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

10.  映射设备和内核内存

11.  设备上下文管理

12.  电源管理

13.  强化 Oracle Solaris 驱动程序

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

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

15.  字符设备驱动程序

16.  块设备驱动程序

17.  SCSI 目标驱动程序

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

19.  网络设备驱动程序

20.  USB 驱动程序

21.  SR-IOV 驱动程序

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

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

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

24.  推荐的编码方法

第 4 部分附录

A.  硬件概述

B.  Solaris DDI/DKI 服务汇总

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

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

E.  pci.conf 文件

索引

驱动程序必需的数据结构

为了支持自动配置,驱动程序需要静态初始化以下数据结构:

驱动程序依赖于图 5-1 中的数据结构。必须提供并正确初始化这些数据结构。没有这些数据结构,可能无法正确装入驱动程序。结果导致可能无法装入必需的例程。如果驱动程序不支持某个操作,则 nodev(9F) 例程的地址可以用作占位符。在某些情况下,驱动程序支持入口点,并且仅需要返回成功信息或失败信息。在这种情况下,可以使用例程 nulldev(9F) 的地址。


注 - 应该在编译时对这些结构进行初始化。在任何其他时间,驱动程序都不应访问或更改这些结构。


modlinkage 结构

static struct modlinkage xxmodlinkage = {
    MODREV_1,       /* ml_rev */
    &xxmodldrv,     /* ml_linkage[] */
    NULL            /* NULL termination */
};

第一个字段是装入子系统的模块的版本号。该字段应为 MODREV_1。第二个字段指向接下来定义的驱动程序的 modldrv 结构。该结构的最后一个元素应始终为 NULL

modldrv 结构

static struct modldrv xxmodldrv = {
    &mod_driverops,           /* drv_modops */
    "generic driver v1.1",    /* drv_linkinfo */
    &xx_dev_ops               /* drv_dev_ops */
};

该结构更加详细地描述模块。第一个字段提供有关模块安装的信息。对于驱动程序模块,该字段应设置为 &mod_driverops。第二个字段是将由 modinfo(1M) 显示的字符串。第二个字段应包含足够的信息,以便确定生成驱动程序二进制文件的源代码版本。最后一个字段指向下节所定义的驱动程序的 dev_ops 结构。

dev_ops 结构

static struct dev_ops xx_dev_ops = {
    DEVO_REV,       /* devo_rev */
    0,              /* devo_refcnt  */
    xxgetinfo,      /* devo_getinfo: getinfo(9E) */
    nulldev,        /* devo_identify: identify(9E) */
    xxprobe,        /* devo_probe: probe(9E) */
    xxattach,       /* devo_attach: attach(9E) */
    xxdetach,       /* devo_detach: detach(9E) */
    nodev,          /* devo_reset */
    &xx_cb_ops,     /* devo_cb_ops */
    NULL,           /* devo_bus_ops */
    &xxpower        /* devo_power: power(9E) */
};

使用 dev_ops(9S) 结构,内核可以找到设备驱动程序的自动配置入口点。devo_rev 字段标识结构的修订号。该字段必须设置为 DEVO_REVdevo_refcnt 字段必须初始化为零。应使用相应驱动程序的入口点地址填充函数地址字段,但以下情况除外:

devo_cb_ops 成员应包含 cb_ops(9S) 结构的地址。devo_bus_ops 字段必须设置为 NULL

cb_ops 结构

static struct cb_ops xx_cb_ops = {
    xxopen,         /* open(9E) */
    xxclose,        /* close(9E) */
    xxstrategy,     /* strategy(9E) */
    xxprint,        /* print(9E) */
    xxdump,         /* dump(9E) */
    xxread,         /* read(9E) */
    xxwrite,        /* write(9E) */
    xxioctl,        /* ioctl(9E) */
    xxdevmap,       /* devmap(9E) */
    nodev,          /* mmap(9E) */
    xxsegmap,       /* segmap(9E) */
    xxchpoll,       /* chpoll(9E) */
    xxprop_op,      /* prop_op(9E) */
    NULL,           /* streamtab(9S) */
    D_MP | D_64BIT, /* cb_flag */
    CB_REV,         /* cb_rev */
    xxaread,        /* aread(9E) */
    xxawrite        /* awrite(9E) */
};

cb_ops(9S) 结构包含设备驱动程序的字符操作和块操作的入口点。驱动程序不支持的所有入口点应初始化为 nodev(9F)。例如,字符设备驱动程序应该将所有块字段(例如 cb_stategy)设置为 nodev(9F)。请注意,保留 mmap(9E) 入口点是为了兼容早期发行版。驱动程序应使用 devmap(9E) 入口点来进行设备内存映射。如果支持 devmap(9E),应将 mmap(9E) 设置为 nodev(9F)

streamtab 字段表明驱动程序是否基于 STREAMS。只有第 19 章中讨论的网络设备驱动程序基于 STREAMS。所有不基于 STREAMS 的驱动程序必须streamtab 字段设置为 NULL

cb_flag 成员包含以下标志:

cb_revcb_ops 结构修订号。该字段必须设置为 CB_REV