以前,对这个VirtualAlloc和VirtualCopy一点都不了解,只是从网上看到一些介绍,这次我发现他们在4.2BSP和5.0BSP下使用有些不同,但是4.2BSP照样在wince5.0下使用也没有问题,现在以4.2BSP和5.0BSP下下的按键驱动为例子。
先看4.2BSP的例子:
/* IO Register Allocation */
v_pIOPregs = (volatile IOPreg *)VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);
if (v_pIOPregs == NULL)
{
ERRORMSG(1,(TEXT("For IOPregs : VirtualAlloc failed!\r\n")));
RetValue = FALSE;
}
else
{
if (!VirtualCopy((PVOID)v_pIOPregs, (PVOID)(IOP_BASE), sizeof(IOPreg), PAGE_READWRITE | PAGE_NOCACHE))
{
ERRORMSG(1,(TEXT("For IOPregs: VirtualCopy failed!\r\n")));
RetValue = FALSE;
}
}
在VirtualCopy的IOP_BASE是个虚拟地址
#define IOP_BASE 0xB1600000 // 0x56000000
但是在5.0BSP却不一样,非常让人震惊。
v_pIOPregs = (volatile S3C2440A_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2440A_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
VirtualCopy((PVOID)v_pIOPregs, (PVOID)(S3C2440A_BASE_REG_PA_IOPORT >> 8), sizeof(S3C2440A_IOPORT_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE );
S3C2440A_BASE_REG_PA_IOPORT 是个物理地址#define S3C2440A_BASE_REG_PA_IOPORT (0x56000000)
这个本来和4.2的虚拟地址就很大不同了,但是还要弄成 S3C2440A_BASE_REG_PA_IOPORT >> 8,右移八位,真是不可思议。
不过这个VirtualCopy的最后一个参数不同,在5.0BSP中多了一个PAGE_PHYSICAL,哦这个估计是关键因素。这里使用物理地址了,但是为什么还要右移八位,要知道答案就看PB的帮助了。
This function dynamically maps a virtual address to a physical address by creating a new page-table entry. Terminate the mapping by calling VirtualFree.
BOOL VirtualCopy( LPVOID lpvDest, LPVOID lpvSrc, DWORD cbSize, DWORD fdwProtect );
Value | Description |
---|---|
PAGE_READONLY | Enables read access to the committed region of pages. An attempt to write to the committed region results in an access violation. If the system differentiates between read-only access and execute access, an attempt to execute code in the committed region results in an access violation. |
PAGE_READWRITE | Enables both read and write access to the committed region of pages. |
PAGE_EXECUTE | Enables execution access to the committed region of pages. An attempt to read or write to the committed region results in an access violation. |
PAGE_EXECUTE_READ | Enables execute and read access to the committed region of pages. An attempt to write to the committed region results in an access violation. |
PAGE_EXECUTE_READWRITE | Enables execute, read, and write access to the committed region of pages. |
PAGE_GUARD | Pages in the region become guard pages. Any attempt to read from or write to a guard page causes the operating system to raise the STATUS_GUARD_PAGE exception and turn off the guard page status. Guard pages thus act as a one-shot access alarm. The PAGE_GUARD flag is a page protection modifier. An application uses it with one of the other page protection flags, with one exception: it cannot be used with PAGE_NOACCESS. When an access attempt leads the operating system to turn off guard page status, the underlying page protection takes over. If a guard page exception occurs during a system service, the service typically returns a failure status indicator. |
PAGE_NOACCESS | Disables all access to the committed region of pages. An attempt to read from, write to, or execute in the committed region results in an access violation exception, called a general protection (GP) fault. |
PAGE_NOCACHE | Allows no caching of the committed regions of pages. The hardware attributes for the physical memory should be specified as no cache. It is useful for device drivers; when, for example, mapping a video frame buffer with no caching. This flag is a page protection modifier and is valid only when used with one of the page protections other than PAGE_NOACCESS. |
PAGE_PHYSICAL | Used to map a physical memory region. When using this flag, divide the physical address — that is, lpvSrc — by 256. Memory mapped with PAGE_PHYSICAL is not freed until the device is rebooted. Calling VirtualFree will not free this mapped physical memory. PAGE_PHYSICAL is intended for use with dedicated hardware buffers, so it cannot be freed after being mapped. |
PAGE_PHYSICAL这个参数决定了要右移八位(除以256),哈哈,这样就达到了异曲同工之妙。不过还有一点就是使用了PAGE_PHYSICAL之后就不要使用VirtualFree 了因为,使用了也无济于事。
现在来看看这个VirtualAlloc 吧。
This function reserves or commits a region of pages in the virtual address space of the calling process.
Memory allocated by VirtualAlloc is initialized to zero.
LPVOID VirtualAlloc( LPVOID lpAddress, DWORD dwSize, DWORD flAllocationType, DWORD flProtect );
If the memory is being reserved, the specified address is rounded down to the next 64-KB boundary.
If the memory is reserved and is being committed, the address is rounded down to the next page boundary.
To determine the size of a page on the host computer, use the GetSystemInfo function.
If this parameter is NULL, the system determines where to allocate the region.
If the lpAddress parameter is NULL, this value is rounded up to the next page boundary.
Otherwise, the allocated pages include all pages containing one or more bytes in the range from lpAddress to lpAddress+dwSize. This means that a 2-byte range straddling a page boundary causes both pages to be included in the allocated region.
The following table shows flags you can specify for this parameter in any combination
关于wince的内存管理,还是很复杂的,如果开源就好了,水平太菜,学习的东西越来越多,但是感觉越来越慌张。