常见的驱动程序设计问题

《常见的驱动程序设计问题》由会员分享,可在线阅读,更多相关《常见的驱动程序设计问题(20页珍藏版)》请在文档大全上搜索。
1、常见的驱动程序设计问题 这一章介绍了所有驱动程序开发者都会感兴趣的一些内容,主要包括以下几部分: 总结了标准驱动程序例程运行的缺省硬件优先级(IRQL)以及在适当的IRQL上调用支持例程的一些策略 关于使用自旋锁的一般策略,这些自旋锁用来同步对驱动程序例程共享的数据或资源的访问
2、 关于用内核栈和后备列表分配系统空间内存的一般策略。 驱动程序应该怎样处理I/O错误,以及NTSTATUS值是怎样定义的 怎样使所有或部分驱动程序映像可分页 怎样注册设备接口以使其他内核模式和
3、用户模式的代码可以访问设备 怎样避免会影响驱动程序可靠性的的常见问题这一章还讨论了设备类型决定或设计决定的设计问题,包括下列内容: 对最低层设备驱动程序,是驱动程序轮询设备,还是建立一个等待Kernel定义的调度者对象的线程,即是用时间还是用信号量
4、160; 对于DMA或PIO驱动程序,怎样在传输操作期间维护缓存的一致性和数据的完整性 对于可删除存储介质设备(removable-media)的驱动程序,怎样处理用户引起的错误(如提供了错误的存储介质或移除了在其上有文件打开的存储介质)这一章的目录如下:16.1 管理硬件优先级16.2 使用自旋锁16.2.1 为自旋锁和被保护数据提供存储空间16.2.2 初始化自旋锁16.2.3 调用使用了自旋锁的支持例程16.2.4 快速释放自旋锁16.2.5 使用自旋锁时防止错误或死锁
5、的出现16.3 轮询设备16.4 管理内存的使用16.4.1 使用系统内存16.4.1.1 访问用户空间内存的驱动程序16.4.1.2 为部分传输请求建立MDL16.4.1.3 分配系统空间内存16.4.1.4 将总线相关(Bus-Relative)的内存空间地址重新映射为虚地址16.4.2 使用内核栈16.4.3 使用后备列表(lookaside list)16.5 对DMA和PIO维护缓存的一致性16.5.1 在DMA操作期间刷新缓存数据16.5.2 在PIO操作期间刷新缓存数据16.6 错误记录和NTSTATUS值16.6.1 调用IoAllocateErrorLogEntry16.6.
6、2 填充错误记录包16.6.3 设置错误记录包中的NTSTATUS值16.6.4 调用IoWriteErrorLogEntry16.6.5 定义新的IO_ERR_XXX16.6.6 定义私有NTSTATUS常量16.7 处理可删除存储介质16.7.1 响应来自文件系统的验证(Check-Verify)请求16.7.2 通知文件系统可能的存储介质改变16.7.3 检查设备对象中的标志16.7.4 在中间层驱动程序中建立IRP16.8 使设备对应用程序和驱动程序可用16.8.1 注册设备接口16.8.2 使设备接口可用和不可用16.8.3 使用设备接口16.9 可分页代码和数据16.9
7、.1 使驱动程序代码可分页16.9.2 锁住可分页代码或数据16.9.3对整个驱动程序分页16.10 常见的驱动程序可靠性问题16.10.1 缓冲I/O中的错误16.10.2 引用用户空间地址时的错误16.10.3 直接I/O中的错误16.10.4 调用者输入和设备状态的错误16.10.5 Dispatch例程中的错误16.10.6 多处理器环境中的错误16.10.7 处理IRP时的错误1.1 管理硬件优先级特定设备或中间层驱动程序例程运行的IRQL决定了它能调用哪些内核模式的支持例程。例如,有些支持例程要求调用者运行在为DISPATCH_LEVEL的IRQL上。其他例程在调用者运行在提高的(
8、raised)IRQL(即高于PASSIVE_LEVEL的IRQL)时不能被安全地调用。表16.1列出了最常见的标准驱动程序例程被调用的缺省IRQL以及Kernel定义的IRQL值(由低到高)。 表16.1 驱动程序例程的缺省IRQLIRQL(由低到高) 屏蔽掉的中断 运行在此IRQL的支持例程 PASSIVE_LEVEL 无 Dispatch、DriverEntry、AddDevice、Reinitialize、Unload例程、驱动程序创建的线程、工作者线程(work-thread)回调、文件系统驱动程序 DISPATCH_LEVEL DISPATCH_LEVEL和
9、APC_LEVEL中断被屏蔽掉了。设备、时钟和电源错误中断仍可发生 StartIo、AdapterControl、AdapterListControl、ControllerControl、IoTimer、Cancel(持有撤消自旋锁时)、DpcForIsr、CustomTimerDpc、CustomDpc例程 DIRQL 驱动程序中断对象中所有IRQL<=DIRQL的中断。时钟和电源错误中断仍可发生 ISR、SyncCritSection例程 当运行在下列三种IRQL之一时,由最低层驱动程序处理IRP: &
10、#160; PASSIVE_LEVEL:没有处理器中断被屏蔽掉,在驱动程序的Dispatch例程中。DriverEntry、AddDevice、Reinitialize和Unload例程也运行在PASSIVE_LEVEL,此外还有驱动程序创建的系统线程 DISPATCH_LEVEL:处理器的DISPATCH_LEVEL和APC_LEVEL中断被屏蔽掉了,在StartIo例程中。AdapterControl、AdapterListControl、Cont
11、rollerControl、IoTimer、Cancel(持有撤消自旋锁时)、DpcForIsr、CustomTimerDpc和CustomDpc例程也都运行在DISPATCH_LEVEL。 Device IRQL(DIRQL):处理器上所有低于或等于驱动程序中断对象的SynchronizeIrql的中断都被屏蔽掉了,在ISR和SyncCritSection例程中。当运行在下列两种IRQL时,由更高层驱动程序处理IRP: