天天看點

Windows Embedded CE6.0高效的記憶體管理

作者:Douglas Boling 時間:2007年3月 本文來自:微軟MSDN技術論文中心

     本文主要介紹新版本嵌入式作業系統(Windows Embedded CE6.0)是如何管理記憶體的,内容主要包括如何構架以及在應用程式發生的變化兩個部分。

     在過去的10年裡,Windows Embedded CE作業系統已經從一個非成熟的作業系統發展成一個新的、有活力的作業系統。當然,Windows Embedded CE始終是一個先進的、搶先多任務和支援虛拟記憶體的作業系統,,在這段發展過程當中,微軟在Windows embedded CE作業系統除記憶體管理外的各個方面都進行改進,但、Windows Embedded CE作業系統卻在一些領域因為記憶體和代碼密集因素受到一些嚴格的限制,例如機頂盒領域。

      具體來說,這些限制是Windows Embedded CE作業系統最多支援32個進行并發,每個程序最對隻有32MB虛拟記憶體。這些限制方面的問題僅僅隻出現在前期版本的Windows Embedded CE作業系統當中,在現今的其他嵌入式作業系統當中也存在。為了減少程序數量,系統往往将許多應用程式如Windows Media® player內建到系統程式中實作,這導緻整個系統和應用程式代碼龐大,如此,往往還需大量的小程式來控制內建到系統中的應用程式。

      由于采用了完全重寫新的作業系統核心和架構,Windows Embedded CE6.0從此打破了“兩個32時代”。新核心支援32000個程序并發,我們可以相信在數年内32K程序并發支援都不會再受到限制。另外應用程式的虛拟記憶體也得到了改善,從原先的32MB提升到了2G的虛拟記憶體空間。

      為了幫助完全了解Windows Embedded CE新核心做的改善,我們先來重新展示Windows Embedded CE5.0作業系統的記憶體結構。圖1.1為Windows Embedded CE5.0的虛拟記憶體結構。如同Windows® XP 和 Windows Embedded CE6.0一樣,Windows Embedded CE5.0的前2G的記憶體為作業系統本身預留的,後半部分(低位址段)被分成很多個區域,每個區域32MB。另一半最大的區域,配置設定了大塊的記憶體,常常配置設定給記憶體映射檔案使用。

Windows Embedded CE6.0高效的記憶體管理

圖 1. 1 Windows Embedded CE5.0虛拟記憶體結構

      下面的大塊記憶體被分成了31個Slot,其中包括正在運作程序的虛拟記憶體結構,下面這些程序Slot,每個程序的最大記憶體空間隻有64MB。更确切的說,最低的32MB區域是分給目前運作的程式,其中包括也這個程序建立線程。

      這樣的“Slot結構”導緻32個程序和32MB虛拟記憶體的限制。因為這31個Slot限制了程序并發的數量,包括系統,不能操作32,計算下,當你将這32個程序并發運作在系統當中所需的記憶體就已經到了2G了。

      如圖1.2所示最低64MB Windows Embedded CE的虛拟記憶體空間。其中低32MB是用來從目前正在運作的程序中的線程中複制其被配置設定的記憶體空間。高32MB用來加載代碼和存儲在隻讀ROM-Based的動态連結庫,高32MB被視為“Slot1”,被所有的運作的應用程式所共享。

      每個Slot的大小導緻32MB的限制,由于單一的,傳統的記憶體空間,如果使每個程序的虛拟記憶體變得更大些,這将減少Slot的數量,進而減少并發程序數量。正是因為記憶體大小(32MB)和程序數量(32個)都做了相應的妥協才保證系統的能更好的工作。

Windows Embedded CE6.0高效的記憶體管理

圖 1. 2 最低64MB Windows Embedded CE的虛拟記憶體空間

      Windows Embedded CE6.0新的記憶體結構如圖1.3所示。采用這種新的記憶體結構,每個應用程式可以最多配置設定到2G的虛拟記憶體空間,雖然這2G的空間表面上類似Windows XP作業系統,但是每個應用程式使用相同的虛拟位址空間布局似乎是不同的。

      圖1.4顯示了Windows Embedded CE6.0中每個程序的虛拟記憶體空間配置設定結構。像早期的Windows Embedded CE6.0一樣,2G的虛拟記憶體空間被分成兩部分。其中低1G空間用于加載代碼和動态配置設定記憶體,這裡所有配置設定的記憶體都被本配到程序中相關線程堆棧的位置。

      剛剛越過這個區域的一個512MB的區域,用于加載系統代碼和所有應用程式需要的存儲在隻讀ROM-based的動态連結庫。像以前版本的Windows Embedded CE作業系統一樣,每個被應用程式加載的DLL都被加載到所有程序加載這個DLL的相同位址位置。這個DLL從這個區域的底部位址(0x40000000)開始,不是自上而下方式,具體要視不同版本的Windows Embedded CE而定。

Windows Embedded CE6.0高效的記憶體管理

圖 1. 3 Windows Embedded CE6.0新的記憶體結構

      越過DLL區域,從0x60000000開始,是一個256MB空間。這段空間用于配置設定RAM-backed記憶體映射檔案。配置設定RAM-backed記憶體映射檔案也被視為記憶體映射對象,沒有一個實際的檔案支援的對象資料。記憶體映射對象常用于程序間通訊。為了友善向後相容,如果一個名為記憶體映射對象是在多個程序配置設定,系統将為這些記憶體映射對象配置設定相同的位址。如果一個程序打開一個記憶體映射通路實際的檔案,則該記憶體映射檔案緩沖區将被配置設定在應用程式虛拟位址的空間的低1GB的空間中。

      在虛拟位址0x70000000後的256MB的區域是用于作業系統和應用程式通信,對應用程式來說,這部區域隻讀,對作業系統來說,這部分可讀可寫。最後,其中0x7FE00000開始的1MB空間是一個警戒區,作業系統和應用程式都無通路權限。

      總之、在Windows Embedded CE6.0中,應用程式有1G的虛拟位址空間用于加載代碼和記憶體配置設定,另外的1GB空間用于專用用途。雖然虛拟記憶體空間隻有一半是可用的記憶體配置設定,它比以前的32 MB的Windows Embedded CE5.0要好的多了。另外,由于Windows Embedded CE 6.0中保留了512 MB的實體的限制,我猜測作業系統在一個應用成熟釋放完成虛拟内空間之前就已經釋放了實體RAM空間。

Windows Embedded CE6.0高效的記憶體管理

圖 1. 4 Windows Embedded CE6.0中每個程序的虛拟記憶體空間配置設定結構

      圖1.5為Windows Embedded CE6.0核心虛拟位址的核心配置設定圖。以早期版本的Windows Embedded CE6.0作業系統一樣,這首兩個核心位址空間區域分别是在實體位址空間上的緩存和非緩存視窗。通過這些視窗作業系統和驅動能通路到RAM和記憶體映射的外設當中。

Windows Embedded CE6.0高效的記憶體管理

圖 1. 5 Windows Embedded CE6.0核心虛拟位址的核心配置設定圖

      在位址0xC0000000後的128MB的區域中分布被核心加載的ROM-based動态連結,下一個0xC8000000開始的128MB區域存儲映射到RAM-based對象的檔案系統。

      從0xD0000000開始就是核心虛拟機空間。這個區域正是系統的核心模式制定的地方。核心、所有的作業系統的擴充(像FileSys、GWE和運作在核心态的裝置驅動)都被加載到這個區域。這個區域的大小依據采用的CPU而定。除sh4是256MB外,其他所有的CPU都是512MB。最後、從0xF0000000開始的區域被用于特定的CPU專有用途。

       新的記憶體配置設定方式比起前期的Windows Embedded CE作業系統發生很大的變。為了更清晰的認識這巨大的變化,接下來讓我們談談Windows Embedded CE作業系統是如何構架。

      正如記憶體讨論的一樣,這充分的展示了Windows Embedded CE6.0核心發生了巨大的變化。我傳回Windows Embedded CE5.0看他們是如何構架。從一開始,Windows Embedded CE一直維繞這使用者模式程式設計被稱為PSLs。雖然核心程式,NK.exe操作在核心模式,作業系統的其他部分如檔案系統、裝置管理、圖形子系統都被獨立分開。使用者模式隻用檔案名FileSys.exe、Device.exe和GWES.exe加以區分。

      這些單獨的程序所作的作業系統強勁,因為來自主要子系統互相保護,但在性能為代價。一個函數調用作業系統造成至少1和可能兩個程序開關。除此之外,受到32MB限制的Windows Embedded CE作業系統限制了所有的程序。

      Windows Embedded CE6.0核心屏蔽了獨立的程序,并把所有的進入核心的程序運作在虛拟機子系統中。這一變化提高了作業系統的性能,因為各子系統之間的溝通現在是一個簡單,内部調用即可。如圖1.6所示Windows Embedded CE作業系統的結構。

      注意早期版本中的子系統(FileSys,Device,和GWES)現在是DLLs。另外、核心代碼也由原來的NK.exe變為現在的Kernel.dll。新的NK.exe隻包含OEM抽象層代碼和一個非常小的相容層。這種分離會改善可維護性,因為核心更新,隻需更新OEM代碼即可。

      現在裝置管理在核心虛拟機裡面實作,大多數的裝置驅動也內建在裡面。在以前版本的Windows Embedded CE,裝置管理器隻有在系統重新開機和有需要後才加載驅動程式,它們都運作在客戶模式,現在所有的裝置驅動都運作在作業系統核心态。

Windows Embedded CE6.0高效的記憶體管理

圖 1.6 Windows Embedded CE作業系統的結構

      然而運動都運作在核心虛拟機裡面,這意味着将OMEs一直到6.0版本将是一個很大哦的工程,并迫在眉睫。但是移植其實很簡單,關鍵的任務是k.Coredll.dll動态庫。他和個動态庫被命名為新的名字Coredll.dll,它一直駐留在使用者模式下,像使用者态程式提供對應的核心态API,例如VirutalAlloc函數。對于應用程式來說,k.Coredll.dll隻反映Kernel.dll調用接口。因為這些調用都是在相同的虛拟機中完成的,這個時候調用VirutalAlloc函數Windows CE5.0後以前的作業系統要簡單多了。

      Coredll.dll不僅僅去掉k.Coredll.dll連結庫中的"K",任何一個DLL想要在使用者和核心模式被調用,那麼這個DLL需要在使用者和核心模式都被加載。由于在Windows Embedded CE6.0為每一個執行個體化的DLL都保持了一個固定的位址,且在DLL名稱前加一個"K"來進行重新命名。

      實際上有些驅動程式不應該加載到核心虛拟機裡面,例如第三方的驅動是在裝置執行個體化之後才進行安裝的。Windows Embedded CE6.0提供了一個使用者模式的驅動管理管理器,它将加載這些驅動到使用者模式。使用者模式的驅動與應用程式的通訊應該盡量減少,除非改善了安全機制。

      在Windows Embedded CE6.0和以前的其他版本的驅動幾乎一樣的方式支援。和以前一樣,Windows Embedded CE6.0的服務被放置帶使用者模式,有服務管理器統一加載。除了系統資料庫外,他們的設計一點沒變,以前的Windows Embedded CE5.0服務隻需更改系統資料庫就可以在6.0平台下運作。

      雖然新的架構看起來很有意思,但是到多數程式員讀到這篇文章可能會很驚訝“這些改變對我的應用程式意味着什麼?” 幸運的是新系統的改變将應用程式變得更加成熟、更加好的處理效果。

      首先、讓我們來回顧一下以前的老問題。Windows Embedded CE作業系統由于DLL檔案占用了太多的程序虛拟記憶體空間導緻被很多年被程式員們所唾棄。一些小的應用程式虛拟機空間,一直有些Windows Embedded CE加載的DLLs用于适合一些系統規則。現在新的系統,2G的位址空間,“DLL 破碎”的問題已經成為過去。

      另一個大記憶體空間的效果,系統保留的虛拟記憶體數量被用光之後,虛拟記憶體跑飛的問題。實際上,系統程式員擔心應用程式在用完虛拟機空間之前已經用完了實體RAM的那塊虛拟機空間。在6.0中這個問題消失了,Windows Embedded CE6.0甯願為配置設定更多的RAM比以前的本版的系統,以防止VM強制移除、内配的記憶體瞬間達到可用的空間。

      Windows Embedded CE2.12以後的版本系統的一個标準特性是系統采用的安全手段。在這個體系中,子產品(可執行檔案和DLL檔案)在加載的時候都被檢測。OEM代碼可以決定系統将這個子產品加載到信任還是非信任模式。如果這個子產品運作在可信模式,它能通路系統的API。如果子產品的代碼加載到非信任區将不能通路系統的一小部分關鍵的API和不能設定任何線程的優先級高于第8個最低的優先級。OEM甚至能告訴系統不要加載某個子產品。

      Windows Embedded CE5.0和以前的版本有一個特殊的模式,在這個模式下,系統能運作所有的代碼運作在核心模式,替代核心代碼隻能運作在核心模式下,系統剩下的部分隻能運作使用者态。由于核心代碼和記憶體空間能通路所有的應用程式,是以在使用特殊模式的時候,應該權衡下安全性能。

       Windows Embedded CE6.0抛棄了上述的特殊模式和可行模式,特殊模式已經不需要了,因為在新的核心架構中大多數都能獲得進入特殊模式的能力。在後期的Windows Embedded CE版本中将用桌面安全通路控制清單來替代可信模型,但是在Windows Embedded CE6.0中完全抛棄了可信模型和安全控制清單。

       Windows Embedded CE6.0和早期的一些版本提供了一樣的程序間通信方式。這些方式包括RAM-backed記憶體映射檔案,敵對點消息隊列和傳統的WM_COPYDATA消息機制。

      利用“Slot based”通信方式已經在Windows Embedded CE6.0行不通了。有些應用程式用MapCallerToProcess和SetProcPermissions試圖去讀寫程序内部的記憶體。這兩個函數有幾個其他的函數依賴與“Slot模型”外,其他一點關系都沒有。如果你從Coredll.dll中到處了用于相容的函數,那麼在Windows Embedded CE6.0中用這兩個函數是一點問題都沒有。

      另外一個Windows Embedded CE6.0的改變是在也不能拷貝句柄到另一個程序中。CE6.0是将每一個程序的句柄表分開。如此句柄值隻依賴于每一個程序本身。為了去解決這個問題,應用程式可以用DuplicateHandle函數從其他程序克隆句柄。

      總體來說,寫好的Windows Embedded CE應用程式(不能用Slot-based方式)可以無需修改就可以運作在Windows Embedded CE6.0系統中,為了確定應用程式能夠運作,你應該在Windows Embedded CE6.0 Platform Builder中加入相容的測試工具。

       Windows Embedded CE6.0對于Windows Embedded CE系列來說是一個巨大的提高。傳統核心限制的消除将較少為了解決這個問題特增加的幫助程式。新的記憶體管理模式将使得Windows Embedded CE更加接近于XP桌面模型,但是核心尺寸和開銷還是不同。期待下一步能看到一款全新的強悍的裝置驅動模型,和更好的Windows Embedded CE版本。

申明:本文為作者原創翻譯,轉載必須獲得部落客同意,否則侵權.

繼續閱讀