• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 74, 文章 - 0, 評論 - 26, 引用 - 0
            數據加載中……

            wince6.0移植之oal 轉

            [克隆BSP]

            Clone一個BSP.

            WinCE6.0安裝armv4i架構后,里面提供了一個名字為DeviceEmulatorBSP. 這個BSPs3c2410BSP.我的是s3c2440a,就克隆這個吧.

             


            [移植OAL]

            WinCE5.0OAL是編譯成為一個靜態庫oal.lib,然后與內核nk.lib靜態編譯成kernel.exe,也就是nk.exe. WinCE6.0OALkernel中剝離出來單獨編譯成為oal.exe,內核則編譯成了Kernel.dll. 分離的代價是不能再直接使用相互的資源了,即相互間的全局變量和函數不能直接訪問了. OEMGLOBAL NKGLOBAL2個結構體充當了OALKernel的接口橋梁. 分離的好處是更方便內核獨立升級(嗯哼~ 這在將來會發生么?設備的架構可是千差萬別的.我想替內核升級最有可能的還是OEMs,不是MS),不過另外一個好處是接口更清晰了,內核會需要哪些OEM函數顯得更直觀明了.

            內核的啟動和原來略有不同了,簡單回顧WinCE5.0的內核啟動過程:

            [NK.exe=Kern.exe]

            StartUp()                      [ OAL入口點]

                 KernelStart()                  [ kernel入口點]

                          ArmInit()

                                     OEMInitDebugSerial()

                             OEMInit()

                       KernelInit()

                           HeapInit()

                           InitMemoryPool()

                           ProcInit()

                           SchedInit()

                         FirstSchedule()                             

             

             
             

             

             

             

             

             

             

             

             

             

             

             

             


            下面是WinCE6.0的內核啟動過程:

             

             

             

             

             

             

             

             

             

             

             

             

             

             

             

             

             

             

             

             


            OAL不能調用內核的KernelStart()函數了, 所以自己要實現一個KernelStart() (nkldr.lib替我們完成了這個, nkldr.lib鏈接到OAL),調用nkldr.lib中的KernelStart().然后執行的ARMInit()函數有一個很重要的任務,它將位于OALOEMinitGlobals()函數指針賦值到Kdata, 后面內核需要這個指針.接下來根據Kdata找到并跳轉到內核kernel.dll的入口點NKStartup().

            Kernel.dll開始執行NKStartUp(),首先要把和OAL的橋梁打通.也就是把內核的NKGlobal數據結構指針交給OAL,并且獲得OALOEMGlobal的數據結構指針. 怎么實現的? 內核根據Kdata找到OAL中一個函數OEMInitGlobals()  還記得嗎,前面說到OALARMInit()曾經鄭重的把OEMInitGlobals函數指針賦值給了Kdata,就是為了這一天... 然后,NKGlobal指針作為參數執行這個函數, 這個函數返回OALOEMGlobal的指針.(嗯哼~ OAL要實現OEMInitGlobals(), oemmain.lib替我們完成了這個,oemmain.lib鏈接到OAL).

            這個Kdata是個什么玩意? 它是內核數據結構, 簡單理解成共享內存好了, oal kernel都可訪問到.再往后沒啥好說了,內核可以訪問OAL,痛快的調用OEM函數,和以前WinCE5.0差不多. 最后調用KernelStart(),這回這個函數可是在內核里面了,WinCE6.0起來了……

            這個流程和WinCE5.0有點點差別.都是因為OALkernel分離了.

            [編譯OAL]

            空談了這么久,來做實質性的工作吧,開始編譯WinCE6.0OAL. 微軟希望它的設計使得移植OAL時候盡可能少工作量,所以oal.exe2個步驟來實現.第一步:編譯oal.lib.第二步:編譯oal.exe. 第一步的oal.lib可以就是原來版本的,你拷貝原來的oal目錄代碼到OALLIB目錄編譯一個oal.lib.關鍵是第二步,原來在WinCE5.0時候,oal.lib+nk.lib編譯成了kern.exe,然后改名成nk.exe.現在,要把oal+nkstub.lib,編譯成oal.exe.nk.lib也不是說不要就可以直接不要的.在編譯oal.lib時候可是大量使用了nk.lib的東東. 你不會想全文重新改變函數和變量的調用形式吧? ok,nkstub.lib鏈接上.這么一來, OALEXE目錄下的SOURCES文件里面,4個庫被添加進來.

              TARGETLIBS= oal.lib oemmain.lib nkldr.lib nkstub.lib ……(路徑省略)

            Nkldr.liboemmain.lib是干嗎的?回溯前面的啟動過程吧. nkldr.lib提供了KernelStart()的實現, oemmain.lib提供了OEMInitGlobals()的實現.當然還有更多的,不羅列了.

            [定制OAL]

            沒有oal.lib咋辦?做一個吧……前面提到OALKernel分離,使得接口更加明顯了,kernel到底需要OEMs提供哪些函數,可以參照著oemglobal.h文件里面OEMGLOBAL結構體來完成.并且在oemglobal.c里面對這個結構體初始化.這個文件位于oemmain.lib.發揚愚公移山的精神,我來抽絲撥繭一下,下面根據我的2440來分析最重要的必須的幾個接口:

            [Init相關接口]

            要提供OEMInit(), OEMInitDebugSerial(),

            OEMInit()函數,建立一個init.c,然后實現這個函數.

            OEMInitDebugSerial()放到下面debug.c中實現.

            [Debug相關接口]

            OEMWriteDebugString

            OEMInitDebugSerial

            OEMWriteDebugByte

            OEMReadDebugByte

            OEMWriteDebugLED

            PQOALoal_other.lib提供了OEMWriteDebugString(),

            OALLIB下創建debug.c ,然后實現OEMInitDebugSerial, OEMWriteDebugByte, OEMReadDebugByte, OEMWriteDebugLED4個函數.

            [Cache相關接口]

            需要提供OEMCacheRangeFlush, 根據自己的架構去已有的PQOAL找吧,我的是oal_cache_arm920t.lib

            [Time相關接口]

            需要提供

            InitClock

            OEMGetRealTime

            OEMSetRealTime

            OEMSetAlarmTime

            OEMQueryPerfCounter

            OEMQueryPerfFreq

            OEMGetTickCount

             

            InitClock,這個功能已經廢除了, 相關功能被移到OEMPowerOff.所以可以實現一個空函數,在初始化OemGlobal時候,把這個指針賦值RetuanFalse()函數也是一樣的效果.OEMGetRealTime ,OEMSetRealTime是設置讀取rtc的日期功能.OEMSetAlarmTime是設置rtc的報警時刻,找到oal_rtc_s3c2440a.lib

            OEMQueryPerfCounter,OEMQueryPerfFreq是提供更高精度時間的查詢,

            OEMGetTickCount返回當前CurMSec,系統運行了多少毫秒.oal_time.lib中已經有實現.特別強調的是,這個函數在WinCE5.0里面是SC_GetTickCount.需要把名字改了.這個是OAL的一個區別.

            [Scheduler相關接口]

                   OEMIdle, OEMNotifyThreadExit, OEMNotifyIntrOccurs, OEMUpdateReschedTime, 一個變量DefaultThreadQuantum.

            [power相關接口]

            OEMPowerOff, 這個還要說啥, 掛起時候會執行這個函數. PQOALoal_power_s3c2440a.lib已經幫忙實現了最基礎的工作,會調用BSPPowerOff來完成平臺相關的動作,建立一個文件power.c來實現這個BSPPowerOff.

                                       

            [DRAM相關接口]

                   OEMGetExtensionDRAM, OEMEnumExtensionDRAM, CalcFSPages, 變量MainMemoryEndAddress

            這組函數詢問擴展RAM的情況,如果OEMEnumExtensionDRAM函數提供了, 就執行這個函數,否則執行OEMGetExtensionDRAM, CalcFSPages計算pages, 這個功能內核自己實現了,已經不要了,指向一個空函數即可.

            [interrupt相關接口]

            OEMInterruptEnable, OEMInterruptDisable, OEMInterruptDone,

            OEMIniterruptMask,OEMInterruptHandler

                   基本工作PQOAL已經做好了,PQOAL下面幾個接口完成平臺相關工作,BSPIntrInit, BSPIntrRequestIrq, BSPINtrEnableIrq, BSPIntrDisableIrq, BSPIntrDoneIrq, BSPIntrActiveIrq.最后一個OEMInterruptHandler就是系統ISR, 將物理irq轉換成邏輯中斷SYSINTR_XXX.

            [other ]

                   OEMIoControl .PQOAL里面已經實現了這個功能.如果OEMs要添加新的控制命令, 建立一個ioctl.c,定義一個全局數組g_oalIoCtlTable, 然后往數組里面填入命令字和對應命令執行的函數的名稱.這個對應命令的執行函數當然要自己實現了. 驅動或者應用使用KernelIOControl這個api時候,相應命令的函數就會執行.

            [總結]

            1.WinCE6.0不只是將OALkernel分離.還將kitl也分離成為了kitl.dll. 所以,OAL也不能直接使用kitl的資源. 首先把kitl.ckitl相關代碼從OAL里面給放到kitl目錄去.然后在OEMInit中不能調用OALKitlStart(),KITLIoctl(IOCTL_KITL_STARTUP, NULL, 0, NULL, 0, NULL);這一句來替代.

            2.OAL需要使用的數據結構定義,和外部函數聲明都在頭文件nkexport.h.可以在oal.hinclude這個nkexport.h頭文件.

                   3. PQOALoal_log庫有了變化,如果使用了這個庫的要注意,它不在使用g_oalLogMask這個全局變量了.

            4. timertimer_dvs目錄下的watchdog.c文件和nkexport.h中重復定義了pfnOEMRefreshWatchDog,dwOemWatchDogPeriod.一個解決辦法是去掉watchdog.c.反正也可以不使用這個接口.默認傳過去的是空接口ReturnFalse()

            5. 編譯smflash.dll出錯,需要fal.lib一起編譯成為smflash.dll. fal的源代碼位于private\winceos\driver\msflash\src.這個fal.lib.好像和以前的不一樣.從錯誤信息中觀察,好像多出來2個接口.fmd.cpp里面增加這2個接口:

            LPVOID FMDHOOK_HookInterface(PFMDInterface pInterface)

            { return (LPVOID) pInterface;}

            Void FMDHOOK_UnhookInterface(LPVOID pContext, FMDInterface *pInterface){}

            至此, 在給oal加上一個啟動代碼startup.s. 一個oal.lib就完成了.

            posted on 2008-11-12 10:19 井泉 閱讀(1050) 評論(0)  編輯 收藏 引用

            国产精品内射久久久久欢欢| 国内精品久久久久久久涩爱| 久久精品国产亚洲一区二区三区 | 99国内精品久久久久久久| 精品久久久久久无码专区不卡| 国产精品一久久香蕉国产线看 | 久久九九久精品国产免费直播| 久久久久无码国产精品不卡| 精品综合久久久久久97| 日本精品久久久中文字幕| 久久精品综合网| 中文字幕久久欲求不满| 亚洲а∨天堂久久精品| 亚洲AV日韩AV永久无码久久| 国产成人AV综合久久| 无码专区久久综合久中文字幕| 日本免费一区二区久久人人澡| 无码国内精品久久综合88| 久久91亚洲人成电影网站| 精品久久人人爽天天玩人人妻| 国产激情久久久久影院老熟女| 亚洲AV乱码久久精品蜜桃| 久久精品成人免费观看97| 精品一区二区久久| 老色鬼久久亚洲AV综合| 久久精品国产亚洲AV香蕉| 久久93精品国产91久久综合| 精品一区二区久久久久久久网站| 99精品久久精品一区二区| 久久亚洲精品国产精品婷婷| 久久精品夜色噜噜亚洲A∨| 久久99毛片免费观看不卡| a高清免费毛片久久| 99久久精品午夜一区二区| 久久亚洲中文字幕精品有坂深雪| 香蕉久久夜色精品国产尤物| 久久青青草原亚洲av无码| 久久影视国产亚洲| 色综合久久天天综线观看| 久久久人妻精品无码一区| 久久精品国产亚洲Aⅴ蜜臀色欲|