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

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

8.  中断处理程序

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

10.  映射设备和内核内存

11.  设备上下文管理

12.  电源管理

13.  强化 Oracle Solaris 驱动程序

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

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

15.  字符设备驱动程序

字符驱动程序结构概述

字符设备自动配置

设备访问(字符驱动程序)

open() 入口点(字符驱动程序)

close() 入口点(字符驱动程序)

I/O 请求处理

用户地址

向量化的 I/O

同步 I/O 与异步 I/O 之间的差别

数据传输方法

程控 I/O 传输

DMA 传输(同步)

DMA 传输(异步)

minphys() 入口点

strategy() 入口点

映射设备内存

对文件描述符执行多路复用 I/O 操作

其他 I/O 控制

ioctl() 入口点(字符驱动程序)

对有 64 位处理能力的设备驱动程序的 I/O 控制支持

处理 copyout() 溢出

32 位和 64 位数据结构宏

结构宏如何工作?

何时使用结构宏

声明并初始化结构句柄

结构句柄的操作

其他操作

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 文件

索引

设备访问(字符驱动程序)

可通过 open(9E)close(9E) 入口点来控制一个或多个应用程序对设备的访问。对代表字符设备的特殊文件进行 open(2) 系统调用始终会导致为驱动程序调用 open(9E) 例程。对于特定的从设备,open(9E) 可以多次被调用,而 close(9E) 例程只有在删除了对设备的最终引用时才会调用。如果通过文件描述符访问设备,则 close(2)exit(2) 系统调用都可能导致对 close(9E) 的最终调用。如果通过内存映射访问设备,则 munmap(2) 系统调用可能导致对 close(9E) 的最终调用。

open() 入口点(字符驱动程序)

open() 的主要功能是检验是否允许打开请求。open(9E) 的语法如下所示:

int xxopen(dev_t *devp, int flag, int otyp, cred_t *credp);

其中:

devp

指向设备编号的指针。会向 open() 例程传递指针,以便驱动程序可以更改次要设备号。使用此指针,驱动程序能够动态创建设备的次要实例。伪终端驱动程序就是这样,只要打开该驱动程序,就会创建新的伪终端。通常,动态选择次要设备号的驱动程序使用 ddi_create_minor_node(9F)attach(9E) 中仅创建一个从设备节点,然后使用 makedevice(9F)getmajor(9F) 更改 *devp 的次要设备号部分:

    *devp = makedevice(getmajor(*devp), new_minor);

您不必调用 ddi_create_minor_node(9F) 来创建新的次要节点。驱动程序不得更改 *devp 的主设备号。驱动程序必须在内部跟踪可用的次要设备号。

flag

使用位指示打开设备是供读取 (FREAD)、写入 (FWRITE) 还是供可同时读写的标志。发出 open(2) 系统调用的用户线程也可以请求对设备进行独占访问 (FEXCL),或指定不得以任何原因阻止打开操作 (FNDELAY),但驱动程序必须强制执行两者。只写设备(例如打印机)的驱动程序可能会将 open(9E) 视为对读操作无效。

otyp

表示如何调用 open() 的整数。驱动程序必须检查 otyp 的值是否适用于相应设备。对于字符驱动程序,otyp 应为 OTYP_CHR(请参见 open(9E) 手册页)。

credp

指向包含有关调用方信息(例如用户 ID 和组 ID)的凭证结构的指针。驱动程序不会直接检查此结构,但会使用 drv_priv(9F) 来检查 root 用户权限的一般情况。在本示例中,只允许 root 或具有 PRIV_SYS_DEVICES 权限的用户打开设备进行写入。

以下示例显示了字符驱动程序的 open(9E) 例程。

示例 15-2 字符驱动程序 open(9E) 例程

static int
xxopen(dev_t *devp, int flag, int otyp, cred_t *credp)
{
    minor_t        instance;

    if (getminor(*devp)         /* if device pointer is invalid */
        return (EINVAL);
    instance = getminor(*devp); /* one-to-one example mapping */
    /* Is the instance attached? */
    if (ddi_get_soft_state(statep, instance) == NULL)
        return (ENXIO);
    /* verify that otyp is appropriate */
    if (otyp != OTYP_CHR)
        return (EINVAL);
    if ((flag & FWRITE) && drv_priv(credp) == EPERM)
        return (EPERM);
    return (0);
}

close() 入口点(字符驱动程序)

close(9E) 的语法如下所示:

int xxclose(dev_t dev, int flag, int otyp, cred_t *credp);

close() 应执行任何必要的清除操作,以完成次要设备的使用,并准备好设备(以及驱动程序)以便再次被打开。例如,可能已使用独占访问 (FEXCL) 标志调用了打开例程。对 close(9E) 的调用允许其他打开例程继续运行。close(9E) 可以执行的其他功能包括:

如果因为外部条件(例如流量控制)而造成 I/O 执行延迟,则等待 I/O 执行完毕的驱动程序会一直等待下去。有关如何避免此问题的信息,请参见线程无法接收信号