关于VirtualAlloc和VirtualCopy

xiaoyake1   2008-9-18 18:06 楼主
请问
VirtualCopy
这个函数是把寄存器的物理地址映射到VirtualAlloc申请的虚拟地址空间中?
还是已经在OEMaddressTable中把物理地址映射为虚拟地址1
再通过VirtualCopy把虚拟地址1映射到VirtualAlloc申请的虚拟地址
比较饶口
不知道我表达清楚没

回复评论 (11)

如果是后者(在OEMaddressTable中把物理地址映射为虚拟地址1
再通过VirtualCopy把虚拟地址1映射到VirtualAlloc申请的虚拟地址中 )
那么为什么这么做呢?为什么不直接把物理地址映射到VirtualAlloc申请的虚拟地址中???
点赞  2008-9-18 18:07
弄清楚这个问题首先要了解VirtualCopy和VirtualAlloc这2个函数的实现和目的,以及wince下动态虚拟内存映射和静态虚拟内存映射
先说VirtualAlloc 和VirtualCopy
VirtualAlloc 首先会从我们的虚拟地址空间中申请(或者说预留)一块虚拟空间,准备接下来要用它。注意此时,可用的物理内存并没有减少,只是虚拟地址少了一块可用的区域。
真正把这块之前reserved的虚拟空间映射到物理的内存区域就是由VirtualCopy来干的,此时,MMU的页表就会增加一个entry,来表示物理--虚拟的映射关系。


再说动态虚拟内存映射和静态虚拟内存映射
OEMaddressTable只是建立了一个一级的静态虚拟--物理的映射关系,一般给kernel(NK.EXE)通过直接访问的形式来用(OALPAtoVA);
MmMapIOSpace(VirtualAlloc +VirtualCopy)是一种动态虚拟映射的手段,一般给驱动根据当前需要(对硬件操作)动态申请并建立映射。

点赞  2008-9-18 19:02
学习
点赞  2008-9-18 20:44
那就是说VirtualCopy 可以直接把物理内存映射到虚拟内存中
而OEMaddressTable所建立的静态虚拟--物理的映射不是必须

也就是说比如对寄存器的映射
可以通过VirtualAlloc申请(预留)一块虚拟内存给寄存器(如:v_pIOPregs)
然后用
VirtualCopy直接把寄存器的物理地址映射到刚才申请(预留)的虚拟地址空间

而在OEMaddressTable中所做的寄存器物理地址与虚拟地址的映射这步可以省略
点赞  2008-9-18 20:57
OEMaddressTable定义处在哪??
点赞  2008-9-18 21:33
引用: 引用 4 楼 wangxin_801115 的回复:
那就是说VirtualCopy 可以直接把物理内存映射到虚拟内存中
而OEMaddressTable所建立的静态虚拟--物理的映射不是必须的

也就是说比如对寄存器的映射:
可以通过VirtualAlloc申请(预留)一块虚拟内存给寄存器(如:v_pIOPregs)
然后用
VirtualCopy直接把寄存器的物理地址映射到刚才申请(预留)的虚拟地址空间

而在OEMaddressTable中所做的寄存器物理地址与虚拟地址的映射这步可以省略

不是省略不省略的问题,是这两种方法是在不同的场合下使用的,如2楼说的,内核部分就要用这个OEMaddressTable来转换,wince5.0下 用户态的驱动(wince6.0驱动貌似是在内核态)就要用这个VirtualAlloc+VirtualCopy来进行地址映射。

OEMaddressTable的定义,你可以查看 bsp\src\inc\oemaddrtab_cfg.inc ,那个g_oalAddressTable便是。
点赞  2008-9-19 09:08
引用: 引用 2 楼 songtitan 的回复:
弄清楚这个问题首先要了解VirtualCopy和VirtualAlloc这2个函数的实现和目的,以及wince下动态虚拟内存映射和静态虚拟内存映射。
先说VirtualAlloc 和VirtualCopy
VirtualAlloc 首先会从我们的虚拟地址空间中申请(或者说预留)一块虚拟空间,准备接下来要用它。注意此时,可用的物理内存并没有减少,只是虚拟地址少了一块可用的区域。
真正把这块之前reserved的虚拟空间映射到物理的内存区域就是由VirtualCopy来干的,此时,…


-------------每次你回答问题都很深入,真是佩服
点赞  2008-9-19 10:08
引用: 引用 6 楼 yy080808 的回复:
引用 4 楼 wangxin_801115 的回复:
那就是说VirtualCopy 可以直接把物理内存映射到虚拟内存中
而OEMaddressTable所建立的静态虚拟--物理的映射不是必须的

也就是说比如对寄存器的映射:
可以通过VirtualAlloc申请(预留)一块虚拟内存给寄存器(如:v_pIOPregs)
然后用
VirtualCopy直接把寄存器的物理地址映射到刚才申请(预留)的虚拟地址空间

而在OEMaddressTable中所做的寄存器物理地址与虚拟地址的映射这步…

再举一个极端的例子,如果OEMaddressTable不映射,驱动还是可以通过MmMapIOSpace来映射操作那块寄存器。
这个方法就是让wince可以突破512M内存这个限制的原因啦。
点赞  2008-9-19 10:43
哦thank u !
我理解错误了
我以为寄存器的物理地址映射到虚拟地址空间需要做两个部分操作
1、在OEMaddressTable做物理----虚拟映射,映射为虚拟地址1
2、再把第一步的虚拟地址通过VirtualCopy映射到VirtualAlloc申请的虚拟空间2
   也就是虚拟地址1-----虚拟地址2

现在看来这两个部分是独立的,各不干扰
即可以通过OEMaddressTable做物理----虚拟映射,供kernel来访问
也可以用VirtualAlloc+VirtualCopy来直接给寄存器的物理地址映射虚拟空间,只需要在VirtualCopy的参数中指定PAGE_PHYSICAL
点赞  2008-9-19 13:35
是不是WinCE下面使用这两个函数就可以直接访问物理内存,而不需要专门编写驱动程序?
谢谢
点赞  2008-9-29 21:32
佩服,学习了
点赞  2010-1-12 09:59
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复