Wince啓動失敗的原因分析

①BootLoader初始化硬件失敗
  BootLoader第一個功能是要實現板級和片級初始化硬件,主要是把CPU
初始化到一已知狀態。在BootLoader目錄下,會發現一些.s文件,可能會是init.s或者是
reset.s等,這樣的文件是CPU加電後最先執行的代碼。StartUp 函數是BootLoader
的入口函數。該函數一般是使用匯編語言編寫,與CPU關係非常緊密,能完成初始化CPU
、內存等核心硬件。然後,BootLoader
在平臺初始化完畢後就可以在不用人工干預的情況下自動加載WinCE內核了。但如果
BootLoader在初始化硬件時失敗,就會直接導致系統的啓動失敗了。
  ②BootLoader加載內核時失敗
  一般在平臺調試完畢後,BootLoader就會加載WinCE內核映像,這也是BootLoader
的功能之一。WinCE內核映像文件通常叫做nk.bin,它是Windows CE
二進制數據格式文件,不僅包含了有效的程序代碼,還有按照一定規則加入的控制信息。
  在系統啓動時BootLoader可以通過兩種不同的方式來加載WinCE內核文件nk.bin
。一種是下載模式,另一種是本地啓動模式。本地啓動模式也稱爲自主模式,即
BootLoader 從目標機上的某個固態存儲設備上將操作系統加載到 RAM
中運行,整個過程並沒有用戶的介入。而下載模式則是目標機上的 BootLoader
將通過串口連接或網絡連接等通信手段從主機(Host)下載文件。當BootLoader正確的把nk
.bin解壓到RAM後,就會把CPU控制權交給CE內核。因此,如果Boot Loader
處理不當,就可能會造成加載和解壓nk.bin
文件的失敗,這樣自然也就會造成系統啓動的失敗了。
  (2)OAL導致的啓動失敗
  OAL(OEM Adaptation Layer)是指OEM 適配層,它是位於Windows CE
內核和硬件之間的一層適配層,是OAL各個模塊代碼被編譯後(.lib)
和其它內核庫鏈接到一起形成Windows CE的內核可執行文檔NK.EXE。OAL
包括了和系統硬件通訊的最底層代碼,內核是通過OAL跟硬件進行交互。邏輯上,OAL
是介於CE內核和設備硬件之間的一個代碼層,是一個抽象的概念。物理上,OAL
和其它一些庫一起鏈接成可執行文件。
  與以前的Win CE舊版本不同的是,在Win CE 6.0中內核(Kenerl)和OEM代碼被分成oal
.exe、kernel.dll和kitl.dll三個部分,其中啓動代碼(startup)和 OAL
層的實現部分不再與內核鏈接生成NK.exe,取而代之的是啓動代碼(startup)
和硬件相關且獨立於內核的OAL層的實現部分編譯成 oal.exe;
而與內核相關且獨立於硬件的OAL層代碼包含在kernel.dll中,內核無關傳輸層(KITL)
的支持代碼從OAL層分離出來編譯成 kitl.dll。因此,WinCE6.0的啓動只與oal.exe和
kernel.dll有關。至於kitl.dll,只有將操作系統編譯成具有 KITL
功能時纔用到。這樣做的好處是可以單獨升級OAL,但整體的OAL結構並沒有改變。
  ①OAL初始化硬件時失敗
  oal.exe是通過Startup函數來完成硬件的初始化。一般來說,OAL的啓動代碼(
Startup.s)與該硬件平臺的Bootloader的啓動代碼(Startup.s)
是可以共享的。例如,其中PreInit 函數主要完成將arm
處理器工作模式切換到管理員模式,同時關閉MMU
,並檢測系統啓動原因。如果是熱啓動,即在該函數調用之前已經啓動過 Bootloader
的啓動代碼(Startup.s),相當基本硬件初始化已經完成,則可直接跳轉到OALStartUp
函數中;
否則需要進行硬件中斷屏蔽、內存、系統時鐘頻率、電源管理等硬件的基本初始化過程。
  在StartUp 函數初始化CPU等核心硬件並跳轉到Main函數後,系統就會轉入C
語言代碼執行環境。這時Main函數分爲3個模塊:BLCOMMON、Download Function、FLASH
Function。其中BLCOMMON模塊是由微軟提供的,執行一些邏輯上的功能。而Download
Function、FLASH Function
中的函數與硬件平臺息息相關。因此,對於每種硬件平臺都要將函數的實現進行適當修改?
庵中薷氖切枰雜布淺J煜さ摹5斃薷某魷執砦笫保突岬賈孿低稱舳О芰恕?
  在硬件平臺初始化完成後,oal.exe
的啓動任務基本完成,餘下的啓動工作由內核相關且獨立於內核的OAL層實現體kernel.
dll接管。也就是說,這時Startup會調用OALStartUp函數,OALStartUp函數主要完成將
OEMAddressTable表傳遞給內核,然後調用KernelStart函數跳轉到內核。因此,如果此時
OAL的啓動Startup函數調用失敗的話,就也會導致系統的啓動失敗了。
  這裏需要特別注意的是,Bootloader和OAL中均包含啓動Startup
函數。它的功能大致相同,都是要初始化最小硬件環境。Bootloader的啓動Startup
函數是在爲自己的執行準備硬件環境,OAL的啓動Startup函數則是爲kernel
的執行準備硬件環境。由於這兩種硬件環境要求基本相同,所以它們的代碼也有很大部分?
梢韻嗷ソ杓5Ω妹靼譈ootloader與OAL
在物理上是獨立的,它們並不是同一段代碼。當然,如果可以確定這一部分在Bootloader
已經初始化過如熱啓動,則在OAL中不必重複執行。
  ②OAL入口位置定位失誤導致的失敗
  從上述WinCE啓動流程可知,在OAL初始化硬件後而在內核啓動前,系統是需要調用
KernelStart函數來跳轉到內核。因此,這裏有一個要點,就是WinCE需要找到OAL
的入口位置,然後才能調用入口函數與全局塊進行指針交換,這樣內核才能使用OAL
層中的信息,同樣OAL層也才能訪問內核(kernel)導出的函數。
  OAL入口位置函數的調用實際上是通過OEMGLOBAL結構體實現的,實際調用位置爲
OEMInitDebugSerial和OEMInit。也就是說,OEMGLOBAL結構體構建了內核和OAL
層之間進行通信的橋樑。OEMGLOBAL結構體定義了OAL層所有必須的函數,該結構體在
oemglobal.c文件中被初始化,並會被編譯在OEMMain.lib和 OEMMain_StaticKITL.lib
兩個庫中。如果OAL
鏈接這兩個庫,則必須要有正確的該結構體的函數實現體,同時還需要調用ARMSetup
來設置物理地址和非緩衝的虛擬內存地址的映像、arm
中斷向量以及內核模式所需要的堆棧、調用OEMInitDebugSerial
函數初始化調試串口、調用OEMInit進行平臺初始化等。否則,如果OAL
入口位置函數有誤,則內核和OAL
層之間的訪問就會失敗,也就會導致系統在啓動時出錯和失敗。
  三.導致的WinCE啓動失敗的其它相關因素
  (1)驅動程序加載錯誤導致的失敗
  在調試中,我們還發現系統在啓動時執行到OEMInit
時也經常會出現錯誤。一般來說,系統調用OEMInit運行完成之後,就會跳回Private或
Public下的代碼繼續運行,然後再啓動device.exe
加載各個驅動程序。由於這一段代碼是微軟提供的default
代碼,基本上不會有問題。所以,我們就有理由懷疑如果加載的驅動程序出了問題,是也?
嵩斐上低稱舳О艿摹R話憷此擔廡┘釉氐那絛蛑饕?BSP中的Audio、Display
、SDMMC、Serial、USB等。
  (2)啓動時加載配置有誤的註冊表導致的失敗
  在WinCE中註冊表在啓動過程中也扮演着非常重要的角色。與桌面Windows一樣,
WinCE註冊表(Registry)也是一個系統數據庫,
用來保存應用程序、驅動程序、用戶的設定以及其它一些系統的配置信息,通常還存儲着?
僮饗低喫俗骱偷饔貿絛虻淖刺畔ⅰ@紓扛鮎沒У吶渲夢募滄暗撓τ貿絛蛞約懊?
個應用程序可以創建的文檔類型、文件夾和應用程序圖標的屬性表設置、系統上存在哪些?
布約罷謔褂媚男┒絲詰取?
因此,對於硬件外設來說註冊表是一個記錄驅動程序設置和位置的數據庫。當WinCE
系統在啓動時需要啓動某些必要的硬件設備時,就會需要使用外設驅動程序。但如果在
WinCE中這個外設驅動是獨立於操作系統的,WinCE
系統就需要知道從哪裏找到它們,例如文件名、版本號、其它設置和信息。因此,註冊表?
廈揮寫松璞傅募鍬際保薔筒荒鼙皇褂謾K裕弊⒉岜碓諂舳奔釉卮砦蠡蛘咦⒉岜?
配置有錯誤時,也是會導致WinCE系統啓動失敗的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章