关于wince的内存问题一直有些混乱,最近看了网上几篇文章,在这里总结梳理一下。
内存第一次映射关系,是定义在OEMAddressTable里,这里通过ARM的MMU实现了物理地址到虚拟地址的映射,因此只要MMU开启,这个映射关系就会一直存在。对于wince而言,只能访问到这里的virtual address。
在这里插个问题就是为什么要地址映射?wince只能管理512M的物理内存,但是拥有4G的虚拟地址空间,使用虚拟内存后每个进程都拥有自己的进程空间,提高了系统的可靠性和安全性。
完成地址映射,512M的物理地址映射到0x80000000-0x9fffffff之间,需要注意的是这是cache and buffer的地址,一般的OEMAddressTable定义的也是caching address,同时512M的物理地址也会映射到uncaching address 0xA0000000-0xBFFFFFFF之间,即uncaching address=caching address + 0x20000000。
Wince内核地址空间为0x80000000-0xffffffff,可见物理地址就是映射到这个区间,因此对于内核而言通过静态的映射可以直接访问物理地址。
应用程序的地址空间为0x00000000-0x7fffffff,物理地址并没有映射到这个区间,因此应用程序要访问物理地址就需要再一次的映射,动态地建立一层映射关系,这就是函数virtualAlloc/Copy和MmMapIoSpace的功能,个人比较多用MmMapIoSpace,直接对应物理地址,关于这两个函数可以查看MSDN。
解决了物理地址和虚地址映射的问题后,在编写驱动程序时经常会用到MapPtrToProcess这个函数,该函数的作用就是将某个pointer转化到实际的slot中去,每个进程占一个slot,该函数就是实现了各个进程之间的pointer映射。在wince6.0中该函数将不再被支持。