非XIP DLL在加载时CE内核会在调用DLL的进程的地址空间中申请足够大的地址空间,并且执行代码时按需提交物理内存。
RAM和ROM文件系统是Windows CE默认的文件系统。RAM文件系统的优点是支持文件压缩、支持事务机制(和数据库中的事务机制相似)、数据I/O较快。Windows CE.NET启动时把除了NK以外的RAM分为对象存储(object store)区域和应用程序内存(program memory)区域,并且默认各使用一半RAM。在基于Windows CE的设备没有采用永久存储器之前,对象存储的作用相当于永久存储器,对象存储区域采用RAM文件系统来保存文件,对象存储中可以存储的对象类型有文件、目录、数据库、记录、数据库卷。默认在对象存储中存储的对象全部是压缩的。当整个系统关闭时,设备的电源还继续提供电力给RAM,这样对象存储中保存的所有数据就不会丢失。应用程序内存区域留给所有应用程序运行时使用。基于Windows CE的设备采用永久存储器后,对象存储的作用就被永久存储器替代了,所以采用永久存储器后,应该减小对象存储区域的大小。如果定制的Windows CE的内核包含了资源管理器(eXPlorer.exe),那么打开“控制面板”,在“系统”-“内存”中,可以调节这两个存储区域的比例。滑块向左,则释放对象存储区域的一些可用内存并将这些内存划到应用程序内存区域中。滑块向右则相反。
2、内存结构
Windows CE.NET只能管理512MB的物理内存和4GB大小的虚拟地址空间。不同的CPU内存管理方法也不同。对于MIPS和SHX系列CPU来说,物理地址映射是由CPU完成的,CE内核可以直接访问512MB的物理内存。对于x86系列和ARM系列的CPU来说,在内核启动过程中它会将现有物理内存地址全部映射到0x8000 0000以上的虚拟地址空间中供内核以后使用。OEM可以通过OEMAddressTable来详细定义虚拟地址和物理地址的映射关系。OEMAddressTable本身并不是一个文件,它只是存在于其它文件中描述虚拟地址和实际物理地址的映射关系的数据。比如文件oem init.asm中包含一段代码:dd 80000000h, 0, 04000000h 。它表示将整个物理地址(0x0400 0000=64MB)共64MB映射到虚拟地址从0x8000 0000到0x8400 0000中。关于OEMAddressTable我将在以后关于PB的文章中讲述。
整个4GB虚拟地址空间主要划分为两部分,从0x8000 0000以上为内核使用部分,0x8000 0000以下为应用程序使用部分。详细见下表:
地址范围用途 0x0000 0000到0x41FF FFFF 由所有应用程序使用。共33个槽,每个槽占32MB。槽0(Slot 0)由当前占有CPU的进程使用。槽1由XIP DLL使用。其它槽用于进程使用,每个进程占用一个槽。 0x4200 0000到0x7FFF FFFF 由所有应用程序共享的区域。32MB地址空间有时不能够满足一些进程的需求。那么进程可以使用这个范围的地址空间。在这个区域里应用程序可以建堆、创建内存映射文件、分配大的地址空间等。 0xA000 0000到0xBFFF FFFF 在这个范围内核重复定义0x8000 0000到0x9FFF FFFF之间定义的物理地址映射空间。区别是在这范围映射的虚拟地址空间不能够用于缓冲。
我举例来说明:假设一个产品有64MB物理内存。如上文所述定义好OEMAddressTable后。内核启动后一个物理地址映射空间范围在0x8000 0000到0x8400 0000,那么内核会从0xA000 0000到0xA400 0000定义一个同样范围的地址空间,这个地址空间和0x8000 0000到0x8400 0000映射到相同的物理地址。但这个虚拟地址空间不能够用于缓冲。 0xC000 0000到0xC1FF FFFF 系统保留空间 0xC200 0000到0xC3FF FFFF 内核程序nk.exe使用的地址空间。 0xC400 0000到0xDFFF FFFF 这个范围为用户定义的静态虚拟地址空间,但这个地址空间只能用于非缓冲使用。
利用OEMAddressTable定义物理地址映射空间后,每次内核启动时这个范围都不改变了,除非产品包含的物理内存容量发生变化。假如增加到128MB物理内存,那么物理地址映射空间也向后扩大了一倍。Windows CE.NET也允许用户创建静态的物理地址映射空间。用户可以调用CreateStaticMapping函数或者NKCreateStaticMapping函数来映射某一段物理地址到0xC400 0000和0xE000 0000之间的某一个范围。需要注意的是用这个函数创建的静态虚拟地址只能够由内核访问,而且不能用于缓冲。
0xE000 0000到0xFFFF FFFF 内核使用的虚拟地址。当内核需要大的虚拟地址空间时,会在这个范围内分配。

进入讨论组讨论。