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)

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

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

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

E.  pci.conf 文件

索引

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

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

32 位和 64 位数据结构宏

示例 15-15 中的方法适用于许多驱动程序。另一种方案是使用 <sys/model.h> 中提供的数据结构宏在应用程序和内核之间移动数据。从功能角度看,这些宏减少了代码混乱问题,并使代码的表现形式完全相同。

示例 15-16 使用数据结构宏移动数据

int
    xxioctl(dev_t dev, int cmd, intptr_t arg, int mode,
        cred_t *cr, int *rval_p)
    {    
        STRUCT_DECL(opdata, op);

        if (cmd != OPONE)
            return (ENOTTY);

        STRUCT_INIT(op, mode);

        if (copyin((void *)arg,
            STRUCT_BUF(op), STRUCT_SIZE(op)))
                return (EFAULT);

        if (STRUCT_FGET(op, flag) != XXACTIVE ||     
            STRUCT_FGET(op, size) > XXSIZE)
                return (EINVAL);
        xxdowork(device_state, STRUCT_FGET(op, size));
        return (0);
}

结构宏如何工作?

在 64 位设备驱动程序中,结构宏使得两种处理能力的数据结构可以使用相同的内核内存片段。内存缓冲区保存数据结构的本机形式的内容,即 LP64 和 ILP32 形式。每种结构的访问是通过条件表达式实现的。如果驱动程序以 32 位方式编译,则仅支持一种数据模型(本机形式)。不使用条件表达式。

64 位版本的宏依赖于数据结构阴影版本的定义。阴影版本描述了使用固定宽度类型的 32 位接口。将 "32" 附加到本机数据结构名称,就形成了阴影数据结构的名称。为方便起见,将阴影结构的定义放置到与本机结构相同的文件中,以降低将来的维护成本。

这些宏可以采用下列参数:

structname

数据结构的本机形式的结构名称,即在 struct 关键字后输入的内容。

umodel

包含用户数据模型(例如 FILP32FLP64)的标志字,从 ioctl(9E) 的模式参数中提取。

handle

此名称用于引用这些宏所处理的结构的特定实例。

fieldname

结构内部的字段的名称。

何时使用结构宏

宏使您能够仅对数据项的字段进行适当地引用。宏不提供采用基于数据模型的单独代码路径的方法。如果数据结构中的字段数量很大,则应避免使用宏。如果对这些字段的引用非常频繁,也应避免使用宏。

在实现宏的过程中,宏隐藏了数据模型之间的很多差异。因此,使用此接口编写的代码通常比较容易理解。如果驱动程序以 32 位方式编译,则生成的代码较为简洁,并且无需冗长的 #ifdefs,但仍保留了类型检查。

声明并初始化结构句柄

可以使用 STRUCT_DECL(9F)STRUCT_INIT(9F) 声明和初始化句柄及空间,以便在栈中对 ioctl 进行解码。STRUCT_HANDLE(9F)STRUCT_SET_HANDLE(9F) 可以声明和初始化句柄,但不在栈中分配空间。如果结构非常大,或者包含在其他某个数据结构中,则后面的宏比较有用。


注 - 因为 STRUCT_DECL(9F)STRUCT_HANDLE(9F) 宏扩展为数据结构声明,所以这些宏在 C 代码中应该使用这些声明进行分组。


用于声明和初始化结构的宏如下所示:

STRUCT_DECL(structname, handle)

structname 数据结构声明一个名为 handle结构句柄STRUCT_DECL 按其本机形式在栈中分配空间。假定本机形式大于或等于结构的 ILP32 形式。

STRUCT_INIT(handle, umodel)

handle 的数据模型初始化为 umodel。在对使用 STRUCT_DECL(9F) 声明的结构句柄进行任何访问之前,必须调用此宏。

STRUCT_HANDLE(structname, handle)

声明调用了 handle结构句柄。它与 STRUCT_DECL(9F) 相对。

STRUCT_SET_HANDLE(handle , umodel, addr )

handle 的数据模型初始化为 umodel,然后将 addr 设置为用于后续处理的缓冲区。在访问使用 STRUCT_DECL(9F) 声明的结构句柄之前,请调用此宏。

结构句柄的操作

用于在结构上执行操作的宏如下所示:

size_t STRUCT_SIZE(handle )

返回 handle 所引用的结构的大小(取决于该结构的嵌入式数据模型)。

typeof fieldname STRUCT_FGET(handle, fieldname)

返回 handle 所引用的数据结构中的指定字段。此字段为非指针类型。

typeof fieldname STRUCT_FGETP(handle, fieldname)

返回 handle 所引用的数据结构中的指定字段。此字段为指针类型。

STRUCT_FSET(handle , fieldname, val)

handle 所引用的数据结构中的指定字段设置为值 valval 的类型应与 fieldname 的类型相匹配。此字段为非指针类型。

STRUCT_FSETP(handle , fieldname, val)

handle 所引用的数据结构中的指定字段设置为值 val。此字段为指针类型。

typeof fieldname *STRUCT_FADDR(handle, fieldname)

返回 handle 所引用的数据结构中的指定字段的地址。

struct structname *STRUCT_BUF(handle)

返回指向 handle 所描述的本机结构的指针。

其他操作

其他一些结构宏如下所示:

size_t SIZEOF_STRUCT(struct_name, datamodel)

返回 struct_name 的大小(取决于给定的数据模型)。

size_t SIZEOF_PTR(datamodel )

根据给定的数据模型,返回指针的大小。