阅读:1485回复:4
由物理地址如何得到线性地址???!!!
各位大侠:
俺们常见的地址转换问题已知虚地址查找物理地址,这是通过线性地址和页面表转换机制得到的,俺的问题是: 1)由虚地址得到物理地址,在编程时用什么函数得到??? 2)如果读基地址寄存器的值(比如plx9030),它返回的是物理地址,那么俺们由物理地址查找其对应的线性地址用什么机制?是否还是通过页面表?在编程时,通过那些函数实现??? 谢谢! |
|
最新喜欢:![]() |
沙发#
发布于:2003-01-15 16:38
用MapPhysicalToLin 在VXD下,wdm得用以下:
NTSTATUS MapPhysicalMemoryToLinearSpace(PVOID pPhysAddress, ULONG PhysMemSizeInBytes, PVOID *ppPhysMemLin, HANDLE *pPhysicalMemoryHandle) { UNICODE_STRING PhysicalMemoryUnicodeString; PVOID PhysicalMemorySection = NULL; OBJECT_ATTRIBUTES ObjectAttributes; PHYSICAL_ADDRESS ViewBase; NTSTATUS ntStatus; PHYSICAL_ADDRESS pStartPhysAddress; PHYSICAL_ADDRESS pEndPhysAddress; PHYSICAL_ADDRESS MappingLength; BOOLEAN Result1, Result2; ULONG IsIOSpace; unsigned char *pbPhysMemLin = NULL; OutputDebugString (\"Entering MapPhysicalMemoryToLinearSpace\"); RtlInitUnicodeString (&PhysicalMemoryUnicodeString, L\"\\\\Device\\\\PhysicalMemory\"); InitializeObjectAttributes (&ObjectAttributes, &PhysicalMemoryUnicodeString, OBJ_CASE_INSENSITIVE, (HANDLE) NULL, (PSECURITY_DESCRIPTOR) NULL); *pPhysicalMemoryHandle = NULL; ntStatus = ZwOpenSection (pPhysicalMemoryHandle, SECTION_ALL_ACCESS, &ObjectAttributes); if (NT_SUCCESS(ntStatus)) { ntStatus = ObReferenceObjectByHandle (*pPhysicalMemoryHandle, SECTION_ALL_ACCESS, (POBJECT_TYPE) NULL, KernelMode, &PhysicalMemorySection, (POBJECT_HANDLE_INFORMATION) NULL); if (NT_SUCCESS(ntStatus)) { pStartPhysAddress.QuadPart = (ULONGLONG)pPhysAddress; pEndPhysAddress = RtlLargeIntegerAdd (pStartPhysAddress, RtlConvertUlongToLargeInteger(PhysMemSizeInBytes)); IsIOSpace = 0; Result1 = HalTranslateBusAddress (1, 0, pStartPhysAddress, &IsIOSpace, &pStartPhysAddress); IsIOSpace = 0; Result2 = HalTranslateBusAddress (1, 0, pEndPhysAddress, &IsIOSpace, &pEndPhysAddress); if (Result1 && Result2) { MappingLength = RtlLargeIntegerSubtract (pEndPhysAddress, pStartPhysAddress); if (MappingLength.LowPart) { // Let ZwMapViewOfSection pick a linear address PhysMemSizeInBytes = MappingLength.LowPart; ViewBase = pStartPhysAddress; ntStatus = ZwMapViewOfSection (*pPhysicalMemoryHandle, (HANDLE) -1, &pbPhysMemLin, 0L, PhysMemSizeInBytes, &ViewBase, &PhysMemSizeInBytes, ViewShare, 0, PAGE_READWRITE | PAGE_NOCACHE); if (!NT_SUCCESS(ntStatus)) OutputDebugString (\"ERROR: ZwMapViewOfSection failed\"); else { pbPhysMemLin += (ULONG)pStartPhysAddress.LowPart - (ULONG)ViewBase.LowPart; *ppPhysMemLin = pbPhysMemLin; } } else OutputDebugString (\"ERROR: RtlLargeIntegerSubtract failed\"); } else OutputDebugString (\"ERROR: MappingLength = 0\"); } else OutputDebugString (\"ERROR: ObReferenceObjectByHandle failed\"); } else OutputDebugString (\"ERROR: ZwOpenSection failed\"); if (!NT_SUCCESS(ntStatus)) ZwClose(*pPhysicalMemoryHandle); OutputDebugString (\"Leaving MapPhysicalMemoryToLinearSpace\"); return ntStatus; } NTSTATUS UnmapPhysicalMemory(HANDLE PhysicalMemoryHandle, PVOID pPhysMemLin) { NTSTATUS ntStatus; OutputDebugString (\"Entering UnmapPhysicalMemory\"); ntStatus = ZwUnmapViewOfSection((HANDLE)-1, pPhysMemLin); if (!NT_SUCCESS(ntStatus)) OutputDebugString (\"ERROR: UnmapViewOfSection failed\"); ZwClose(PhysicalMemoryHandle); OutputDebugString (\"Leaving UnmapPhysicalMemory\"); return ntStatus; } :D :) :P |
|
板凳#
发布于:2003-01-15 16:54
取得物理地址physical_addr的页地址page_addr
(page_addr = physical_addr&0xfffff000) 遍历所有进程 遍历相应进程的页表 对存储的值value进行转换 cur_value = value&0xfffff000 如果cur_value == page_addr 则此进程使用此物理地址 在此进程中其相应的线性地址接下来很容易找到 当然这些你必须在ring0下实现 |
|
地板#
发布于:2003-01-15 20:28
.......对存储的值value进行转换
cur_value = value&0xfffff000 如果cur_value == page_addr 则此进程使用此物理地址....... 请问老兄你这里的value是个什么东东是页表和页目录项里的物理地址吗? |
|
地下室#
发布于:2003-01-16 09:04
是的
二楼那位老兄的函数是将物理地址映射到线性地址空间中 而不是得到正在使用的物理地址所映射的线性地址 |
|