阅读:2190回复:19
关于中断死机的问题
板子是pci总线的,通过读配置寄存器,获得其interrupt register值为11,代码如下:
Vec = HalGetInterruptVector(PCIBus, 0, 11, //(1) 11, //(1) &Irql, &DeviceExtension->Affinity); if (Vec == 0) DbgPrint(\"HalGetInterruptVector failed\\n\"); sts = IoConnectInterrupt(&DeviceExtension->InterruptObject, IntIsr, // ServiceRoutine DeviceObject, // ServiceContext NULL, // SpinLock Vec, // Vector Irql, // Irql Irql, // SynchronizeIrql LevelSensitive, // InterruptMode TRUE, // ShareVector DeviceExtension->Affinity, // ProcessorEnableMask FALSE); // FloatingSave 运行后,整个win2000就死机了,但没有重启也没有蓝屏.经过测试发现问题出在IoConnectInterrupt函数上,注释掉 它后,就不死机了! 又进一步测试,发现如果将HalGetInterruptVectort函数中的两个11换成9,IoConnectInterrupt则正常返回,换成 7就返回失败,再换回11仍旧死机! 我想这两个函数用法应该没有问题,是不是和系统有关系,凭我的经验我真分析不出是什么问题,请大家帮我看看, 谢谢您的指教!! |
|
沙发#
发布于:2005-04-04 17:17
还有一点忘说了,就是pci bus 有master abort错误,我也不懂这是什么意思??不知和这个有没有关系?
|
|
板凳#
发布于:2005-04-05 11:14
我将驱动sys文件拷贝到另一台机器试了,还是死机!
还有,驱动退出时没有IoDisconnectInterrupt,这会有影响吗? |
|
地板#
发布于:2005-04-05 12:44
在2K下吗?pnp了就不需要自己去查资源,os会给你的
需要disconnect |
|
地下室#
发布于:2005-04-05 13:27
谢谢arthurtu
是在w2k下,但驱动是NT下的,也就是没用wdm的pnp等功能 还有,我现在用的测试代码和硬件没有关系,在DriverEntry中主要就使用了HalGetInterruptVector和IoConnectInterrupt两个函数, 就象前面那段代码一样,(1)处取固定值11就死机,取9就可以正常注册中断(IoConnectInterrupt返回成功),问题就是中断9和中断11有什么区别?为什么11就死机,9就正常!!! 我看了cmos中的中断资源,9和11配置相同,真搞不明白! 谢谢大家了! |
|
5楼#
发布于:2005-04-05 15:08
那你的IntIsr干了些什么?简单的返回FALSE?
|
|
6楼#
发布于:2005-04-05 15:22
为了学习使用dpc,所以IntIsr中只有一句IoRequestDpc,但返回TRUE
可我觉的与IntIsr没关系,因为写9时使用的是同一个IntIsr,且不死机!!!写11就死机 |
|
7楼#
发布于:2005-04-05 15:40
可能就是因为你返回true的缘故,既然不是你的中断,你应该返回false,让系统继续找应该处理此中断的isr去
不同的中断被不同的设备占用,因此现象不一样 |
|
8楼#
发布于:2005-04-05 16:09
谢谢arthurtu的耐心指导
我通过\"设备管理器\"看了一下,中断11没有被占用,而中断9却被多个设备使用!不知能否通过这种方式查看系统中断资源的使用情况? 谢谢!! |
|
9楼#
发布于:2005-04-06 17:09
我又试了一下,发现设置为中断5也死机,设置为1,3,4时Ioconnectinterrupt返回失败,但不死机!
pci板子系统分配它的中断就是11,运行到ioconnectinterrupt就死机,这可怎么办,能否让系统不分11给板子,比如分个9什么的是不是就不会死机了?? 谢谢 |
|
10楼#
发布于:2005-04-07 11:14
一般,1是键盘的,3、4是COM1和COM2用的,都不会和你共享中断,故connect失败
你在你的ISR返回直接false,什么都不干,应该就不死机了,不是使用哪个中断号的问题 |
|
11楼#
发布于:2005-04-07 12:39
谢谢arthurtu
我又试了,问题依旧 代码在下面,大家有时间的话帮我看看,谢谢!!! /****************************************************/ #include <ntddk.h> typedef struct _LOCAL_DEVICE_INFO { PKINTERRUPT InterruptObject; ULONG Level; ULONG Vector; KAFFINITY Affinity; ULONG intSucc; } LOCAL_DEVICE_INFO, *PLOCAL_DEVICE_INFO; NTSTATUS InterruptCreateDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) { Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } BOOLEAN InterruptIsr(IN PKINTERRUPT Interrupt, IN OUT PVOID Context) { return FALSE; } VOID InterruptUnload(IN PDRIVER_OBJECT DriverObject) { WCHAR DOSNameBuffer[] = L\"\\\\DosDevices\\\\Interrupt\"; UNICODE_STRING uniDOSString; PLOCAL_DEVICE_INFO extension = DriverObject->DeviceObject->DeviceExtension; /* Disconnect Interrupt */ if (!extension->intSucc) IoDisconnectInterrupt(extension->InterruptObject); /* Delete Symbolic Link */ RtlInitUnicodeString(&uniDOSString, DOSNameBuffer); IoDeleteSymbolicLink (&uniDOSString); /* Delete Device */ IoDeleteDevice(DriverObject->DeviceObject); } NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath) { PDEVICE_OBJECT DeviceObject; NTSTATUS status; PLOCAL_DEVICE_INFO DeviceExtension; ULONG MappedVector; KIRQL Irql; WCHAR NameBuffer[] = L\"\\\\Device\\\\Interrupt\"; WCHAR DOSNameBuffer[] = L\"\\\\DosDevices\\\\Interrupt\"; UNICODE_STRING uniNameString, uniDOSString; RtlInitUnicodeString(&uniNameString, NameBuffer); RtlInitUnicodeString(&uniDOSString, DOSNameBuffer); status = IoCreateDevice(DriverObject, // DriverObject sizeof(LOCAL_DEVICE_INFO), // DeviceExtensionSize &uniNameString, // DeviceName FILE_DEVICE_UNKNOWN, // DeviceType 0, // DeviceCharacteristics TRUE, // Exclusive &DeviceObject); // *DeviceObject if(!NT_SUCCESS(status)) return status; DeviceExtension = DeviceObject->DeviceExtension; DeviceExtension->intSucc = 0; status = IoCreateSymbolicLink (&uniDOSString, &uniNameString); if (!NT_SUCCESS(status)) return status; DeviceExtension->Level = 11; //(1) DeviceExtension->Vector = DeviceExtension->Level; MappedVector = HalGetInterruptVector(PCIBus, 0, DeviceExtension->Level, DeviceExtension->Vector, &Irql, &DeviceExtension->Affinity); if (MappedVector == 0) { DbgPrint(\"Interrupt.sys: HalGetInterruptVector failed\\n\"); return status; } status = IoConnectInterrupt(&DeviceExtension->InterruptObject, // InterruptObject InterruptIsr, // ServiceRoutine DeviceObject, // ServiceContext NULL, // SpinLock MappedVector, // Vector Irql, // Irql Irql, // SynchronizeIrql LevelSensitive,//Latched, // InterruptMode TRUE,//FALSE, // ShareVector DeviceExtension->Affinity, // ProcessorEnableMask FALSE); // FloatingSave if (!NT_SUCCESS (status)) { DbgPrint(\"Interrupt.sys: IoConnectInterrupt Failed!\\n\"); DeviceExtension->intSucc = 1; } else DbgPrint(\"Interrupt.sys: IoConnectInterrupt Success!\\n\"); DriverObject->MajorFunction[IRP_MJ_CREATE] = InterruptCreateDispatch; DriverObject->DriverUnload = InterruptUnload; return STATUS_SUCCESS; } /******************************************/ 如果方便,可以编译运行试试!后果不负,haha! 我是用build -cZ编译后,用driver loader加载的,一加载就死机, 鼠标什么的全静止了,只能reboot 再次感谢!! |
|
12楼#
发布于:2005-04-08 11:55
又查了一下,ioconnectinterrupt返回值是STATUS_INVALID_PARAMETER
|
|
13楼#
发布于:2005-04-11 12:51
问题又来了,我找了一个程序,可以将自己的中断处理函数加入中断向量表中,之后
我用asm int xx可以运行该中断处理函数,但我用HalGetInterruptVector和IoConnectInterrupt返回成功后,也就是将连接中断处理函数成功,再用asm int xx指令触发中断,可是没有任何反映,应用程序也找不到isr入口! 我想,这两种方式肯定有区别,请大家指教一下! 谢谢! |
|
14楼#
发布于:2005-04-12 12:13
又是一堆问题
(1)总感觉是和其他设备的共享中断造成了死机,有些资料上提到了KeSynchronizeExecution,难到共享中断必须用它吗? (2)如果IoConnectInterrupt返回成功,能否通过asm int XX指令触发ISR,我试了一下,isr没有反映,感觉是被其他isr给 半路劫走了! (3)对于pci设备,我们必须使用系统分配的中断号吗?如果可以自己指定,该如何做?? 谢谢! |
|
15楼#
发布于:2005-04-12 12:32
to worldcup:你是直接用DDK来开发驱动的吗?我下了DriverStudio,但调试工具SoftICE不好用,我不知道是我的问题还是软件的问题,反正是死活都不能用。你直接用DDk来开发,调试过程和写应用程序的调试一样吗?就设断点,然后用调试进行的吗?我现在真快绝望了,你有用Windriver来开发吗?调试是如何用的。
我是在读研究生,做的毕业课题是这个,老板要求我半年内完成,非常需要你的帮助。对浪费你宝贵的时间表示非常感谢!!! |
|
16楼#
发布于:2005-04-13 09:39
to cxm1212:
谈不上开发,我也是初学者 我现在是直接用ddk 不好意思,你说的driverstudio,softice我都没用过,不过这方面的资料我想网上应该不少!! 祝你顺利! |
|
17楼#
发布于:2005-04-13 09:42
又是一堆问题
(1)总感觉是和其他设备的共享中断造成了死机,有些资料上提到了KeSynchronizeExecution,难到共享中断必须用它吗? (2)如果IoConnectInterrupt返回成功,能否通过asm int XX指令触发ISR,我试了一下,isr没有反映,感觉是被其他isr给 半路劫走了! (3)对于pci设备,我们必须使用系统分配的中断号吗?如果可以自己指定,该如何做?? 谢谢! |
|
18楼#
发布于:2005-04-14 15:28
#include <ntddk.h>
typedef struct _LOCAL_DEVICE_INFO { PKINTERRUPT InterruptObject; ULONG Level; ULONG Vector; KAFFINITY Affinity; ULONG intSucc; } LOCAL_DEVICE_INFO, *PLOCAL_DEVICE_INFO; NTSTATUS InterruptCreateDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) { Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } BOOLEAN InterruptIsr(IN PKINTERRUPT Interrupt, IN OUT PVOID Context) { return FALSE; } VOID InterruptUnload(IN PDRIVER_OBJECT DriverObject) { WCHAR DOSNameBuffer[] = L\"\\\\DosDevices\\\\Interrupt\"; UNICODE_STRING uniDOSString; PLOCAL_DEVICE_INFO extension = DriverObject->DeviceObject->DeviceExtension; /* Disconnect Interrupt */ if (!extension->intSucc) IoDisconnectInterrupt(extension->InterruptObject); /* Delete Symbolic Link */ RtlInitUnicodeString(&uniDOSString, DOSNameBuffer); IoDeleteSymbolicLink (&uniDOSString); /* Delete Device */ IoDeleteDevice(DriverObject->DeviceObject); } NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath) { PDEVICE_OBJECT DeviceObject; NTSTATUS status; PLOCAL_DEVICE_INFO DeviceExtension; ULONG MappedVector; KIRQL Irql; UNICODE_STRING uniNameString, uniDOSString; RtlInitUnicodeString(&uniNameString, L\"\\\\Device\\\\Interrupt\"); RtlInitUnicodeString(&uniDOSString, L\"\\\\DosDevices\\\\Interrupt\"); status = IoCreateDevice(DriverObject, // DriverObject sizeof(LOCAL_DEVICE_INFO), // DeviceExtensionSize &uniNameString, // DeviceName FILE_DEVICE_UNKNOWN, // DeviceType 0, // DeviceCharacteristics TRUE, // Exclusive &DeviceObject); // *DeviceObject if(!NT_SUCCESS(status)) return status; // DeviceObject->Flags |= DO_BUFFERED_IO; DeviceExtension = DeviceObject->DeviceExtension; DeviceExtension->intSucc = 0; status = IoCreateSymbolicLink (&uniDOSString, &uniNameString); if (!NT_SUCCESS(status)) { IoDeleteDevice(DeviceObject); return status; } DeviceExtension->Level = 11; //(1) DeviceExtension->Vector = DeviceExtension->Level; MappedVector = HalGetInterruptVector(PCIBus, 0, DeviceExtension->Level, DeviceExtension->Vector, &Irql, &DeviceExtension->Affinity); if (MappedVector == 0) { DbgPrint(\"Interrupt.sys: HalGetInterruptVector failed\\n\"); IoDeleteSymbolicLink(&uniDOSString); IoDeleteDevice(DeviceObject); return status; } status = IoConnectInterrupt(&DeviceExtension->InterruptObject, // InterruptObject InterruptIsr, // ServiceRoutine DeviceObject, // ServiceContext NULL, // SpinLock MappedVector, // Vector Irql, // Irql Irql, // SynchronizeIrql LevelSensitive,//Latched, // InterruptMode TRUE,//FALSE, // ShareVector DeviceExtension->Affinity, // ProcessorEnableMask FALSE); // FloatingSave if (!NT_SUCCESS (status)) { DbgPrint(\"Interrupt.sys: IoConnectInterrupt Failed!\\n\"); IoDeleteSymbolicLink(&uniDOSString); IoDeleteDevice(DeviceObject); DeviceExtension->intSucc = 1; return status; } else DbgPrint(\"Interrupt.sys: IoConnectInterrupt Success!\\n\"); DriverObject->MajorFunction[IRP_MJ_CREATE] = InterruptCreateDispatch; DriverObject->MajorFunction[IRP_MJ_CLOSE] = InterruptCreateDispatch; DriverObject->DriverUnload = InterruptUnload; return STATUS_SUCCESS; } 不知道你的机器为什么挂了,我接11号(多个设备共享)、7号(空),都没有问题 |
|
19楼#
发布于:2005-04-14 15:41
谢谢arthurtu的耐心指导
在你的机器上可以用 { _asm { int 0xXX } } 触发中断吗?? 难道和主板有关系,我的主板是i810的,就是那种集成显卡的 谢谢了!! [编辑 - 4/15/05 by worldcup] |
|