-
-
[未解决,已结帖]
[求助]MDL映射硬件的io资源蓝屏
100.00雪花
-
发表于:
2019-6-5 22:35
3141
-
[未解决,已结帖] [求助]MDL映射硬件的io资源蓝屏
100.00雪花
我做一个pcie驱动,底层的硬件bar空间在内核里面用了LocalMmMapIoSpace函数映射到了内核的虚拟地址,也可以操作,没什么问题,但是操作需要通过ioctl系统调用实现,感觉效率不高,想直接将这个映射到用户层,通过mdl,在linux系统是实现了的,windows就没有搞定,mdl映射蓝屏,想请教各位,是不是windows的外设io资源不能映射到用户层,感觉不应该,映射到内核虚拟地址可以,用户层虚拟地址应该也可以。
应用层io命令-----------》ioctl 调用映射-------------》返回映射的虚拟地址。
MmbarInfo 是一个结构体里面包含,用户层的地址,内核地址,mdl句柄,大小,方便iocrl传递
bar空间映射
pDeviceContext->PhysicalAddressRegister = descriptor->u.Memory.Start.LowPart;
pDeviceContext->BAR0_VirtualAddress = MmMapIoSpace(
descriptor->u.Memory.Start,
descriptor->u.Memory.Length,
MmNonCached);
pDeviceContext->MmBarInfo.KVA = pDeviceContext->BAR0_VirtualAddress;
pDeviceContext->MmBarInfo.SIZE = descriptor->u.Memory.Length;
用户层调用,ioctl,拷贝会映射的虚拟地址
case TK_IOCTL_ALLOC_BAR:
status = WdfRequestRetrieveOutputBuffer(Request, sizeof(DmaMmInfo), &outBuffer, NULL);
/*BAR寄存*/
Tk_DmaBarRemapUser(device, pDevContext, &pDevContext->MmBarInfo);
RtlCopyMemory(outBuffer, &pDevContext->MmBarInfo, sizeof(DmaMmInfo));
WdfRequestCompleteWithInformation(Request, status, sizeof(DmaMmInfo));
if (!NT_SUCCESS(status))
goto Exit;
break;
映射函数的内部实现
NTSTATUS Tk_DmaBarRemapUser(IN WDFDEVICE Device,
IN OUT PDEVICE_CONTEXT deviceContext,
OUT DmaMmInfo * pMmInfo)
{
NTSTATUS status = STATUS_SUCCESS;
PMDL BufferMdl = IoAllocateMdl(pMmInfo->KVA, (ULONG)pMmInfo->SIZE, FALSE, FALSE, NULL);
//其实是确保非分页
MmBuildMdlForNonPagedPool(BufferMdl);
//锁定物理页面的映射关系
MmProbeAndLockPages(BufferMdl, KernelMode, (IoReadAccess | IoWriteAccess | IoModifyAccess));
pMmInfo->UVA = MmMapLockedPagesSpecifyCache(BufferMdl, UserMode, MmNonCached, NULL, FALSE, NormalPagePriority);
if (!pMmInfo->UVA)
{
MmFreePagesFromMdl(BufferMdl);
IoFreeMdl(BufferMdl);
status = STATUS_INSUFFICIENT_RESOURCES;
return status;
}
pMmInfo->PMD = BufferMdl;
return status;
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2019-6-6 09:56
被张飞online编辑
,原因: