新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > Windows CE內核啟動分析

        Windows CE內核啟動分析

        作者: 時間:2011-02-24 來源:網絡 收藏

        Windows CE內核啟動分析

        移植或者創建一個BSP,也許需要先熟悉Windows CE的內核啟動過程.

        目錄

        基于ARM的Windows CE內核啟動分析1

        1.startup.s2

        2.KernelStart2

        2.1 ARMInit()3

        2.1.1 OALIntrInit3

        2.1.2 OALTimerInit4

        2.1.2.1 Variable Tick Scheduler4

        2.2 KernelInit()4

        2.3 FirstSchedule5

        1.startup.s

        內核入口點startup.S,內核從這里啟動.因為內核經過bootloader加載,內核運行時候,已經由bootloader完成了硬件的基本初始化(關閉watchdog, pll設置等等)所以,startup.S的任務比較簡單,只是將oemaddrtab_cfg.inc里面的g_oalAddressTable數組地址作為參數,傳遞給KernelStart,這個數組用來描述和實現物理地址到虛擬地址的映射.

        (. + 8)是流水線處理.KernelStart()位于

        PRIVATEWINCEOSCOREOSNKKERNELARMarmtrap.s

        2.KernelStart

        ARMInit()位于本目錄的mdram.c文件.

        KernelInit()位于PRIVATEWINCEOSCOREOSNKKERNELkwin32.c中.

        FirstSchedule()位于armtrap.s的一個label.

        主要關注ARMInit()和KernelInit(),前一個進行目標板的初始化,后一個負責內核的初始化.FirstSchdule()開始調度第一個程序.

        2.1 ARMInit()

        先看看ARMInit()它的幾個關鍵性動作如下:

        KernelRelocate()是進行重定位.KernelFindMemory()是查找系統可用內存,并分成應用內存和object store兩部分.這2個函數都已由MS自己實現.我們需要添加的函數是名字以OEM開頭的函數.

        OEMInitDebugSerial()初始化一個調試口,我們一般使用一個串口來作為調試口,這個函數需要自己實現,在 PLATFORMSMDK2440ASrcKernelOaldebug.c中定義這個函數.比如可以將串口0設置為調試口,在這個函數中對串口0進行初始化.

        OEMInit()是一個比較重要的函數,

        OALCacheGlobalsInit()在PLATFORMCOMMONSRCARMCOMMONCACHEinit.s中實現,這部分代碼以PQOAL的形式提供.

        OALIntrInit()初始化中斷.

        OALTimerInit()初始化定時器TIMER4,作為系統時鐘(tick),

        configGPIO()初始化gpio口,設置相關寄存器.

        InitDisplay()初始化LCD.有時候,我們希望在oal啟動和內核加載期間顯示一副等待圖片或者顯示LOGO,為達到這個目的,需要先初始化LCD.

        OALKitlStart()準備啟動KITL.

        此外,在ARMInit還會通過調試口打印一些基本信息,開始時候打印”Windows CE Kernel for ARM….”字樣, 中間打印處理器類型等等信息.結束時候打印” ARMInit done.”

        2.1.1 OALIntrInit

        調用OALIntrMapInit()初始化2個數組g_oalSysIntr2Irq,g_oalIrq2SysIntr,這2個數組表征irq和邏輯中斷SysIntr的映射關系.

        然后初始化中斷寄存器,

        最后,留一個接口給oem: BSPIntrInit(),如果oem需要在這個階段初始化一些中斷,可以定義這個函數并實現.

        2.1.2 OALTimerInit

        這個函數比較重要. 都知道所有WinCE系統都需要一個定時器來提供一個heartbeat,

        g_oalTimer包含各種系統時鐘相關的變量.

        curridlehigh, curridlelow,這2個32位的DWORD變量合起來實現一個64位的計數器,反映了系統處于空閑模式(Idle mode)的時間。一般在OEMIdle()函數內更新。用戶程序通過調用GetIdleTime()函數可以得到這個值。

        初始化內核函數指針:pQueryPerformanceFrequency, pQueryPerformanceCounter.通過這兩個函數實現高精度的計時器. 這兩個函數的原型也已經由PQOAL實現.

        初始化TIMER4作為系統時鐘.TIMER4是一個16bit的定時器.此函數將TIMER4設置成為自動轉載模式.

        2.1.2.1 Variable Tick Scheduler

        可變的系統時鐘節拍,這個是WinCE5.0中增加的新的性能.

        每一次定時器中斷時候,內核分析所有線程后決定切換到哪個線程運行.假如所有線程都在等待狀態,系統將進入idle狀態.在這個狀態的時候,任何中斷都會喚醒系統重新開始調度.一般系統大部分時間是處于idle狀態的,內核會調用OEMIdle()進入idle狀態,我們已經知道這個狀態會被任何中斷喚醒. 在以前的版本中,系統中斷(即上面的TIMER4中斷)每毫秒產生一次,查看系統是否需要重新調度. 為了節電,不希望中斷那么頻繁.于是WinCE5.0中,在調用OEMIdle()之前會先調用pOEMUpdateRescheduleTime().通過這個函數重新設置俠義次系統時鐘中斷的時間.

        2.2 KernelInit()

        再看看KernelInit()函數

        不過多關注KernelInit().

        2.3 FirstSchedule

        位于armtrap.s的一個label.開始第一個線程調度.整個內核開始運行.


        linux操作系統文章專題:linux操作系統詳解(linux不再難懂)


        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 宣汉县| 锦屏县| 三穗县| 曲沃县| 绥中县| 兴业县| 乐平市| 仪征市| 龙里县| 龙胜| 西贡区| 民权县| 邹城市| 峨眉山市| 井研县| 日照市| 浙江省| 正定县| 太白县| 颍上县| 普兰店市| 泗水县| 克拉玛依市| 九台市| 临高县| 长岛县| 镇安县| 吉林市| 奉节县| 出国| 叙永县| 德令哈市| 商河县| 尼勒克县| 济南市| 文登市| 清远市| 城口县| 遵义市| 东方市| 清新县|