您的位置:首页 > 移动开发 > IOS开发

VirtualAlloc,VirtualCopy和MmMapIoSpace

2011-08-22 17:34 459 查看


VirtualAlloc,VirtualCopy和MmMapIoSpace


在WinCE的驱动程序里经常要去访问硬件设备,对硬件设备寄存器进行操作,如CPU的IOPORT,中断寄存器等,这就要使用VirtualAlloc,VirtualCopyMmMapIoSpace进行地址的分配及映射.

如SMDK2410 BSP中的SDHC驱动中Sdiocontrollerbase.cpp:

view plain

//----- 1. Map the GPIO registers needed to enable the SDI controller -----  

vm_pIOPreg = (S3C2410X_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2410X_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);  

if (vm_pIOPreg == NULL)   

{  

    DEBUGMSG (1,(TEXT("GPIO registers not allocated")));  

    status = SD_API_STATUS_INSUFFICIENT_RESOURCES;  

    goto INIT_ERROR;  

}  

if (!VirtualCopy((PVOID)vm_pIOPreg, (PVOID)(S3C2410X_BASE_REG_PA_IOPORT >> 8), sizeof(S3C2410X_IOPORT_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)) {  

    DEBUGMSG (1,(TEXT("GPIO registers not mapped")));  

    status = SD_API_STATUS_INSUFFICIENT_RESOURCES;  

    goto INIT_ERROR;  

又如串口驱动Ser_smdk2410.cpp:

view plain

if (TranslateBusAddr(m_hParent,Internal,0, ioPhysicalBase,&inIoSpace,&ioPhysicalBase)) {  

    // Map it if it is Memeory Mapped IO.  

    m_pIOPregs = (S3C2410X_IOPORT_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C2410X_IOPORT_REG),FALSE);  

}  

首先来看看VirtualAlloc的原型:
LPVOID VirtualAlloc(

  LPVOID
 lpAddress

  DWORD
 dwSize

  DWORD
 flAllocationType

  DWORD
 flProtect 
); 

VirtualAlloc 是在虚拟地址空间中申请一段dwSize大小的虚拟地址.

lpAddress为指定虚拟地址的起始地址,为0则由系统来自动分配地址.

flAllocationType有两个选项MEM_COMMIT和MEM_RESERVE,MEM_RESERVE为系统保留,不会被其他内存分配函数占用.使用MEM_COMMIT参数可以将上次使用MEM_RESERVE保留的地址空间进行实际的分配.如第一次调用使用MEM_RESERVE,第二次调用使用MEM_COMMIT.在驱动程序中我们只用MEM_RESERVE保留,然后使用VirtualCopy将物理地址映射到该虚拟地址上.

VirtualCopy的原型
BOOL VirtualCopy( 

  LPVOID 
lpvDest

  LPVOID 
lpvSrc

  DWORD 
cbSize

  DWORD 
fdwProtect 
);
VirtualCopy将分配的虚拟地址空间与物理地址进行了映射.

LPVOID lpvSrc 可以是虚拟地址也可以是物理地址.
fdwProtect程序用了PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE的组合.PAGE_PHYSICAL 表明是用来映射物理内存区域,这样lpvSrc为物理地址,需要右移8位.(这是由于VirtualCopy的实现决定的)

MmMapIoSpace实际上就是调用了VirtualAlloc,VirtualCopy,并做了一些地址检验,源代码位于/PUBLIC/COMMON/OAK/DRIVERS/CEDDK/DDK_MAP/ddk_map.c

原型为:
PVOID MmMapIoSpace( 

  PHYSICAL_ADDRESS 
PhysicalAddress

  ULONG
 NumberOfBytes

  BOOLEAN 
CacheEnable 
);
同样还有个MmUnmapIoSpace进行内存的释放.

更多详细内容可参考MSDN.

在CE驱动程序中基本就是通过上述两种方法进行物理地址到虚拟地址的内存分配(VirtualAlloc+VirtualCopy或者MmMapIoSpace)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  wince api c null