原创 【转帖】关于VirtualAlloc和VirtualCopy的奇怪问题

2011-9-22 10:07 1568 6 6 分类: 软件与OS

以前,对这个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 callingVirtualFree.

BOOL VirtualCopy( 
LPVOID , 
LPVOID , 
DWORD , 
DWORD  
);

Parameters

lpvDest
[in] Pointer to the destination memory, which must be reserved.
lpvSrc
[in] Pointer to committed memory.
cbSize
[in] Size, in bytes, of the region. The allocated pages include all pages containing one or more bytes in the range from lpAddress to lpAddress+cbSize. This means that a 2-byte range straddling a page boundary causes both pages to be included in the allocated region.

fdwProtect[in] Type of access protection. If the pages are being committed, any one of a number of flags can be specified, along with the PAGE_GUARD and PAGE_NOCACHE, protection modifier flags. The following table shows the flags that can be specified.
ValueDescription
PAGE_READONLYEnables 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_READWRITEEnables both read and write access to the committed region of pages.
PAGE_EXECUTEEnables 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_READEnables 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_READWRITEEnables execute, read, and write access to the committed region of pages.
PAGE_GUARDPages 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_NOACCESSDisables 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_NOCACHEAllows 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_PHYSICALUsed 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 , 
DWORD , 
DWORD , 
DWORD  
);

Parameters

lpAddress
[in] Long pointer to the specified starting address of the region to be allocated.

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.

dwSize
[in] Specifies the size, in bytes, of the region. It is an error to set this parameter to 0.

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.

flAllocationType
[in] Specifies the type of allocation.

The following table shows flags you can specify for this parameter in any combination

      关于wince的内存管理,还是很复杂的,如果开源就好了,水平太菜,学习的东西越来越多,但是感觉越来越慌张。     

转载请标明:作者wogoyixikexie@gliet.桂林电子科技大学一系科协,原文地址:http://www.cnblogs.com/wogoyixikexie/(或者我在CSDN的博客:http://blog.csdn.net/gooogleman——如有错误,希望能够留言指出;如果你有更加好的方法,也请在博客后面留言,我会感激你的批评和分享。
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
6
关闭 站长推荐上一条 /3 下一条