Windows CE 6.0 啟動過程分析

來源:互聯網
上載者:User

在理順了上述檔案的相互之間的關係之後,再來分析Windows CE 6.0的啟動過程可能就比較容易啦。
      1、Startup函數:
      從Windows CE 6.0的協助文檔可以看出,WinCE6.0的啟動只與oal.exe和kernel.dll有關,至於kitl.dll,只有將作業系統編譯成具有 KITL功能時才用到。分析Windows CE 6.0的啟動過程實際上找到編譯oal.exe和kernel.dll的源碼位置。
oal.exe的通過Startup函數完成硬體的初始化。Startup.s代碼與該硬體平台的Bootloader啟動代碼共用,其中PreInit 函數主要完成將ARM處理器工作模式切換到管理員模式、同時關閉MMU,並檢測系統啟動原因,如果是暖開機、即在該函數調用之前已經啟動了 Bootloader程式,相當基本硬體初始化已經完成,則直接跳轉到OALStartUp函數中;否則需要進行硬體中斷屏蔽、記憶體、系統時鐘頻率、電源管理等硬體的基本初始化過程。
     2、OALStartUp函數:
     在系統硬體初始化完畢之後,Startup調用OALStartUp函數,OALStartUp函數主要完成將OEMAddressTable表傳遞給核心;然後調用KernelStart函數跳轉到核心  OEMAddressTable表的主要作用表的每一個入口都定義了一個記憶體中的物理位置、記憶體的大小以及映射這物理地址的靜態虛擬位址;
    ◆靜態虛擬記憶體地址被定義在緩衝儲存空間的範圍之內;
    ◆核心可以建立非緩衝的記憶體位址指向到相同的物理地址;
    ◆對於同一物理地址,既有一個緩衝的虛擬記憶體地址,也有一個非緩衝的虛擬記憶體地址;
    ◆OEMAddressTable最後必須以0結尾;
    ◆對於MIPS和SHx類型的CPU,物理地址與虛擬位址的映射由CPU完成,無需建立OEMAddressTable;
    3、KernelStart函數主要作用:
    ◆完成OEMAddressTable表中的物理地址到虛擬位址和虛擬位址到物理地址之間的映射;
    ◆對儲存空間頁表和核心參數區儲存空間(RAM或DRAM)進行清零處理。
    ◆讀出CPU的ID號,核心需要根據該ID決定ARM的MMU處理,因為ARMV6和ARMV6之前的ARM處理器的MMU處理過程有所區別;
    ◆設定並開啟MMU和Cache,因為在Startup函數關閉MMU和Cache;
    ◆設定ARM處理器工作模式的SP指標,ARM處理器共用7種不同的工作模式(USER、FIQ、IRQ、Supervisor、Abort、 Undefined、System),除使用者模式(USER)和系統模式(System)之外,其他5種工作模式都有具有特定的SP指標寄存器(ARM處理器稱其為影子寄存器);
    ◆讀取核心啟動所需要的KDataStruct結構體;
    ◆調用ARMInit函數重新置放Windows CE核心參數pTOC和初始化OEMInitGlobals全域變數;
    ◆利用mov pc, r12指令跳轉到kernel.dll的入口位置,即NKStartup函數中。
    5、NKStartup函數:
    硬體平台初始化完成後,oal.exe的啟動任務基本完成,餘下的啟動工作由核心相關且獨立於核心的OAL層實現體kernel.dll接管。kernel.dll主要作用:
   ◆從結構體參數KDataStruct * pKData提取核心啟動時所必須的全域變數,同時初始化核心全域變數;
   ◆定位對Windows CE 6.0特有的OEMGLOBAL結構體的初始化函數OEMInitGlobals地址,該結構體構建了核心和OAL層之間進行通訊的橋樑。在 OEMGLOBAL結構體定義了OAL層所必須的函數,該結構體在oemglobal.c檔案中被初始化,並被編譯在OEMMain.lib和 OEMMain_StaticKITL.lib兩個庫中,如果OAL連結這兩個庫,則必須要有該結構體中函數實現體;
   ◆通過調用ARMSetup設定物理地址和非緩衝的虛擬記憶體地址的映射、ARM中斷向量以及核心模式所需要的堆棧。
   ◆調用OEMInitDebugSerial函數初始化調試串口;
   ◆調用OEMInit進行平台初始化;
需要注意的時,NKStartup函數調用OEMInitDebugSerial和OEMInit函數的過程與Windows CE 6.0之前的版本完全不同,這是因為在Windows CE 6.0以前的版本中,由於核心(kernel)、OAL和KITL編譯在一個可執行檔檔案中,它們之間的共用變數只需簡單利用extern關鍵字申明便可相互之間進行訪問,而在Windows CE 6.0中,由於核心(kernel)、OAL和KITL被編譯成不同的可執行檔,變數之間的相互訪問無法使用extern關鍵字實現共用,即核心無法使用extern DWORD varX方法訪問OAL層的變數varX,當然OAL層的實現體同樣無法通過同樣的方式訪問核心變數。為實現核心和OAL訪問共用資訊,Windows CE 6.0定義了OEMGLOBAL和GLOBAL兩個結構體。
在 Windows CE 6.0的核心啟動時,OS找到OAL的入口位置,然後調用入口函數與全域塊進行指標交換,這樣核心才能使用OAL層中的資訊,同樣OAL層才能訪問核心(kernel)匯出的函數。
   所以上述兩個函數的調用實際上通過OEMGLOBAL結構體實現的。實際調用位置為$(_PRIVATEROOT)/winceos/coreos/nk /oemstub/oemstub.c中的OEMInitDebugSerial和OEMInit,這兩個函數中通過OEMGLOBAL結構體指標訪問 OAL層中的OEMInitDebugSerial和OEMInit。
調用KernelFindMemory()函數分割RAM地區,在Windows CE作業系統中,RAM空間主要分為儲存記憶體和程式記憶體,儲存記憶體主要為檔案的儲存空間,包括核心檔案和複製到系統中所有目標檔案,程式記憶體為運行程式時所需要的儲存空間。
   ◆KernelStart ()啟動核心。
   6、KernelSstart函數:
這裡的KernelStart函數與前面的KernelStart函數的屬於兩個完全不同的函數,NKStartup函數中調用的KernelStart 函數為$(_PRIVATEROOT)/WINCEOS/COREOS/NK/KERNEL/ARM/armtrap.s檔案中的KernelStart 函數,主要完成調用核心初始化函數KernelInit,並跳轉到作業系統的第一個啟動的任務。
   7、KernelInit函數:
Windows CE 6.0的核心初始化函數同其他版本的核心初始化函數基本相近,主要完成在啟動第一個線程前對核心進行初始化,主要包括API函數集初始化、堆的初始化、初始化記憶體池、進程初始化、線程初始化和檔案對應初始化等操作。
   8、FirstSchedule:
FirstSchedule函數為Windows CE作業系統啟動過程中最後無條件跳轉的一個函數,windows CE進行第一個調度,實際為一個空閑線程,因為windows CE系統還沒有完成啟動,只有當windows CE完全啟動並進入穩定點,然後開機檔案系統filesys.dll,裝置管理device.dll,表單映像子系統gews.dll和shell程式 explore.exe.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.