(轉)關於romimage

1. romimage是什麼?
romimage是wince編譯過程中最後一步。在此之前,ce的編譯系統已經調用自己的arm編譯器,對每個模塊完成了編譯工作,並生成了.exe,.dll等文件;同時針對當前的環境設置,生成了.bib,.reg等文件。另外還有一些別的文件。最後編譯系統將所有這些需要“打包”的文件,拷貝到_WINCEROOT/release目錄下。而romimage的作用,就是根據ce.bib文件,來生成最後的nk.bin和nk.nb0。

2. romimage的輸入和輸出。
romimage輸入ce.bib文件,輸出nk.bin和nk.nb0。ce.bib相當於一個配置文件,告訴romimage如何生成映像。而nk.bin和nk.nb0實質上其實是一個東西,nk.nb0是系統在ram裏跑的一個平坦映像(plane image)。當eboot或者ipl將nk.nb0加載(或者先將nk.bin“解碼“然後加載)到指定的內存地址後,會跳轉到這個地址上從而開始ce的os的執行。
而nk.bin是以sections爲單位的映像。romimage其實最先生成的是nk.bin,然後將其組織成nk.nb0。關於bin文件的結構,在ce的文檔裏有一篇文章“Windows CE Binary Image Data Format”專門加以說明。

3. 準備工作。
爲了便於調試追蹤,我重新編譯了romimage.exe,編譯環境是vc6.0 sp6。編譯的時候有些lib文件ms沒有提供,將相關的代碼註釋掉即可,並不影響對romimage的理解。
另外由於romimage的運行時間太久,所以我處理了ce.bib文件,保留MEMORY、CONFIG段不變,MODULES段保留如下內容:
nk.exe          g:/WINCE500/release/kernkitl.exe             NK SH
osaxst0.dll     g:/WINCE500/release/osaxst0.dll              NK SHK
hd.dll          g:/WINCE500/release/hd.dll                   NK SHK
coredll.dll     g:/WINCE500/release/coredll.dll              NK SH
filesys.exe     g:/WINCE500/release/filesys.exe              NK SHM
gwes.exe        g:/WINCE500/release/gwes.exe                 NK SHM
device.exe      g:/WINCE500/release/device.exe               NK SHM
   devmgr.dll      g:/WINCE500/release/devmgr.dll               NK SHM
這8個文件基本覆蓋了MODULES段的各種情況。對於FILES段,類似的保留4個文件:
ceconfig.h       g:/WINCE500/release/ceconfig.h              NK
wince.nls       g:/WINCE500/release/wince.nls                NK SHU
initobj.dat     g:/WINCE500/release/initobj.dat              NK SH
boot.hv         g:/WINCE500/release/boot.hv                  NK SH
另外對於ROMSIZE,設得越小越好,我改成了00300000。 這樣在我的機器上,運行debug模式的romimage,只需要10秒鐘,生成的nk.bin只有2M大小。
還可以進一步減少這個時間。一開始我的memory段是這樣設的:
ARGS     80060000 00001000 RESERVED
    NK       800B0000 02000000 RAMIMAGE

    RAM      820B0000   01F10000 RAM
    IMCPY    83FC0000 00040000 RESERVED
而AUTOSIZE=ON。這意味着romimage要對MODULES段和FILES段的所有的文件掃描兩遍,第一遍的目的僅僅是確定真正的RAMIMAGE的大小。所以我直接設置RAMIMAGE的大小,將AUTOSIZE=OFF。現在memory段是這樣的:
    ARGS     80060000 00001000 RESERVED
    NK       800B0000 223F10 RAMIMAGE

    RAM      802E0000   3CE0000 RAM
    IMCPY    83FC0000 00040000 RESERVED
這樣運行romimage只需要5秒鐘。但是這樣做的目的不是節省這5秒鐘的時間,而是對於romimage的整個過程更加簡潔便於理解。
另外,對於windows mobile尤其漫長的編譯時間感到厭煩的朋友,可以使用這種方法減少一些編譯時間。   

4. romimage的流程概述。
romimage做了一些初始化工作後,首先要做fixup。這也是romimage的主要工作。fixup的目的是根據rel文件給出的地址信息,將大部分modules裏的地址信息reloacate。這是因爲.exe和.dll文件本來是以進程的虛擬地址空間編譯的,其base地址和加載地址可能並不符合realaddress的需要。fixup又分三種情況。第一種是對於內核空間的modules,比如nk, osaxst0.dll, hd.dll等,其base地址是在內核空間0x80000000以上,其fixup需要特殊處理。第二種是對於dll,其優先的加載地址是在slot1,但是其可寫的數據段地址還要加載在slot0;第三種是虛擬地址slot0加載的.exe,這種一般不需要fixup。
之後對於有導入段的模塊需要處理導入符號,有壓縮標誌的段進行壓縮,還有一些其它的處理。
接下來需要對每個模塊的段的位置加以調整。wince原則上將readonly段按照模塊順序依次以page大小對齊從NK開始放置。每個段之間會有一些閒置的區域,叫做holes,最後一個段到NK的結束地址還有一個很大的hole。wince利用這些holes存放readwrite段,還有其它的信息,比如e32, o32, romhdr, 模塊和文件名稱等等信息。因爲對於readwrite段,要麼會在系統初始化的時候被copy到ram區域(此種情況對應內核空間的readwrite段),要麼會在程序初始化的時候給其分配具體的地址空間(此種情況對應普通的exe的readwrite段)。
最後將所有信息寫入bin或者nb0文件,例如ptoc等各種信息,包括上面的e32等,還有具體的段的內容就是在這時寫入的。

5. 總結。
romimage是一個挺有意思的工具。充分理解它的機制,對於理解wince的os,以及縮短具體項目的編譯時間,是很有幫助的。我花了一段時間讀懂了代碼,但是由於工作緊張實在沒有時間具體記錄下來,只能寫個大概了。所以我將3. 準備工作寫得很詳細,是希望能夠方便有興趣的朋友去研究。

 

http://hi.baidu.com/garnetttt/blog/item/c971bc31f45099ac5edf0eed.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章