zoukankan      html  css  js  c++  java
  • 了解MmMapIoSpace以及MmUnmapIoSpace函数的实现原理以及实现方法

    了解MmMapIoSpace以及MmUnmapIoSpace函数的实现原理以及实现方法


      1 源码路径
      2 H:\WINCE600\PUBLIC\COMMON\OAK\DRIVERS\CEDDK\DDK_MAP
      3 目的,了解MmMapIoSpace以及MmUnmapIoSpace函数的实现原理以及实现方法
      4 分析之前,要看看一个很关键的东西——PHYSICAL_ADDRESS,这个参数很重要,是地址的组织形式。
      5  // in ceddk.h
      6 typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS;
      7 // in winnt.h
      8 typedef struct _LARGE_INTEGER {
      9 #else // MIDL_PASS
     10 typedef union _LARGE_INTEGER {
     11     struct {
     12         DWORD LowPart;
     13         LONG HighPart;
     14     };
     15     struct {
     16         DWORD LowPart;
     17         LONG HighPart;
     18     } u;
     19 #endif //MIDL_PASS
     20     LONGLONG QuadPart;
     21 } LARGE_INTEGER;
     22 在MSDN中有这样的解释:
     23 LARGE_INTEGER Union
     24 
     25 The LARGE_INTEGER structure is used to represent a 64-bit signed integer value.
     26 
     27 Note  Your C compiler may support 64-bit integers natively. For example, Microsoft Visual C++ supports the __int64 sized integer type. For 
     28 
     29 more information, see the documentation included with your C compiler.
     30 
     31 Members
     32 LowPart 
     33 Low-order 32 bits.
     34 
     35 HighPart 
     36 High-order 32 bits.
     37 
     38 
     39 LowPart 
     40 Low-order 32 bits.
     41 
     42 HighPart 
     43 High-order 32 bits.
     44 
     45 QuadPart 
     46 Signed 64-bit integer.
     47 
     48 Remarks
     49 The LARGE_INTEGER structure is actually a union. If your compiler has built-in support for 64-bit integers, use the QuadPart member to store 
     50 
     51 the 64-bit integer. Otherwise, use the LowPart and HighPart members to store the 64-bit integer.
     52 
     53 
     54 OK,现在就来看看MmMapIoSpace吧。
     55 首先看它的一个成功使用例子:
     56 
     57 void CDlgDemoDlg::OnButton1()   
     58 {   
     59 // TODO: Add your control notification handler code here   
     60 //unsigned char *gpio_base;   
     61 unsigned int *gpio_base;   
     62 OutputDebugString(L"TestDrv - LedDrive1\n");   
     63 //PUCHAR ioPortBase;   
     64 PHYSICAL_ADDRESS PortAddress = {0x560000600}; //  LowPart=0x56000060;HighPart=0;
     65 gpio_base =(unsigned int *)MmMapIoSpace( PortAddress, 0x04,FALSE ); // 获得内存,4字节大小。   
     66 *gpio_base = 0x0585ff87// 直接访问硬件   
     67 MmUnmapIoSpace(gpio_base,0x04);//释放内存   
     68 }  
     69 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/gooogleman/archive/2009/05/16/4189536.aspx
     70 
     71 再看MmMapIoSpace实现过程H:\WINCE600\PUBLIC\COMMON\OAK\DRIVERS\CEDDK\DDK_MAP
     72 
     73 /*++
     74 Routine Description:
     75   map the given physical address range to nonpaged system space
     76 
     77 Arguments:
     78   PhysicalAddress - starting physical address of the I/O range to be mapped
     79   NumberOfBytes - number of bytes to be mapped
     80   CacheEnable - TRUE if the physical address range can be mapped as cached
     81                 memory
     82 
     83 Return Value:
     84   base virtual address that maps the base physical address for the range, or
     85   NULL if space for mapping the range is insufficient
     86 --*/
     87 PVOID
     88 MmMapIoSpace (
     89     IN PHYSICAL_ADDRESS PhysicalAddress,
     90     IN ULONG NumberOfBytes,
     91     IN BOOLEAN CacheEnable
     92     )
     93 {
     94     PVOID   pVirtualAddress;
     95     ULONGLONG   SourcePhys;
     96     ULONG   SourceSize;
     97     BOOL    bSuccess;
     98 
     99     //
    100     // Page align source and adjust size to compensate
    101     //
    102 
    103     SourcePhys = PhysicalAddress.QuadPart & ~(PAGE_SIZE - 1);// for page align
    104     SourceSize = NumberOfBytes + (PhysicalAddress.LowPart & (PAGE_SIZE - 1));
    105 
    106     if (SourceSize < NumberOfBytes) { // Prevent Integer overflow.
    107         SetLastError(ERROR_INVALID_PARAMETER);
    108         return NULL;
    109     }
    110     
    111 
    112     pVirtualAddress = VirtualAlloc(0, SourceSize, MEM_RESERVE, PAGE_NOACCESS);
    113 
    114     if (pVirtualAddress != NULL)
    115     {
    116         bSuccess = VirtualCopy(
    117             pVirtualAddress, (PVOID)(SourcePhys >> 8), SourceSize,
    118             PAGE_PHYSICAL | PAGE_READWRITE | (CacheEnable ? 0 : PAGE_NOCACHE));
    119 
    120         if (bSuccess)
    121         {
    122             (ULONG)pVirtualAddress += PhysicalAddress.LowPart & (PAGE_SIZE - 1);//保证虚拟地址是页对齐
    123         }
    124         else
    125         {
    126             VirtualFree(pVirtualAddress, 0, MEM_RELEASE);//释放内存。
    127             pVirtualAddress = NULL;
    128         }
    129     }
    130 
    131     return pVirtualAddress;//返回虚拟内存地址。
    132 }
    133 
    134 =================================================================================
    135   从这个看来MmMapIoSpace也是使用了驱动中常用的VirtualAlloc、VirtualCopy、VirtualFree来实现的,只不过是加入了页对齐,使用起来较安全。
    136   再看看MmUnmapIoSpace
    137 
    138 /*++
    139 Routine Description:
    140   unmap a specified range of physical addresses previously mapped by
    141   MmMapIoSpace
    142 
    143 Arguments:
    144   BaseAddress - pointer to the base virtual address to which the physical
    145                 pages were mapped
    146   NumberOfBytes - number of bytes that were mapped
    147 
    148 Return Value:
    149   None
    150 --*/
    151 VOID
    152 MmUnmapIoSpace (
    153     IN PVOID BaseAddress,
    154     IN ULONG NumberOfBytes
    155     )
    156 {
    157     VirtualFree((PVOID)((ULONG)BaseAddress & ~(ULONG)(PAGE_SIZE - 1)), 0, MEM_RELEASE);
    158 }
    159 //嘿嘿,还是使用驱动的常用方法VirtualFree来释放虚拟内存,只是安全系数高一些。
    160 类似参考文章:http://hi.chinaunix.net/?uid-21747227-action-viewspace-itemid-39331
    161 
  • 相关阅读:
    WM平台玩转Android全攻略
    WP7实时监控内存转
    Silverlight内存释放的方法
    .net中同步多个ScrollViewer滚动的四种方法
    windows phone7,zune:can't connect to your phone WP7手机无法连接Zune 的解决方法
    64位虚拟机Guest OS安装错误:0xC0000225
    Tip: Resharper 中 "Unknown Comment" 问题的解决办法
    工具: 删除Visual Studio项目中文件链接,并把原文件复制到相应的目录
    一个代表年月的类YearMonth
    在64bit Win2008上运行Asp + Access网站
  • 原文地址:https://www.cnblogs.com/gooogleman/p/1869626.html
Copyright © 2011-2022 走看看