zoukankan      html  css  js  c++  java
  • 关于VirtualAlloc和VirtualCopy的奇怪问题(作者:wogoyixikexie@gliet)

    关于VirtualAlloc和VirtualCopy的奇怪问题(作者:wogoyixikexie@gliet)

         以前,对这个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 );

    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_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 ); 

    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的内存管理,还是很复杂的,如果开源就好了,水平太菜,学习的东西越来越多,但是感觉越来越慌张。     

  • 相关阅读:
    UltraEdit程序设置添加到右键菜单
    UltraEdit加入到右键菜单中
    vim常用命令
    Linux vi命令大全
    vi/vim 计算搜寻关键字数量
    vi 删除全部内容
    vi中全选的命令或者快捷方式
    VI打开和编辑多个文件的命令
    vi/vim 查找替换使用方法
    VMware workstation 与 VMware GSX Server 的区别
  • 原文地址:https://www.cnblogs.com/gooogleman/p/1869731.html
Copyright © 2011-2022 走看看