阅读:1571回复:6
求救:RtlCopyMemory在writedispatch出现page fault
用DS3.0开发2000下PCI FPGA仿真加速卡的WDM驱动,busmaster,DO_DIRECT_IO,
因为数据传输量小(128字节)而且严格遵循收发间隔的半双工状态,所以使用common buffer,作为Tx和Rx DMA缓冲区。 NTSTATUS FPGAPCIWriteDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PFPGAPCI_DEVICE_EXTENSION deviceExtension; NTSTATUS status; PIO_STACK_LOCATION irpStack; PVOID writeBuffer; ULONG writeLength; ULONG numberOfMapRegisters; BOOLEAN isRead = FALSE; KIRQL oldIrql; FPGAPCIDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__\"++. IRP %p\", Irp); deviceExtension = (PFPGAPCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension; status = FPGAPCICheckIoLock(&deviceExtension->IoLock, Irp); if (!NT_SUCCESS(status) || (status == STATUS_PENDING)) { FPGAPCIDebugPrint(DBG_IO, DBG_WARN, __FUNCTION__\"--. IRP %p STATUS %x\", Irp, status); return status; } //save current IRP deviceExtension->WriteCurrentIrp = Irp; // Get our IRP stack location irpStack = IoGetCurrentIrpStackLocation(Irp); // Get the write buffer length writeLength = irpStack->Parameters.Write.Length; writeBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); // dma allocations should be called at DISPATCH_LEVEL //KeRaiseIrql(DISPATCH_LEVEL, &oldIrql); RtlCopyMemory(deviceExtension->RxCmBuf.StartVa, writeBuffer, writeLength); //错误!!!Page Fault (0Eh). Fault=0002 SetTxDma(deviceExtension,TRUE); //KeLowerIrql(oldIrql); FPGAPCIDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__\"--. IRP %p STATUS %x\", Irp, status); return status; } 原先我以为是writeBuffer是分页内存的原因,但是我在 RtlCopyMemory(deviceExtension->RxCmBuf.StartVa, writeBuffer, writeLength)前加 RtlZeroMemory(writeBuffer, 128); //能正确执行 RtlZeroMemory(deviceExtension->RxCmBuf.StartVa, 128); //现象同上Page Fault (0Eh). Fault=0002 由此我判断是deviceExtension->RxCmBuf.StartVa是分页内存造成的错误。 使用DO_BUFFER_IO也是同样的现象, 哪位大侠能指点迷津,不胜感激! |
|
沙发#
发布于:2005-03-01 20:23
RtlCopyMemory只有在两个常驻内存的区域互相拷贝的时候,,才可以运行在DISPATCH_LEVEL........
否则只能在小于DISPATCH_LEVEL下使用,,,。。 这里没有在dispztch 级下运行。。。。怎么会出现缺页bug那?。。 |
|
|
板凳#
发布于:2005-03-01 20:39
原来在在DISPATCH_LEVEL出现分页错误,我就该用DO_BUFFER_IO,错误还是没有变,所以就把KeRaiseIrql函数去掉了,但是这个问题仍然没有消除。
难道是AllocateCommonBuffer调用时有问题? |
|
地板#
发布于:2005-03-01 21:46
我想知道我这种把user data拷贝到common buffer中,然后配置DMA发送,这种思路是否可行?
|
|
地下室#
发布于:2005-03-01 21:54
我想知道我这种把user data拷贝到common buffer中,然后配置DMA发送,这种思路是否可行? 你看看。。《windows WDM 驱动开发指南》那有这么个buffer传输例子 我记得不清楚了,,, 那本书网上也有电子版的,,找找吧,,好运! |
|
|
5楼#
发布于:2005-03-01 22:58
方式是没有错
你检查过那个length么 在rtlcopymemory那里设置一个断点 然后用page 命令看看? common buffer就是这样使用的啊.... 其实 你的pci设备既然是bus master...那就应该会支持 gather scatter的吧.... 为什么不使用 AllocateChannel MapTransfer FreeChannel 这样的函数呢.... bus master跟 gather scatter的设备所调用的这些函数基本都是直接return的.... |
|
6楼#
发布于:2005-03-03 13:40
问题已经解决,用page查看发现deviceExtension->RxCmBuf.StartVa为NULL,是我在前面的程序不小心把它设置为NULL的。
怎么给分? |
|