Documentation Home
> 编写设备驱动程序
编写设备驱动程序
Book Information
索引
数字和符号
A
B
C
D
E
F
G
H
I
K
L
M
N
O
P
R
S
T
U
V
W
X
保
备
崩
避
编
标
部
测
程
处
串
窗
磁
次
存
错
打
代
单
地
第
电
调
动
独
读
对
多
二
访
分
复
高
故
关
管
光
过
函
互
缓
恢
回
获
集
寄
兼
将
结
句
可
克
控
块
链
列
流
轮
描
名
命
模
内
排
配
弃
前
潜
强
驱
全
热
任
入
软
上
设
实
使
事
视
属
数
锁
特
条
停
通
同
突
图
脱
外
网
伪
文
无
物
系
现
线
相
像
消
校
卸
虚
叶
以
异
引
硬
用
与
预
源
灾
诊
支
中
主
传
装
状
资
子
字
自
总
前言
第 1 部分 针对 Solaris 平台设计设备驱动程序
第 1 章 Solaris 设备驱动程序概述
设备驱动程序基础知识
什么是设备驱动程序?
什么是设备驱动程序入口点?
设备驱动程序入口点
通用于所有驱动程序的入口点
设备访问入口点
可装入模块入口点
自动配置入口点
内核统计信息入口点
电源管理入口点
通用入口点汇总
用于块设备驱动程序的入口点
用于字符设备驱动程序的入口点
用于 STREAMS 设备驱动程序的入口点
用于内存映射设备的入口点
网络设备驱动程序入口点
用于 SCSI HBA 驱动程序的入口点
用于 PC 卡驱动程序的入口点
设备驱动程序设计注意事项
DDI/DKI 功能
设备 ID
设备属性
中断处理
回调函数
软件状态管理
程控 I/O 设备访问
直接内存访问 (Direct Memory Access, DMA)
分层驱动程序接口
驱动程序上下文
返回错误
动态内存分配
热插拔
第 2 章 Solaris 内核和设备树
什么是内核?
多线程执行环境
虚拟内存
作为特殊文件的设备
DDI/DKI 接口
设备树概述
设备树组件
显示设备树
libdevinfo 库
prtconf 命令
/devices 目录
将驱动程序绑定到设备
通用设备名称
第 3 章 多线程
锁定原语
驱动程序数据的存储类
互斥锁
设置互斥锁
使用互斥锁
读取器/写入器锁
信号
线程同步
线程同步中的条件变量
初始化条件变量
等待条件
发出条件信号
cv_wait() 和 cv_timedwait() 函数
cv_wait_sig() 函数
cv_timedwait_sig() 函数
选择锁定方案
潜在的锁定缺点
线程无法接收信号
第 4 章 属性
设备属性
设备属性名称
创建和更新属性
查找属性
prop_op() 入口点
第 5 章 管理事件和排队任务
管理事件
事件介绍
使用 ddi_log_sysevent() 记录事件
ddi_log_sysevent() 语法
记录事件的样例代码
定义事件特性
排队任务
任务队列简介
任务队列接口
使用任务队列
观察任务队列
任务队列内核统计信息计数器
任务队列 DTrace SDT 探测器
第 6 章 驱动程序自动配置
驱动程序的装入和卸载
驱动程序必需的数据结构
modlinkage 结构
modldrv 结构
dev_ops 结构
cb_ops 结构
可装入驱动程序接口
_init() 示例
_fini() 示例
_info() 示例
设备配置概念
设备实例和实例编号
次要节点和次要设备号
probe() 入口点
attach() 入口点
驱动程序软状态管理
锁变量和条件变量的初始化
创建从设备节点
延迟连接
detach() 入口点
getinfo() 入口点
使用设备 ID
注册设备 ID
注册设备提供的 ID
注册虚构 ID
注销设备 ID
第 7 章 设备访问:程控 I/O
设备内存
管理设备和主机字节序之间的差别
管理数据排序要求
ddi_device_acc_attr 结构
映射设备内存
映射设置示例
设备访问函数
备用设备访问接口
访问内存空间
访问 I/O 空间
PCI 配置空间访问
第 8 章 中断处理程序
中断处理程序概述
设备中断
高级别中断
传统中断
标准消息告知中断和扩展消息告知中断
MSI 中断
MSI-X 中断
软件中断
DDI 中断函数
中断功能函数
中断初始化和销毁函数
优先级管理函数
软中断函数
中断函数示例
注册中断
注册传统中断
注册 MSI 中断
中断资源管理
中断资源管理功能
回调接口
注册回调处理程序函数
取消注册回调处理程序函数
回调处理程序函数
中断请求接口
分配中断
修改所请求的中断向量数量
中断用法和灵活性
中断资源管理实现样例
中断处理程序功能
处理高级别中断
高级互斥锁
高级别中断处理示例
第 9 章 直接内存访问 (Direct Memory Access, DMA)
DMA 模型
设备 DMA 的类型
总线主控器 DMA
第三方 DMA
第一方 DMA
主机平台 DMA 的类型
DMA 软件组件:句柄、窗口和 Cookie
DMA 操作
执行总线主控器 DMA 传送
执行第一方 DMA 传送
执行第三方 DMA 传送
DMA 特性
ddi_dma_attr 结构
S 总线示例
ISA 总线示例
管理 DMA 资源
对象锁定
分配 DMA 句柄
分配 DMA 资源
设备寄存器结构
DMA 回调示例
确定最大突发流量大小
分配专用 DMA 缓冲区
处理资源分配故障
对 DMA 引擎进行编程
释放 DMA 资源
释放 DMA 句柄
取消 DMA 回调
同步内存对象
高速缓存
ddi_dma_sync() 函数
DMA 窗口
第 10 章 映射设备和内核内存
内存映射概述
导出映射
segmap(9E) 入口点
devmap(9E) 入口点
将设备内存与用户映射相关联
将内核内存与用户映射相关联
为用户访问分配内核内存
将内核内存导出到应用程序
释放为用户访问导出的内核内存
第 11 章 设备上下文管理
设备上下文简介
什么是设备上下文?
上下文管理模型
上下文管理操作
devmap_callback_ctl 结构
用于设备上下文管理的入口点
devmap_map() 入口点
devmap_access() 入口点
devmap_contextmgt() 入口点
devmap_dup() 入口点
devmap_unmap() 入口点
将用户映射与驱动程序通知关联
管理映射访问
devmap_load() 入口点
devmap_unload() 入口点
第 12 章 电源管理
电源管理框架
设备电源管理
系统电源管理
设备电源管理模型
电源管理组件
多个电源管理组件
电源管理状态
电源级别
电源管理相关性
设备的自动电源管理
设备电源管理接口
繁忙-空闲状态转换
设备能耗状态转换
power() 入口点
系统电源管理模型
自动关闭阈值
繁忙状态
硬件状态
系统的自动电源管理
系统电源管理使用的入口点
detach() 入口点
attach() 入口点
电源管理设备访问示例
电源管理控制流程
电源管理接口的更改
第 13 章 强化 Solaris 驱动程序
Sun 故障管理体系结构 I/O 故障服务
什么是预测性自我修复?
Solaris Fault Manager
诊断、可疑列表和故障事件
响应代理
消息 ID 和字典文件
系统拓扑
错误处理
声明故障管理功能
清除故障管理资源
获取故障管理功能位掩码
报告错误
对错误事件排队
检测和报告与 PCI 相关的错误
报告标准 I/O 控制器错误
服务影响函数
访问属性结构
DMA 属性结构
获取错误状态
清除错误
注册错误处理程序
故障管理数据和状态结构
诊断故障
标准叶设备诊断
专门的设备诊断
事件注册表
词汇表
资源
用于 Solaris 设备驱动程序的防御性编程方法
使用单独的设备驱动程序实例
独占使用 DDI 访问句柄
检测已损坏的数据
设备管理和控制数据的损坏
已接收数据的损坏
DMA 隔离
处理有问题的中断
其他编程注意事项
线程交互
自上而下请求的威胁
自适应策略
驱动程序强化测试工具
故障注入
设置测试工具
安装测试工具
配置测试工具
测试驱动程序
创建故障
注入故障
故障注入过程
测试工具警告
使用脚本自动完成测试过程
自动化测试过程
第 14 章 分层驱动程序接口 (Layered Driver Interface, LDI)
LDI 概述
内核接口
分层标识符-内核设备使用方
分层驱动程序句柄-目标设备
打开和关闭目标设备
访问目标设备
检索目标设备信息
检索目标设备属性值
接收异步设备事件通知
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 章 块设备驱动程序
块驱动程序结构概述
文件 I/O
块设备自动配置
控制设备访问
open() 入口点(块驱动程序)
close() 入口点(块驱动程序)
strategy() 入口点
buf 结构
bp_mapin 结构
同步数据传输(块驱动程序)
异步数据传输(块驱动程序)
检查是否有无效的 buf 请求
对请求进行排队
开始第一个传输
处理中断的设备
dump() 和 print() 入口点
dump() 入口点(块驱动程序)
print() 入口点(块驱动程序)
磁盘设备驱动程序
磁盘 ioctl
磁盘性能
第 17 章 SCSI 目标驱动程序
目标驱动程序介绍
Sun 公用 SCSI 体系结构概述
常规控制流程
SCSA 函数
硬件配置文件
声明和数据结构
scsi_device 结构
scsi_pkt 结构(目标驱动程序)
SCSI 目标驱动程序的自动配置
probe() 入口点(SCSI 目标驱动程序)
attach() 入口点(SCSI 目标驱动程序)
detach() 入口点(SCSI 目标驱动程序)
getinfo() 入口点(SCSI 目标驱动程序)
资源分配
scsi_init_pkt() 函数
scsi_sync_pkt() 函数
scsi_destroy_pkt() 函数
scsi_alloc_consistent_buf() 函数
scsi_free_consistent_buf() 函数
生成和传输命令
生成命令
设置目标功能
传输命令
同步 scsi_transport() 函数
命令完成
重新使用包
自动请求检测模式
转储处理
SCSI 选项
第 18 章 SCSI 主机总线适配器驱动程序
主机总线适配器驱动程序介绍
SCSI 接口
SCSA HBA 接口
SCSA HBA 入口点摘要
SCSA HBA 数据结构
scsi_hba_tran() 结构
scsi_address 结构
scsi_device 结构
scsi_pkt 结构 (HBA)
按目标实例的数据
传输结构克隆
SCSA HBA 函数
HBA 驱动程序的相关性和配置问题
声明和结构
每个命令的结构
模块初始化入口点
_init() 入口点(SCSI HBA 驱动程序)
_fini() 入口点(SCSI HBA 驱动程序)
自动配置入口点
attach() 入口点(SCSI HBA 驱动程序)
软状态结构
DMA
传输结构
附加 HBA 驱动程序
寄存器映射
添加中断处理程序
创建可管理电源的组件
报告附加状态
detach() 入口点(SCSI HBA 驱动程序)
SCSA HBA 驱动程序入口点
目标驱动程序实例初始化
tran_tgt_init() 入口点
tran_tgt_probe() 入口点
tran_tgt_free() 入口点
资源分配
tran_init_pkt() 入口点
分配和初始化 scsi_pkt(9S) 结构
分配 DMA 资源
重新分配用于数据传送的 DMA 资源
tran_destroy_pkt() 入口点
tran_sync_pkt() 入口点
tran_dmafree() 入口点
命令传输
tran_start() 入口点
中断处理程序和命令完成
超时处理程序
功能管理
tran_getcap() 入口点
tran_setcap() 入口点
中止和重置管理
tran_abort() 入口点
tran_reset() 入口点
tran_bus_reset() 入口点
tran_reset_notify() 入口点
动态重新配置
SCSI HBA 驱动程序特定问题
安装 HBA 驱动程序
HBA 配置属性
scsi-reset-delay 属性
scsi-options 属性
按目标的 scsi-options
x86 目标驱动程序配置属性
排队支持
第 19 章 网络设备驱动程序
GLDv3 网络设备驱动程序框架
GLDv3 MAC 注册
GLDv3 MAC 注册过程
GLDv3 MAC 注册函数
mac_init_ops() 和·mac_fini_ops() 函数
mac_alloc() 和 mac_free() 函数
mac_register() 和 mac_unregister () 函数
GLDv3 MAC 注册数据结构
GLDv3 功能
硬件校验和负载转移
硬件校验和负载转移功能信息
mac_hcksum_get()() 函数标志
mac_hcksum_set()() 函数标志
大段(或发送)负载转移
GLDv3 数据路径
传输数据路径
流量控制
硬件校验和:硬件
大段负载转移
虚拟 LAN:硬件
接收数据路径
硬件校验和:MAC 层
虚拟 LAN:MAC 层
GLDv3 状态更改通知
GLDv3 网络统计信息
GLDv3 属性
GLDv3 接口汇总
GLDv2 网络设备驱动程序框架
GLDv2 设备支持
Ethernet V2 和 ISO 8802-3 (IEEE 802.3)
TPR 和 FDDI:SNAP 处理
TPR:源路由
GLDv2 DLPI 提供者
GLDv2 DLPI 原语
GLDv2 I/O 控制函数
GLDv2 驱动程序需求
GLDv2 网络统计信息
GLDv2 声明和数据结构
gld_mac_info 结构
gld_stats 结构
GLDv2 函数参数
GLDv2 入口点
gldm_reset() 入口点
gldm_start() 入口点
gldm_stop() 入口点
gldm_set_mac_addr() 入口点
gldm_set_multicast() 入口点
gldm_set_promiscuous() 入口点
gldm_send() 入口点
gldm_intr() 入口点
gldm_get_stats() 入口点
gldm_ioctl() 入口点
GLDv2 返回值
GLDv2 服务例程
gld_mac_alloc() 函数
gld_mac_free() 函数
gld_register() 函数
gld_unregister() 函数
gld_recv() 函数
gld_sched() 函数
gld_intr() 函数
第 20 章 USB 驱动程序
Solaris 环境中的 USB
USBA 2.0 框架
USB 客户机驱动程序
绑定客户机驱动程序
USB 设备如何显示在系统中
USB 设备和 Solaris 设备树
兼容设备名称
具有多个接口的设备
检查设备驱动程序绑定
基本设备访问
连接客户机驱动程序之前
描述符树
注册驱动程序以获取设备访问权限
设备通信
USB 端点
缺省管道
管道状态
打开管道
关闭管道
数据传输
同步传输、异步传输和回调
请求
分配和取消分配请求
请求特性和字段
控制请求
批量传输请求
中断请求
等时请求
刷新管道
设备状态管理
热插拔 USB 设备
热插拔回调
热插入
热移除
热重新插入
电源管理
设备电源管理
主动电源管理
被动电源管理
系统电源管理
序列化
实用程序函数
设备配置工具
获取接口编号
管理整个设备
多配置设备
修改或获取替代设置
其他实用程序函数
检索字符串描述符
管道专用数据工具
清除 USB 条件
获取设备、接口或端点状态
获取设备的总线地址
USB 设备驱动程序样例
第 3 部分 生成设备驱动程序
第 21 章 编译、装入、打包和测试驱动程序
驱动程序开发摘要
驱动程序代码布局
头文件
源文件
配置文件
准备安装驱动程序
编译和链接驱动程序
模块相关性
编写硬件配置文件
安装、更新和删除驱动程序
将驱动程序复制到模块目录
使用 add_drv 安装驱动程序
更新驱动程序信息
删除驱动程序
装入和卸载驱动程序
驱动程序打包
软件包后安装
软件包预删除
驱动程序测试条件
配置测试
功能测试
错误处理
测试装入和卸载
压力、性能和互操作性测试
DDI/DKI 兼容性测试
安装和打包测试
测试特定类型驱动程序
磁带驱动程序
磁盘驱动程序
异步通信驱动程序
网络驱动程序
第 22 章 调试、测试和调优设备驱动程序
测试驱动程序
启用 Deadman 功能以避免硬挂起
使用串行连接进行测试
针对 tip 连接设置主机系统
在 SPARC 平台上设置目标系统
在 x86 平台上设置目标系统
设置测试模块
设置内核变量
装入和卸载测试模块
使用 modload() 函数
使用 modinfo() 函数
使用 modunload()
设置 moddebug 内核变量
设置 kmem_flags 调试标志
避免测试系统中发生数据丢失
备份关键系统文件
使用替代内核进行引导
考虑替代备份计划
捕获系统崩溃转储
恢复设备目录
调试工具
事后调试
使用 kmdb 内核调试程序
在 SPARC 平台上使用替代内核引导 kmdb
在 x86 平台上使用替代内核引导 kmdb
在 kmdb 中设置断点
为驱动程序开发者提供的 kmdb 宏
使用 mdb 模块调试程序
模块调试程序入门
使用 kmdb 和 mdb 执行的有用调试任务
使用 kmdb 查找系统寄存器
检测内核内存泄漏
使用 mdb 编写调试程序命令
获取内核数据结构信息
获取设备树信息
检索驱动程序软状态信息
修改内核变量
调优驱动程序
内核统计信息
内核统计信息结构成员
内核统计信息结构
内核统计信息函数
Solaris 以太网驱动程序的内核统计信息
用于动态检测过程的 DTrace
第 23 章 推荐的编码方法
调试准备方法
使用唯一前缀来避免内核符号冲突
使用 cmn_err() 记录驱动程序活动
使用 ASSERT() 捕捉无效假设
使用 mutex_owned() 验证和记录锁定要求
使用条件编译在开销较大的调试功能之间切换
将变量声明为可变变量
可维护性
定期运行状况检查
第 4 部分 附录
附录 A 硬件概述
SPARC 处理器问题
SPARC 数据对齐
SPARC 结构中的成员对齐
SPARC 字节排序
SPARC 寄存器窗口
SPARC 乘法和除法指令
x86 处理器问题
x86 字节排序
x86 体系结构手册
字节存储顺序
存储缓冲区
系统内存模型
全存储排序 (Total Store Ordering, TSO)
部分存储排序 (Partial Store Ordering, PSO)
总线体系结构
设备标识
支持的中断类型
总线特定信息
PCI 局部总线
PCI 地址域
PCI 配置地址空间
PCI 配置基址寄存器
PCI 内存地址空间
PCI I/O 地址空间
PCI 硬件配置文件
PCI Express
S 总线
S 总线物理地址空间
物理 S 总线地址
S 总线硬件配置文件
设备问题
时间关键型部分
延迟
内部顺序逻辑
中断问题
SPARC 计算机上的 PROM
Open Boot PROM 3
Forth 命令
遍历 PROM 设备树
映射设备
读取和写入
附录 B Solaris DDI/DKI 服务汇总
模块函数
设备信息树节点 (dev_info_t) 函数
设备 (dev_t) 函数
属性函数
设备软件状态函数
内存分配和取消分配函数
内核线程控制和同步函数
任务队列管理函数
中断函数
程控 I/O 函数
直接内存访问 (Direct Memory Access, DMA) 函数
用户空间访问函数
用户进程事件函数
用户进程信息函数
用户应用程序内核和设备访问函数
与时间有关的函数
电源管理函数
故障管理函数
内核统计信息函数
内核日志记录和列显函数
缓存 I/O 函数
虚拟内存函数
设备 ID 函数
SCSI 函数
资源映射管理函数
系统全局状态
实用程序函数
附录 C 使设备驱动程序支持 64 位
64 位驱动程序设计简介
常规转换步骤
使用硬件寄存器的固定宽度类型
使用固定宽度的公共访问函数
检查并扩展派生类型的用法
检查 DDI 数据结构中更改的字段
buf 结构更改
ddi_dma_attr
ddi_dma_cookie 结构更改
csi_arq_status 结构更改
scsi_pkt 结构更改
检查 DDI 函数中更改的参数
getrbuf() 参数更改
drv_getparm() 参数更改
delay() 和 timeout() 参数更改
rmallocmap() 和 rmallocmap_wait() 参数更改
scsi_alloc_consistent_buf() 参数更改
uiomove() 参数更改
cv_timedwait() 和 cv_timedwait_sig() 参数更改
ddi_device_copy() 参数更改
ddi_device_zero() 参数更改
ddi_dma_mem_alloc() 参数更改
修改处理数据共享的例程
ioctl() 中的数据共享
devmap() 中的数据共享
mmap() 中的数据共享
检查 x86 平台上 64 位 Long 数据类型的结构
已知的 ioctl 接口
设备大小
附录 D 控制台帧缓存器驱动程序
Solaris 控制台和内核终端仿真器
x86 平台控制台通信
SPARC 平台控制台通信
控制台可视化 I/O 接口
I/O 控制接口
轮询式 I/O 接口
视频模式更改回调接口
在控制台帧缓存器驱动程序中实现可视化 I/O 接口
VIS_DEVINIT
VIS_DEFINI
VIS_CONSDISPLAY
VIS_CONSCOPY
VIS_CONSCURSOR
VIS_PUTCMAP
VIS_GETCMAP
在控制台帧缓存器驱动程序中实现轮询式 I/O
特定于帧缓存器的配置模块
特定于 X 窗口系统帧缓存器的 DDX 模块
开发、测试和调试控制台帧缓存器驱动程序
测试 I/O 控制接口
测试轮询式 I/O 接口
测试视频模式更改回调函数
有关测试控制台帧缓存器驱动程序的其他建议
© 2010, Oracle Corporation and/or its affiliates