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

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  =  { 0x56000060 0 };  //   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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值