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.  驱动程序自动配置

驱动程序的装入和卸载

驱动程序必需的数据结构

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.  Oracle Solaris DDI/DKI 服务汇总

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

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

E.  pci.conf 文件

索引

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

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

可装入驱动程序接口

设备驱动程序必须是可动态装入的。驱动程序还应是可卸载的,以帮助节省内存资源。可卸载驱动程序还应易于测试、调试和修补。

每个设备驱动程序都需要实现 _init(9E)_fini(9E)_info(9E) 入口点以支持驱动程序的装入和卸载。以下示例显示了可装入驱动程序接口的典型实现。

示例 6-1 可装入接口部分

static void *statep;                /* for soft state routines */
static struct cb_ops xx_cb_ops;     /* forward reference */
static struct dev_ops xx_ops = {
    DEVO_REV,
    0,
    xxgetinfo,
    nulldev,
    xxprobe,
    xxattach,
    xxdetach,
    xxreset,
    nodev,
    &xx_cb_ops,
    NULL,
    xxpower,
    ddi_quiesce_not_needed,
};

static struct modldrv modldrv = {
    &mod_driverops,
    "xx driver v1.0",
    &xx_ops
};

static struct modlinkage modlinkage = {
    MODREV_1,
    &modldrv,
    NULL
};

int
_init(void)
{
    int error;
    ddi_soft_state_init(&statep, sizeof (struct xxstate),
        estimated_number_of_instances);
    /* further per-module initialization if necessary */
    error = mod_install(&modlinkage);
    if (error != 0) {
        /* undo any per-module initialization done earlier */
        ddi_soft_state_fini(&statep);
    }
    return (error);
}

int
_fini(void)
{
    int error;
    error = mod_remove(&modlinkage);
    if (error == 0) {
        /* release per-module resources if any were allocated */
        ddi_soft_state_fini(&statep);
    }
    return (error);
}

int
_info(struct modinfo *modinfop)
{
    return (mod_info(&modlinkage, modinfop));
}

_init() 示例

以下示例显示了典型的 _init(9E) 接口。

示例 6-2 _init() 函数

static void *xxstatep;
int
_init(void)
{
    int error;
    const int max_instance = 20;    /* estimated max device instances */

    ddi_soft_state_init(&xxstatep, sizeof (struct xxstate), max_instance);
    error = mod_install(&xxmodlinkage);
    if (error != 0) {
        /*
         * Cleanup after a failure
         */
        ddi_soft_state_fini(&xxstatep);
    }
    return (error);
}

_init() 中装入驱动程序期间,驱动程序应执行所有一次性资源分配或数据初始化。例如,在该例程中驱动程序应初始化所有对于该驱动程序为全局互斥锁的互斥锁。但是,驱动程序不应使用 _init(9E) 来分配或初始化与设备特定实例有关的任何内容。必须在 attach(9E) 中完成每个实例的初始化。例如,如果打印机的驱动程序可以同时处理多台打印机,则该驱动程序应在 attach() 中分配特定于每台打印机实例的资源。


注 - 一旦 _init(9E) 调用了 mod_install(9F),驱动程序便不应更改连接至 modlinkage(9S) 结构的任何数据结构,因为系统可能会复制或更改这些数据结构。


_fini() 示例

以下示例显示了 _fini() 例程。

int
_fini(void)
{
    int error;
    error = mod_remove(&modlinkage);
    if (error != 0) {
        return (error);
    }
    /*
     * Cleanup resources allocated in _init()
     */
    ddi_soft_state_fini(&xxstatep);
    return (0);
}

同样,在 _fini() 中,驱动程序应该释放在 _init() 中分配的所有资源。驱动程序必须将其自身从系统模块列表中删除。


注 - 将驱动程序连接至硬件实例时,可能会调用 _fini()。在本示例中,mod_remove(9F) 返回失败信息。因此,在 mod_remove() 返回成功信息之前,不应释放驱动程序资源。


_info() 示例

以下示例显示了 _info(9E) 例程。

int
_info(struct modinfo *modinfop)
{
    return (mod_info(&xxmodlinkage, modinfop));
}

调用该驱动程序是为了返回模块信息。应按如上所示实现入口点。