yeammy
驱动牛犊
驱动牛犊
  • 注册日期2002-12-27
  • 最后登录2012-02-22
  • 粉丝0
  • 关注0
  • 积分63分
  • 威望12点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
阅读:1485回复:4

由物理地址如何得到线性地址???!!!

楼主#
更多 发布于:2003-01-15 13:53
各位大侠:
    俺们常见的地址转换问题已知虚地址查找物理地址,这是通过线性地址和页面表转换机制得到的,俺的问题是:
    1)由虚地址得到物理地址,在编程时用什么函数得到???
    2)如果读基地址寄存器的值(比如plx9030),它返回的是物理地址,那么俺们由物理地址查找其对应的线性地址用什么机制?是否还是通过页面表?在编程时,通过那些函数实现???
    谢谢!

最新喜欢:

flyfoxflyfox
shusanyi
驱动牛犊
驱动牛犊
  • 注册日期2002-04-17
  • 最后登录2003-09-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于: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
bushwhack
驱动牛犊
驱动牛犊
  • 注册日期2002-11-15
  • 最后登录2003-12-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-01-15 16:54
取得物理地址physical_addr的页地址page_addr
(page_addr = physical_addr&0xfffff000)
遍历所有进程
遍历相应进程的页表
对存储的值value进行转换
cur_value = value&0xfffff000
如果cur_value == page_addr
则此进程使用此物理地址  
在此进程中其相应的线性地址接下来很容易找到

当然这些你必须在ring0下实现
wwwwwww
驱动牛犊
驱动牛犊
  • 注册日期2003-01-09
  • 最后登录2003-06-17
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-01-15 20:28
.......对存储的值value进行转换
cur_value = value&0xfffff000
如果cur_value == page_addr
则此进程使用此物理地址.......


请问老兄你这里的value是个什么东东是页表和页目录项里的物理地址吗?
bushwhack
驱动牛犊
驱动牛犊
  • 注册日期2002-11-15
  • 最后登录2003-12-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-01-16 09:04
是的

二楼那位老兄的函数是将物理地址映射到线性地址空间中
而不是得到正在使用的物理地址所映射的线性地址
游客

返回顶部