• 了解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 
  • 相关阅读:
    CS229 6.4 Neurons Networks Autoencoders and Sparsity
    CS229 6.3 Neurons Networks Gradient Checking
    【Leetcode】【Easy】Min Stack
    【Leetcode】【Easy】Merge Sorted Array
    【Leetcode】【Easy】ZigZag Conversion
    【Leetcode】【Easy】Valid Palindrome
    【Leetcode】【Easy】Reverse Integer
    【Leetcode】【Easy】Palindrome Number
    【Leetcode】【Easy】Length of Last Word
    【Leetcode】【Easy】Remove Nth Node From End of List
  • 原文地址:https://www.cnblogs.com/gooogleman/p/1869626.html
Copyright © 2020-2023  润新知