阅读:2765回复:8
!!!帮帮我
我第一次开发驱动程序,任务是做公司专用板的驱动程序,是pci接口,芯片采用plx9052,在win2000下将物理地址转换为应用层使用的线形地址时总是转换不成功。
我尝试用MmMapIoSpace函数直接进行转换,程序刚开始运行时正常,但程序运行一段时间后,地址的内容就被全部改变了。是不是系统给更改了。 另外我用厂商提供的函数,主要应用ZwMapViewOfSection函数,但返回的是空地址,具体代码实现见附件。 我真是很着急,请高手们快帮帮忙,我先谢了。 |
|
沙发#
发布于:2001-07-16 16:50
看你的代码,你取得值有误,应该取ResourcesTranslated,不应该取ResourceRaw.
PCM_PARTIAL_RESOURCE_LIST partialResourceList; PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceTranslated; partialResourceList = &irpstack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList; ResourceTranslated=partialResourceListTranslated->PartialDescriptors; 你看mapmem就知道,传进去MapInUserSpace的值应该是translated后的。附上mapmem的部分代码 NTSTATUS MapMemMapTheMemory( IN PDEVICE_OBJECT DeviceObject, IN OUT PVOID IoBuffer, IN ULONG InputBufferLength, IN ULONG OutputBufferLength ) /*++ Routine Description: Given a physical address, maps this address into a user mode process's address space Arguments: DeviceObject - pointer to a device object IoBuffer - pointer to the I/O buffer InputBufferLength - input buffer length OutputBufferLength - output buffer length Return Value: STATUS_SUCCESS if sucessful, otherwise STATUS_UNSUCCESSFUL, STATUS_INSUFFICIENT_RESOURCES, (other STATUS_* as returned by kernel APIs) --*/ { PPHYSICAL_MEMORY_INFO ppmi = (PPHYSICAL_MEMORY_INFO) IoBuffer; INTERFACE_TYPE interfaceType; ULONG busNumber; PHYSICAL_ADDRESS physicalAddress; ULONG length; UNICODE_STRING physicalMemoryUnicodeString; OBJECT_ATTRIBUTES objectAttributes; HANDLE physicalMemoryHandle = NULL; PVOID PhysicalMemorySection = NULL; ULONG inIoSpace, inIoSpace2; NTSTATUS ntStatus; PHYSICAL_ADDRESS physicalAddressBase; PHYSICAL_ADDRESS physicalAddressEnd; PHYSICAL_ADDRESS viewBase; PHYSICAL_ADDRESS mappedLength; BOOLEAN translateBaseAddress; BOOLEAN translateEndAddress; PVOID virtualAddress; if ( ( InputBufferLength < sizeof (PHYSICAL_MEMORY_INFO) ) || ( OutputBufferLength < sizeof (PVOID) ) ) { MapMemKdPrint (("MAPMEM.SYS: Insufficient input or output buffer\n")); ntStatus = STATUS_INSUFFICIENT_RESOURCES; goto done; } interfaceType = ppmi->InterfaceType; busNumber = ppmi->BusNumber; physicalAddress = ppmi->BusAddress; inIoSpace = inIoSpace2 = ppmi->AddressSpace; length = ppmi->Length; // // Get a pointer to physical memory... // // - Create the name // - Initialize the data to find the object // - Open a handle to the oject and check the status // - Get a pointer to the object // - Free the handle // RtlInitUnicodeString (&physicalMemoryUnicodeString, L"\\Device\\PhysicalMemory"); InitializeObjectAttributes (&objectAttributes, &physicalMemoryUnicodeString, OBJ_CASE_INSENSITIVE, (HANDLE) NULL, (PSECURITY_DESCRIPTOR) NULL); ntStatus = ZwOpenSection (&physicalMemoryHandle, SECTION_ALL_ACCESS, &objectAttributes); if (!NT_SUCCESS(ntStatus)) { MapMemKdPrint (("MAPMEM.SYS: ZwOpenSection failed\n")); goto done; } ntStatus = ObReferenceObjectByHandle (physicalMemoryHandle, SECTION_ALL_ACCESS, (POBJECT_TYPE) NULL, KernelMode, &PhysicalMemorySection, (POBJECT_HANDLE_INFORMATION) NULL); if (!NT_SUCCESS(ntStatus)) { MapMemKdPrint (("MAPMEM.SYS: ObReferenceObjectByHandle failed\n")); goto close_handle; } // // Initialize the physical addresses that will be translated // physicalAddressEnd = RtlLargeIntegerAdd (physicalAddress, RtlConvertUlongToLargeInteger( length)); // // Translate the physical addresses. // translateBaseAddress = HalTranslateBusAddress (interfaceType, busNumber, physicalAddress, &inIoSpace, &physicalAddressBase); translateEndAddress = HalTranslateBusAddress (interfaceType, busNumber, physicalAddressEnd, &inIoSpace2, &physicalAddressEnd); if ( !(translateBaseAddress && translateEndAddress) ) { MapMemKdPrint (("MAPMEM.SYS: HalTranslatephysicalAddress failed\n")); ntStatus = STATUS_UNSUCCESSFUL; goto close_handle; } // // Calculate the length of the memory to be mapped // mappedLength = RtlLargeIntegerSubtract (physicalAddressEnd, physicalAddressBase); // // If the mappedlength is zero, somthing very weird happened in the HAL // since the Length was checked against zero. // if (mappedLength.LowPart == 0) { MapMemKdPrint (("MAPMEM.SYS: mappedLength.LowPart == 0\n")); ntStatus = STATUS_UNSUCCESSFUL; goto close_handle; } length = mappedLength.LowPart; // // If the address is in io space, just return the address, otherwise // go through the mapping mechanism // if (inIoSpace) { *((PVOID *) IoBuffer) = (PVOID) physicalAddressBase.LowPart; } else { // // initialize view base that will receive the physical mapped // address after the MapViewOfSection call. // viewBase = physicalAddressBase; // // Let ZwMapViewOfSection pick an address // virtualAddress = NULL; // // Map the section // ntStatus = ZwMapViewOfSection (physicalMemoryHandle, (HANDLE) -1, &virtualAddress, 0L, length, &viewBase, &length, ViewShare, 0, PAGE_READWRITE | PAGE_NOCACHE); if (!NT_SUCCESS(ntStatus)) { MapMemKdPrint (("MAPMEM.SYS: ZwMapViewOfSection failed\n")); goto close_handle; } // // Mapping the section above rounded the physical address down to the // nearest 64 K boundary. Now return a virtual address that sits where // we wnat by adding in the offset from the beginning of the section. // (ULONG) virtualAddress += (ULONG)physicalAddressBase.LowPart - (ULONG)viewBase.LowPart; *((PVOID *) IoBuffer) = virtualAddress; } ntStatus = STATUS_SUCCESS; close_handle: ZwClose (physicalMemoryHandle); done: return ntStatus; } 这几天驱动网总是登不了! |
|
板凳#
发布于:2001-07-13 10:41
获取部分及调用部分见附件
另外想请教到那里去看mapmem的例子 |
|
地板#
发布于:2001-07-11 16:43
看看ddk的例子mapmem吧!
|
|
地下室#
发布于:2001-07-11 13:53
将你的Ie->选项->高级->始终以utf8发送 前的勾去掉就能看附件了,因为它用的是中文名。
|
|
|
5楼#
发布于:2001-07-11 13:16
你能把取值的代码部分和调用MapInUserSpace代码贴出来吗?
|
|
6楼#
发布于:2001-07-11 12:52
第一个参数是从pnp的startdevice里取得的值
即操作系统硬件资源中分配的硬件地址 |
|
7楼#
发布于:2001-07-11 12:15
你的MapInUserSpace传递的第一个参数是什么值,是否是translated后的值,或者是从pnp的startdevice里取得的值
|
|
8楼#
发布于:2001-07-11 12:03
附件好像不行!
|
|