Windows Embedded CE 6.0高级内存管理 .
Windows Embedded CE 6.0高级内存管理
摘要
本文介绍新版本Windows Embedded CE如何处理内存,它是如何构建的 ,以及这些变化对应用程序的影响。
简介
在过去的十年里,Windows Embedded CE的已经从一个新鲜面孔的新人,成长为嵌入式操作系统世界的白发老兵。在此期间,微软改进了有关Windows Embedded CE的几乎所有东西,但没有改进它的管理内存方式。当然,Windows Embedded CE是而且始终是一个现代化的、虚拟内存支持的优先多任务操作系统的,但也有对内存和代码密集系统如机顶盒等的严格限制。
具体来说,限制是32个并行进程限制和32 MB的应用程序虚拟空间限制。在Windows Embedded CE的初期这些限制都不是问题,在现在建立的许多嵌入式系统也不是问题。这些问题发生在集中媒体驱动的系统上,因此,运行Windows Media ®播放器,系统需要大量系统代码和应用代码。这些问题发生在有大量小进程(如一些进程控制系统)的系统上。
Windows Embedded CE 6.0中吹走了“两个32年代”,由于完全重写的内核和新操作系统架构。新的内核允许多达3.2万进程在任何时间运行。我怀疑在几年时间内这个新32K的进程限制不应该是问题。此外,对于给定应用程序的虚拟内存空间已经从每个进程32MB虚拟地址空间提高到每个进程2 GB的地址空间。
内存架构
要充分认识在新内核的改进,Windows CE 5.0架构综述是很有帮助的。图1显示了在Windows Embedded CE 5.0的虚拟地址空间。如同在Windows ® XP和Windows Embedded CE 6.0中,前2 GB是系统保留的地址空间。该地址空间的低半部被分成若干区域。这个区域的大多数,几乎一半的空间,被定义为大存储区。这个区域是用来分配通常用于内存映射文件中的大块内存空间。
图1
大内存区域下面是一套31“进程槽”,包含当前正在运行进程的虚拟地址映像。进程槽的下面,在内存空间最低端,是64 MB的区域。这64 MB区域,更准确的最低32 MB区域,是包含当前正在运行的线程的进程的复制进程槽。
这种“插槽结构”施加了32进程和32 MB虚拟内存限制。因为有数量有限的插槽(31),并发进程数量有限。 (按照市场营销数学,当你加入内核进程时,31进程插槽进入32个进程,位于高2GB的地址空间)。
图2是早期Windows Embedded CE进程空间中最低64 MB的扩展图。低32 MB的进程空间是进程槽的复制空间,该进程是当前正在运行的线程正在执行的进程。高32 MB用于加载代码,以及基于ROM的动态链接库的只读内存。高32 MB被称为“槽1”,是所有运行应用程序之间的共享。
图 2
32 MB虚拟空间限制来自于每个进程槽的大小。由于单一的,统一的地址空间,使得每个进程虚拟空间更大,这将导致较少的总插槽,从而减少并发进程。由于它是32个进程和每个进程作品32 MB的妥协,或者至少工作得很好。
应用程序虚拟地址空间
Windows Embedded CE 6.0的内存结构如图3所示。随着新的设计,每个正在运行的进程得到了整个低2GB地址空间的副本。虽然在表面看来,这2 GB的空间与Windows XP有相同的布局,但应用程序地址空间的使用是不同的。
图 3
图4显示了一个给定的Windows Embedded CE 6.0进程的虚拟内存空间的布局。像早期的Windows Embedded CE的体系结构,应用程序的虚拟内存空间一分为二。低1 GB的空间是来加载应用程序代码,而且应用程序可以分配内存。这里是所有内存分配的地方,这也是应用程序的所有线程的堆栈位置。
图 4
这个区域上面是一个512 MB的区域,系统会加载代码和DLL只读数据,当前正在运行的各种应用程序加载的。像早期的Windows Embedded CE的版本,一个由一个应用程序加载的给定的DLL是在一个进程加载的加载具体地址在所有进程的同一地址加载该DLL。在这一区域的DLL是从下往上装在该区域(在0x4000 0000开始),而不是自上而下的,就像是Windows Embedded CE早期版本的情况。
在DLL地址空间的上,0x6000 0000开始,是一个256 MB的区域用来分配支持RAM内存映射文件。支持RAM内存映射文件,也称为内存映射对象已知的是内存映射文件,没有实际的文件支持对象中的数据。内存映射对象通常用于进程间通信。为了便于向后兼容性,如果一个已命名的内存映射对象是在多个进程分配,它映射在所有映射对象的进程的相同基址。如果一个进程打开一个内存映射访问的实际文件时,该内存映射文件缓冲区分配在应用程序的地址空间的低1GB。
在虚拟地址0x7000 0000是一个255 MB的区域是操作系统和应用程序之间的通信。这个区域对应用程序是只读,但对操作系统可读可写。最后,还有在0x7FE0 0000的1 MB后卫区域不能由应用程序或操作系统访问。
总之,应用程序有1GB的地址空间,供其代码和所有内存和堆栈分配,另一个1GB为了专用用途。虚拟内存空间只有一半可用来内存分配,它比早期的在Windows Embedded CE 5.0的有同样目的32 MB区域更好。此外,由于Windows Embedded CE 6.0中保留了512 MB的物理RAM电流限制,我怀疑应用程序用完虚拟内存空间之前,系统会用完物理内存。
内核的虚拟地址空间
Windows Embedded CE 6.0中的内核地址空间的内存映射如图5所示。
图 5
由于早期的Windows Embedded CE的版本中,前两个内核地址空间区域在物理地址空间中是缓存和未缓存的窗口。正是通过这些窗口的操作系统和驱动程序访问内存和内存映射的外设。
在地址0xC000 0000有一个128 MB的区域,它是基于ROM由内核加载的DLL被映射。 128 MB的区域在0xC800 0000的上方,它被文件系统用来映射基于RAM的对象存储。
从0xD000 0000开始的区域是内核的虚拟机空间。该区域是操作系统的内核模式端执行的区域。所有操作系统的扩展例如文件系统和GWE,以及所有内核模式设备驱动程序,加载在内核区域。这个区域的大小取决于CPU。对于SH4处理器,该区域是256 MB,但所有其他CPU的大小为512 MB。最后,在0xF000 0000区域由内核用于CPU特定用途。
这种新的存储器映射是一个很大的线索,这不是你父亲的Windows Embedded CE。对于一个更清晰的操作系统巨大变化的例子,,让我们谈谈Windows Embedded CE 6.0中的架构。
操作系统的体系结构
藉由对内存的讨论,来充分理解在Windows Embedded CE 6.0内核的变化,我们需要回顾Windows嵌入式CE 5.0,看看它是如何放在一起。从一开始,Windows Embedded CE设计在一系列用户模式进程周围,称为进程服务器库(PSLs)。而内核,在内核模式下运行nk.exe,对操作系统的其他部分,如文件系统,设备管理器,图形子系统每个单独的,用户模式的可执行文件名分别为FileSys.exe,Device.EXE,和GWES.EXE。
这些独立的进程使操作系统强劲,因为主要子系统彼此受到保护,但这以性能为代价。一个函数调用操作系统造成至少一或两个进程切换。除了这些进程受到相同的32 MB的进程限制,即Windows Embedded CE对所有进程的限制。
在新的Windows Embedded CE 6.0内核摒弃了独立的进程,给所有子系统带来了内核虚拟机。这一变化提高了操作系统的性能,因为各子系统之间的通信现在是一个简单的、进程内调用。图6显示了新的操作系统架构图。
图 6
请注意,早先的子系统(文件系统,设备和GWES)是现在的DLL。此外,用在nk.exe里的内核代码现在在Kernel.dll里。新nk.exe只包含了OEM抽象层的代码和一个非常薄的兼容层。这种分离会提高可维护性,因为现在内核可以从OEM代码独立更新。
既然设备管理在内核虚拟机里,大部分设备驱动程序也移到这里了。以前版本的Windows Embedded CE,设备管理器将在开机和需求加载设备驱动程序,但现在,不是在用户模式下运行,大部分设备驱动程序将运行在内核模式。
在内核虚拟机中运行驱动程序,可能意味着一个大的移植工作是从OEMs移植到版本6.0,移植应该是很简单。简单移植任务的关键是一个新的DLL名为k.Coredll.dll。此DLL模仿Coredll.dll,仍然驻留在用户模式下,提供相同的API到内核模式代码呈现给用户模式应用程序。当一个内核模式DLL调用一个API,如VirutalAlloc,k.CoreDll只是反映了Kernel.dll处理。由于此调用都在同一个虚拟机内时,调用VirtualAlloc代码的时间明显比在Windows Embedded CE5.0驱动调用的时间或以前要少。
Coredll.dll不只是来得到这个“k”待遇的DLL。任何需要在内核和用户模式加载的DLL将被实际加载到这两者中。由于Windows Embedded CE 6.0中保留了需要保持在固定地址的一个DLL实例,该DLL的内核拷贝将其名称在DLL的名称前加上一个k.。
在某些系统上有一些驱动不应该在内核虚拟机中,例如,第三方驱动程序是在设备安装后启动。对于这些类型的驱动程序,Windows Embedded CE 6.0中提供了一个用户模式设备驱动程序管理器,它将在用户模式下驱动程序装载。当与调用应用程序通信时,用户模式驱动程序将有所放缓,但其隔离性提高将安全性。
在Windows Embedded CE 6.0中支持的服务,与在以前版本的操作系统支持的方式几乎相同。像以前一样,在Windows Embedded CE 6.0的服务将运行在用户模式下,将被服务管理器载入。他们的设计除了一个小注册表外没有变化,改变了面向Windows Embedded CE 5.0的服务将未修改运行在Windows Embedded CE 6.0。
新设计的规划影响
虽然新架构看起来很有趣,阅读这篇文章的大多数程序员可能会想:“这对我的应用程序意味着什么?”幸运的是,操作系统应用程序的变化将变小。
首先,让我们来看看现在已经过时的老问题。 Windows Embedded CE系统多年来一直困扰的问题,即太多DLL占用了一个多进程的虚拟内存空间。虚拟空间的小型应用程序,以及一些规则即Windows Embedded CE用来的加载DLL会导致适合一些系统。随着新的2 GB的地址空间,“DLL危机”问题是过去的事情。
另一个较大内存空间的影响,当保留大量虚拟内存时用完虚拟内存空间的问题已经不复存在了。事实上,曾痴迷于小虚拟机空间的系统程序员现在要看到这样的应用程序,它在用完虚拟机空间之前用完物理内存。这并不是说Windows Embedded CE 6.0比早期版本使用更多的内存,懒惰的程序员会简单地分配内存来填满可用空间,而不是消除虚拟机障碍。
安全
自2.12以来Windows Embedded CE的标准功能一直是“信任模块”的安全方法。在这个方案中,在加载进程时检查模块(EXE和DLL)。 OEM代码可以决定让系统加载模块到“受信任”或“不信任”模式。如果模块在 “信任模式”下 运行,它可以调用系统中的任何API。在“不可信模式”下的代码不能调用系统的关键API的小套,找不到任何一个线程的优先级比从最低优先级起第八级还高。此外,OEM甚至可以告诉系统不要加载模块。
Windows Embedded CE 5.0和以前版本也有,系统的所有代码运行在内核模式中的一种特殊模式,而不是把内核运行在内核模式或用户模式系统的其余部分。运行在“内核模式”的优势在于安全与性能的权衡,因为内核代码和内存空间,可以访问所有应用程序。
Windows Embedded CE 6.0去掉“所有内核模式”和安全信任模型。所有的内核模式不是必需的,因为“所有内核模式”的性能是由于新内核架构优势而提升的。信任模式消失,移植桌面的访问控制列表(ACL)安全预期到未来版本的Windows Embedded CE。对Windows Embedded CE 6.0,没有信任模式,也没有ACL安全。
Windows Embedded CE 6.0提供与以前Windows Embedded CE版本相同的进程间通信工具。这些工具包括RAM支持的内存映射文件,点至点的消息队列,以及诸如WM_COPYDATA消息的老经典。
Windows Embedded CE 6.0不提供的是“基于槽”的通信方法。有一些应用程序使用进程映射调用(MapCallerToProcess)和设置权限API(SetProcPermissionsAPI)以能够读取和写入跨进程边界的内存。这两个API,以及其他一些依赖槽模型的功能不再相关。为兼容性它们由Coredll.dll输出,并没有在Windows Embedded CE 6.0中的作用。用设置权限(SetProcPermissions)的应用程序的工作区,是使用读进程内存(ReadProcessMemory)和写进程内存(WriteProcessMemory),这是CE 6.0支持的。
另一个在Windows Embedded CE 6.0里的变化是,应用程序可以不再从一个进程复制句柄到另一个。 CE 6.0每个进程使用单独处理表,因此每个进程处理的值是独立的。要变通解决此问题,应用程序应该使用复制句柄API(DuplicateHandle API)来克隆一个句柄,以便在另一个进程使用。
在一般情况下,写得很好的Windows Embedded CE应用程序(写得很好的意思是它们不使用以插槽为基础的方法)未经修改在Windows Embedded CE 6.0中运行。为了确保您的应用程序将运行,你可以使用相容性测试工具,将交付给Windows Embedded CE 6.0平台生成器。
结论
Windows Embedded CE 6.0是Windows
Embedded CE的巨大进步。取消经典内核限制将减少帮助企业解决这些问题的顾问的工作要求。这种新的内存模型使Windows Embedded CE更接近桌面模式,没有Windows
XP的大小或成本。希望看到一类由这一更好的新版本Windows Embedded CE驱动的功能强大的全新设备。