Windows Mobile 5的虚拟内存模型如下图:
我们会看见这样的概念:kernel space 和 user space。看似简单,你真的理解么?分析这样的memory space概念的时候一定分清视角,通俗说就是你是以user进程的角度,还是以微软操作系统内核的角度看这个空间。这点非常重要。不信你试试看。
0x8000,0000到0xFFFF,FFFF这个叫内核空间,也就是只有内核代码可以用这样的地址,他们是高特权级的区域。你的应用程序是访问不到的。如果你要“硬”来,操作系统一定会把你destroy掉,并给你一个类似非法访问的警告提示。除非你是“黑客”,用类似“缓冲溢出”等攻击方法来访问。
那么对于0x8000,0000以下的空间,叫做用户空间。什么?你做就知道了?!哈哈!那我问你,用户空间是不是只有用户程序可以访问的空间?你要是回答是,那就错了。用户空间是用户程序可以访问的空间,但不是“只有”。内核是老大,他当然也可以访问。所以你看,我们定义user space的概念一般只是针对user来说,而定义kernel space只是针对kernel来说,如果你只是单单把user space和kernel space放在一起,实际上没什么可比性。
小总结一下,kernel可以访问整个4GB空间,而user“最多”只能直接访问下2GB空间。我这里又多强调了一个“最多”。下面将详细讲解。
“最多”也就是说用户程序不能整个空间都是他的,一个多任务分时操作系统上同时有很多的用户的程序在“奔跑”,而且彼此独立,互不打扰。内存空间这样宝贵的资源,内核不可能让某个进程独占,因此,Windows Mobile5将下2GB空间均匀划分成64块,每一块32MB,并且slot0~slot32用于用户程序,slot32-slot63用于shared memory,所以WM5最多能有32个进程同时在运行。我们可以看见,每个单独的process是有可怜的32MB的大小。这个数值才是我们真正该关心的东西。每个进程的内存是不允许其他空间随便访问的。可怜可怜,你只有有32MB可以“使用”。“使用”这个概念再落实一下,就是如你调用VirtualAlloc()这样的内存分配函数。
我这篇文章叫“危机”,不是光介绍一下这些概念。想想,像device.exe这样的“进程大户”,身上挂装了n多的DLL,而且每个驱动程序都要类似调用VirtualAlloc的函数来映射寄存器空间,也就是CPU的整个寄存器空间几乎都要映射到这个狭小的32MB空间里,自己本身还有很多的代码与数据要占用空间,这个进程真是很吃力呀。随着SOC(system on chip)的茁壮成长,一个chip里集成的module数量越来越多,随之而来的寄存器的增多,也就是寄存器组空间的增大,Windows Mobile5将不再可以使用。
幸好2007年我们迎来了Windows CE 6,虚拟空间的问题得以解决。可是微软相继发布的CrossBow主要是UI的变化,内核依然采用windows CE 5。不知什么时候微软会发布使用CE6内核的Windows Mobile。
我们现在还要继续使用Windows CE5 kernel,那就要想办法解决这个问题。
前面提到slot32-slot63用于shared memory,如果能使用这块空间,那么虚拟内存不足的问题就可以解决。微软告诉我们mapped file是使用这块空间的,所以解决方案自然是
h_map=CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, Size, NULL);
VirBase=MapViewOfFile(h_map, FILE_MAP_WRITE, 0, 0, 0);
这样分配下来的虚拟地址会在0x4200,0000-0x7E00,0000区域内。此时只有虚拟空间被分配,实际的物理内存还并没有映射。因此这个时候你不能类似这样:
*(volatile DWORD *)VirBase=123;
写内存,这个动作会分配实际的物理内存,从而直接导致下面的VirtualCopy的失败。
这样虚拟空间有了,实际的物理内存可以这样映射
VirtualCopy((void*)VirBase, (void *)(PhyBase >> 8), fbSize, PAGE_READWRITE | PAGE_NOCACHE | PAGE_PHYSICAL)
这个三个函数的结合使用,使我们可以充分利用user memory 的空间。
1 条评论:
这么说我们可以使用更多的虚拟内存了?无限量?取决于SD卡?
发表评论