您的位置:首页 > 理论基础 > 计算机网络

内核驱动加载调试(1)

2009-01-08 15:26 218 查看
背景知识
 
1 驱动相关
驱动在硬件上,操作系统提供给应用程序接口以下.
WINDOWS2000/XP上的设备驱动程序不直接操作硬件,而是调用HAL功能作为与硬件的接口。
WINDOWS2000/XP上有如下几种类型的设备驱动程序: 
   1。硬件设备驱动程序操作硬件,它将输出写入物理设备或网络,并从物理设备或网络获得输入; 
   2。文件系统驱动程序接受面向文件的I/O请求,并把它们转化为对特殊设备的I/O请求。 
   3。过滤驱动程序截取I/O并在传递I/O到下一层之前执行某些特定处理。

  从WDM的角度看,有三种驱动程序: 
  1。总线驱动程序用于各种总线控制器、适配器、桥或可以连接子设备的设备,这是必须的驱动程序 
  2。功能驱动程序用于驱动那些主要的设备,提供设备的操作接口。一般来说,这也是必须的,除非采用一种原始的方法来使用这个设备(功能都被总线驱动和总线过滤器实现了,如SCSI PASSTHRU)。 
  3。过滤器驱动程序用于为一个设备或一个已经存在的驱动程序增加功能,或者改变来自其他驱动程序的I/O请求和响应行为。过滤驱动程序是可选的,并且可以有任意的数目,它存在于功能驱动程序的上层或者下层、总线驱动程序的下层。
2 一个简单的驱动程序
在VS中编写,驱动入口点是DriverEntry,类似于C/C++中的main,_tmain.
一个完整的驱动程序还应该包含有驱动卸载例程.unload rountine.

示例:

//一个简单的驱动程序实例
#include "ntddk.h"
NTSTATUS DriverEntry ( IN  PDRIVER_OBJECT theDriverObject,
IN  PUNICODE_STRING theRegistryPath )
{
DbgPrint("I am a driver!");
return STATUS_SUCCESS;
}
 
如何为其添加卸载例程:

//一个简单的驱动程序实例
#include "ntddk.h"
// 这里是我们的卸载函数
VOID MyUnload( IN PDRIVER_OBJECT DriverObject )
{
DbgPrint("MyUnload called/n");
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,
IN PUNICODE_STRING theRegistryPath)
{
DbgPrint("I am a driver and I loaded!");
// 初始化DriverObject对象中指向卸载函数的指针
theDriverObject->DriverUnload  =  MyUnload;
return STATUS_SUCCESS;
}
这样一来,我们用重启系统就能方便地装载和卸载驱动程序了。
3 驱动集成开发调试环境
开发
构建驱动集成开发环境,这个内容太多了.见下节内核驱动加载调试(2)
 
调试
光在编译的时候看打印语句,是无法看到的.因为驱动程序打印的位置在内核.只有使用WinDbg等调试工具,才能够看见打印信息。
有两种调试方案:
(1)使用DebugView与DDK在同一系统中直接进行调试.DebugView是一款本地调试软件,它能捕获驱动程序的调试输出信息。DebugView不仅能够捕获用户模式的应用程序产生的调试输出,而且还能捕获Windows内核本身或/和内核模式设备驱动程序所产生的调试输出信息。
使用InstDrv安装启动编译好的驱动程序.然后使用DebugView查看打印信息.
(2)在两个系统中使用WinDbg与DDK。将DDK安装在虚拟机中,使用WinDbg在主系统中,查看虚拟机运行驱动程序打印出的打印信息.(推荐使用)
由于驱动很容易把系统跑挂,使用虚拟机开发,可以及时的恢复系统.WinDbg能够捕获用户态应用程序打印信息,由于虚拟机对于主系统来说,是在上层的.用WinDbg能够看到在虚拟机中的驱动程序产生的调试输出信息.
在主系统中使用以下语句,连接虚拟机和主系统中的WinDbg.
"C:/Program Files/Debugging Tools for Windows/windbg.exe" -b -k com:pipe,port=//./pipe/com_1,baud=115200,reconnect -y

D:/WINDOWS/Symbols;srv*D:/Mysymbols*h

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息