文件wince雜談1 WindowsCE下流驅動的動態(tài)加載_第1頁
文件wince雜談1 WindowsCE下流驅動的動態(tài)加載_第2頁
文件wince雜談1 WindowsCE下流驅動的動態(tài)加載_第3頁
文件wince雜談1 WindowsCE下流驅動的動態(tài)加載_第4頁
文件wince雜談1 WindowsCE下流驅動的動態(tài)加載_第5頁
已閱讀5頁,還剩273頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、WindowsCE驅動的動態(tài)加很多WinCE的開發(fā)人員,尤其是剛并且做驅動開發(fā)的工程師,都曾碰DLL打包到先前做好的操作系統(tǒng)映像當中,最簡單也得MakeImg一下,還要修改BIB文件、表文作上。這種調試驅動的方法實在效率太低了。想到Linux下面的驅動調試,多方便!直接INSMOD一下,應用程序就可以調用,出現(xiàn)問題就RMMOD,根本無須來回倒騰操作系統(tǒng)的映像文件。那么,WinCE下難道就沒有這么簡便的方法閑話少說,進入正題。查找ECtivtevic(可用tivteDvicEx(。HANDLEActivateDevice(LPCWSTRlpszDevKey,DWORDdwInfo[in]Pointertotheregistrypathstringofthedevice'sdriverkeyunderHKEY_LOCAL_MACHINE.AdriverkeycontainstheDLLname,thedeviceprefix,friendlyname,andotherdeviceinformation.dw[in]Datathatwillbestoredinthedevice'sActivekeyintheInfovalue.Theregistrypathtothedriver'sActivekeyispassedinasthecontextparametertothedevice'sXXX_Initfunction.ThevalueindwInfoisstoredintheregistrybeforeXXX_Initiscalled.ReturnOnsuccess,ActivateDevicereturnsahandletothedevicethatcanbeusedinsubsequentcallstoDeactivateDevice.ThisfunctionissupersededbyActivateDeviceloadsadevicedriver.ActivateDevicereadstheregistrykeyspecifiedinlpszDevKeytogettheDLLname,deviceprefix,index,andothervalues.NextitaddsthedevicetotheactivedevicelistintheregistrybranchHKEY_LOCAL_MACHINE\Drivers\Active,andstorestherelevantvaluesthere.IfnodeviceindexwasspecifiedinthekeynamedinlpszDevKey,thenitassignsaindex.ThenitloadsthedevicedriverDLLintheprocessspaceoftheDeviceManager.ThenitbroadcastsaWM_DEVICECHANGEmessageforthenewdeviceandtriggersNOTIFICATION_EVENT_DEVICE_CHANGEeventintheapplicationnotificationsystemtonotifyapplicationsofthepresenceofthenewdevice.,而這個參數(shù)是表中的一個路徑字符串。所以,要想很方便的動態(tài)加載任意一個驅動,我們還要了解一下有關表的內容。但其中最的就是一條驅動的相關表信息放到HKEY_LOCAL_MACHINE下主要內容包括Prefix、DLL、Index、Order等信息。這里就不展開說明了。,我們假設已經(jīng)做好一個簡單的流驅動DrvDemo.dll,其對應的表文件為DrvDemo.regDrvDemo.exe。我們把這三個文件和驅動調試助手(DM.exe)WinCE系統(tǒng)上,如下圖所示。首先運行DrvDemo.exe,點擊打開設備,或者其他按鈕,我們發(fā)現(xiàn)打開設備失DrvDemo.dll還沒有工作呢。.x表,瀏覽到我們準備好的表文件rvDmo.rg,選中并點擊K按鈕,rvDmo.rgDrvDemo.exeDLLDLL覽到我們準備好的DrvDemo.dll文件在彈出的框中設置正確的PrefixOrder、Index怎么樣,這種方法就很類似于Linux下的InsmodRmmod其實,如果在表中已經(jīng)有了相應的鍵,你甚至可以直接選中它,然后在效果,但這樣就連導入文件都省了。有的可以自己試一下。從此擺脫不斷MakeImgDownload的夢魘,節(jié)省很多寶貴的開發(fā)時間。WinCE4.2中,有關中斷的驅動是無法直接用此方法來動態(tài)加載的,而5.06.0WinCE4.2中的中斷處理機制所致。驅動調試助手可以同時加載幾個驅動,這時候建議將所有表信息寫到驅動調試助手中的表編輯功能經(jīng)幾番修改已基本完善編輯IE-E的表修改。于用戶態(tài)的驅動也可以通過該方法加載,但是需要設定相應的表信息。手可以 /we-hjb/WINCEDM.rar到一起學習WindowsEmbedded。最后,希望不要被認為是“性質的文章。2、單機搭建WinCE沒有時間調,所以只能回家做,可家里又沒實驗板。好在WindowsCE是有模擬題,不過都一一解決了,寫出來跟大家一下。最早主機上已經(jīng)安裝了EVC4+SP4,VS2005+SP1+tformBuilder6.0+R2等WindowsCE的主要開發(fā)工具。既然沒有實驗板,那就定制一個中文的WinCE6.0的操作系統(tǒng),再導出SDK,這不就解決了板子的問題嗎?思路是對了,可一動手就發(fā)現(xiàn)有問題。PB6.0MFC的支持。而目前很多程序都是基于MFC的這要調試MFC的程序可怎么辦?想了,系統(tǒng)要支持MFC,其實就是要DLLMFC相關的幾個DLL加到NK.bin中不就行了?在ProgramFiles\VisualStudio8\VC\ce\Dll\armv4的MFCDLLMFC,只是想讓大伙少用把這幾個DLL拷貝到BSP對應的下并修改tform.bib文件。第一個問題順利解決。MFC加進去了,.NETCompactFramework那更是必須選問題是系統(tǒng)啟動后得自己去創(chuàng)建接,還要修改”PC連接”的選項才能用。冊表信息導出來,放到tform.reg里去,這樣重新編譯完的系統(tǒng)就能直接使用ActiveSyncActiveSync,讓DMA的連接方式。該導出SDK了。在導SDKMFC也沒有相關選項的支持。這不又SDKMFCVS2005MFC編寫設備的程序。得想辦法把MFC加進來。還是在ProgramFiles\VisualStudio8\VC\ce\的下面有一個atlmfc的。這里面包括了MFC對應的頭文件和庫。在定制SDKAdditionalFolders中添加相關的項,最后編譯安裝,MFC時只選擇armv4I的,要全部選可有好幾百至此,我們就在單機上搭建好了完整的WindowsCE的開發(fā)環(huán)境,不光是裝了很多開發(fā)軟件,連硬件都有了!很多想學WindowsCE開發(fā)的學生就不用費心費力費錢去選板子,暫時用模擬器做的學習也是個不錯的選擇。 /we-hjb/WINCE6.0CHSEMU.rar有WinCE6.0中文模擬器SDK的使用方法和實驗的效果。Devicetextconsolwindow來模擬。我們VS2005EVC來編寫程序,通過文件共享放到WinCE6.0的模擬器中去執(zhí)行,添加打印信息的調試方法在這里也可以使用。另外,文中定制的SDK可以在這里到VS2005+PB6.0VS2008的。機器也支持同步。在使用模擬器的過程中發(fā)現(xiàn)一個小技巧。如果從DeviceEmulatorManager中連接到該模擬器,則每次都必須重新設置網(wǎng)絡和共享等內容。這點擊“屬性”后彈出的框如下圖所示,點擊“仿真器選項,進行配置,就不一一介紹了,根據(jù)自己的需求進行設定。配置完成以后,下次再從Device在調試程序時,難免要用到工具。前段時間在調試2410開發(fā)板的WinCE6.0接。但測試發(fā)現(xiàn)根本不行,截圖如下,提示說”UnabletoloaddevicesideEVC4.0RemoteToolsWinCE5.0的設備時也出現(xiàn)這樣的情況。難道是RemoteTools6.0的,這太C:\ProgramFiles的下看到過一個CERemoteTools的,這里面放的應該也是工具吧。進去看看,果然有幾個。但比C:\ProgramFiles\CommonFiles\Shared\WindowsCETools\tman\bin\wce500下的少多了文件名也不大一樣不是以CE打頭而是用CC打頭打開看看再說,連接,等待,DownloadingBitmap,果然可以!再比較一下這兩個版本到底哪里ActiveSync或者網(wǎng)絡進最后補充說明一下,你可以從開始\程序\ VisualStudio2005\VisualStudioRemoteTools中找到這個能用的6.0版的RemoteTools。所以是否說明(3)(3)通過前兩篇的介紹,我們已經(jīng)搭建了WinCE開發(fā)環(huán)境,并了解了如何使用工具進行相關調試。這一篇,我們進一步完善單機搭建的WinCE開發(fā)環(huán)境——在WinCE6.0的模擬器中使用串口。WinCE設備中串口的使用頻率是相當高的,一般有一個調試串口,而很多實際應用中與GPS、GSM(GPRS)模塊的通信都是通過串口來進行的。在第一篇中,紹過為調試串口創(chuàng)建一個TextConsolWindowVS2005發(fā)布的6.0的RemoteTools是真的可用的6.0版本而隨tform6.0不管怎樣,我們在單機上搭建的WinCE來調試GPS、GSM模塊的程序了了。今天便在VS2008中安裝了一下WinCE6.0中文模擬器的SDK,又遇到了一些小問題,貼出來跟大家一下,也算是對單機搭建WinCEOKRollBack了。重新試了兩遍,都是如此。難道VS2008不支持WinCE6.0 歉”。再Go一下,果然有6項相關的網(wǎng)頁。其中有一篇提到,在VS2008中安裝WinCE6.0的SDK時,不能完全安裝,必須選擇定制,并把.NETCompactFramework取消掉。 ation也取消掉,其他兩項NativeDevelopmentSupport和Common保留,竟然可以了!新建了一個MFC的工程,編譯 完全沒有問題,這證明VS2008確實是支持WinCE6.0應用程序的開發(fā)的!ToolsMsmCA(Error):IHxFiltersfilterregistrationfailure:Err= ,Context=pFilters->SetNameSapce(Namespace)ToolsMsmCA(Error):IHxRegisterSessiontransactionfailure:Err=0x 3、WinCE下的控WindowsCERemoteZoominRemoteZoominRefreshCE和PCPCCEWinCERDPCEWindowsXP,CE本身并不能做Server,只能做 初步分析了一下,為了實現(xiàn)這個功能,CE端需要做兩個事情,第一,實時PCPC端發(fā)過來令(主要是鼠標和鍵盤的消息命令)并模擬鼠標和鍵盤。而PCCE端發(fā)來的屏幕內容的BUF并將其顯示,第二是捕獲鼠標和鍵盤的消息并給CE發(fā)CEDIBPCStretchDIBits()顯示接收ColorData。這里唯一需要注意的就是在截屏時并沒有截取鼠標指針的信息,所以在截屏之后得手動畫上鼠標的指針。否則,PCCE 在CE端是很容易的,用mouse_event()和keybd_event()這兩個函數(shù)就足夠了。而PC端捕獲鼠標和鍵盤的消息則有兩種方法,方法一是在PreTranslateMessage中來做,方法二則是在各個消息處理函數(shù)中來做。這里需要注意一下,鍵盤的消息必須在PreTranslateMessage中Windows下的控制類軟件的思路是一樣的。接下來就考慮一些細節(jié)的問題。譬如通信的方式,EVC中的工具是可以通過ActiveSync來通信的,也可以用Ethernet。所以為了方便最好也能用這兩種方式。另外,如果在使用ActiveSync時,是否可以利用RAPI,直接CE仔細琢磨了一陣,發(fā)現(xiàn)這些需求都可以實現(xiàn)。把各部分都實現(xiàn)完了以后聯(lián)調,基本達到了預期的效果。但在CE分辨率較大時感覺有點遲鈍。所以又想優(yōu)化的方法?;旧嫌幸韵氯c,比較、分塊、壓縮。所謂比較,就是在CE屏之后做一個備份,再次截屏時將其與備份進行比較,如果不一致再發(fā)送,否則就不用發(fā)給PC做更新。分塊是可以和比較一起使用的,如果屏幕只是局部新,那可以只發(fā)送更新的塊,而其他塊則不發(fā)送。壓縮理論上是可以提高傳輸效率的。粗略的比較了一下,一張640*480的16Bit的位圖是600K,而壓縮之后的JPG 才幾十K,差別還是相當可觀的。這三種方法都能節(jié)省網(wǎng)絡帶CPU后來有一次,有人問起CE下的觸摸屏校準在哪里,CE同步的連接怎么建 專家的麻煩。于是,找了一個很方便用的從BMP保存為AVI的類,添加了錄屏功能。當然由于沒有壓縮,所以錄制的AVI文件WinCERMCUSBActiveSyncLCDEbootpowertoys,RMCEthernetUSBSOTI5.0RMC/we- 4、FoxitReaderV1.1forPXA270WinCE6.0WinCE6.0的強大,定制了一個增強型的操作系統(tǒng)但WinCE6.0中已經(jīng)不支持PDF等閱讀器了于是從上找PPCFoxitReaderWinCE6.0OS不支持,PPCFoxitReaderWindowsCE應用程序”是不一樣的。既然這樣,那說明程序還是運行起來了,只是檢測OS時出錯,所以才會出現(xiàn)如下圖所示的提示。想,如果讓程序跳過檢測OS,是不是就可以正常運行呢。滿懷著希望,用IDA反BEQB。UltraEdit0AEABEQB,再拷貝到設備上面去,果然可以運可以看到,上面的AboutFoxitReader框竟然沒有關閉的按鈕。這可怎么退出呢?重啟ECS退出的,只是覺得很不爽,得加個關閉按鈕。開始想IDAexescope就可以很輕松的達到這個效果,用exescope打開編輯了一下,再運行,關閉按鈕的出現(xiàn)了。嘿嘿,到這里就算成功了PPC版的FoxitReader,使其能在CE6.0上面運行。雖然這對點擊這 工欲善其事,必先利其器。做工欲善其事,必先利其器。做WinCE驅動的開發(fā)已有一段時間了,WinCE驅動調試助手也跟著更新了很多功能。現(xiàn)在只要做驅動,DM是必須用的。最近在調試WinCE6.0下的驅動,所以又針對WinCE6.0增加了新的功能,也修正了原來的一些先介紹一下WinCE驅動調試助手V2.5 PC上的方法一樣。這也是一個方便使用的功能。V2.5中新建鍵、值以及刪除、修改鍵值的功能都做了提示,盡量減少因誤操作而ID,方便開發(fā)者找出原因。動時,相當于按下了Backspace,向右滑動時,相當于按下空格。有點意思。V2.5的導入導出功能在WinCE5.0和6.0上測試,未發(fā)現(xiàn)問題,在4.2中測試4.2下有保留的使用吧。附帶的中演示了6.0下測試導出導 下的是,在導 總之, V2.5中新增了對系統(tǒng)啟動時加載的設備驅動的管理。這個功能類似與PC6.05.0中使用,4.2是不支持的。附帶的中演示了停用StorageCard設備的方法。該功能與先前的功能一起在驅動列表中操V2.5ERRORID,一般ID5.06.04.2上測試時,同時加載兩個以上設備的驅動,經(jīng)常會出現(xiàn)ErrorID0的情況,再試幾次又能ErrorID還是有一定的參考意義,而不象以前,只知道出錯 綜上所述,除了增加了設備管理器的功能外,V2.5的主要更新都是細節(jié)的完善, CE的開發(fā)者使用。WinCE驅動調試助手V2.5的 演 地 /we-博客園的件 空間用完了,所這中間版本已被清。請到這里 e-hjbWMrr6、驅動調試助手的今天發(fā) 的DM程序,在PPC上面不能正常運行,截圖如下每個主鍵下只打開了一個子鍵。而TREAdditionally,thesystemprotectsasetofregistrykeyssothattheycannotbemodifiedbynormalapplications.Allapplicationscanreadallregistrykeysandvalues,butonlyprivilegedapplicationscanmodifyvaluesorsubkeysbelowprotectedkeys.Thesystemprotectsabasesetofkeys.ThissetofkeysisextensiblebytheoriginalequipmentGetCursorPos()PPC上似乎是不支持這個API的,用()替換掉該API不光是PPC上會有這個問題,在某些特定的WinCE系統(tǒng)上(沒有包涵GWES_CURSORORGWES_MCURSOR組件)也會存在這個問題,只是自己平時定BUG。這里又涉及到一個問題,如何確定一個程序能否在特定的WinCE系統(tǒng)上正常運行。因為WinCE系統(tǒng)是一個非標的操作系統(tǒng),它對API的支持在定制系統(tǒng)時就決定了。關于這個問題,有時間Report,方便開發(fā)者判斷需要在定剛剛去書店轉了一下,發(fā)現(xiàn)已經(jīng)有介紹WinCE6.0還有一本是《EVC高級編程及應用開發(fā)》的升級版,基于VS2005WinCE系統(tǒng),通過修改表,了開機運行explorer.exe,直接運行自己的程序。所謂可沒有任何問題,只是S沒運行而已。外接鍵盤根本無法輸入以致進入不了系統(tǒng)的問題他想到用RMC來輸入,可沒想系統(tǒng)也不支持。這主要是因為他的車載GPS系統(tǒng)根本沒有鍵盤的驅動。這個問無法輸入。當時的解決辦法就是重新燒系統(tǒng),很冤。其實,這個問題的關鍵就在軟鍵盤OK了?為了解決客戶和linsk碰到的問題,修改了一下RMC的程序,增加了控制設備端軟鍵盤顯示和啟動設備S 的功能。只要能同步上,PC就能控制CE了。后,點擊S 按鈕,設備進入WinCE系統(tǒng),接下來可以怎么調試都行。當然,如果是忘記了,那還真是件麻煩事。簡單試了一下NTLM的幾個函數(shù),雖然文中提到的RMC的地址 8、S3C2410處理器支持將啟動代碼 在NANDFlash中。為了實現(xiàn)這 2410配備了一個名為“Step stone”的內部SRAM。在啟動時,NANDFlash中第一個4K字節(jié)的內容將被加載到Step stone中并執(zhí)行。這個工作由MCU主動完成,而我們只需將NANDFlash配置為AutoBoot模式即可。 在NANDFlash中的內容至SDRAM中。在使用ECC校驗時,NANDFlash中數(shù)據(jù)的有效性將被確認。在完成拷貝的工作后,啟動代碼將跳轉到已加載到SDRAM中的主程序中,這時啟動代碼的使命完成,MCU由WinCE操作系統(tǒng)從文件的組成來看一般分為兩部分:BOOTLOADER和NK.bin。在WinCE中,BOOTLOADER一般為EBOOT。它的主要功能是初始化硬件設備,主要包括CPU內部的相關控制器、內存、網(wǎng)絡、串口甚至USB口和LCD。在初始化完成后,它將通過網(wǎng)絡或USB從外部 NK.bin,或從本地Flash中加載NK.bin并執(zhí)行,從而啟動WinCE操作系統(tǒng)??梢钥吹紼boot雖然是啟動代碼,但它得完成相當多的工作,最終的映像文件也將超過4K。所以,我們不能直接將Eboot存放在NANDFlash的第一個4K字節(jié)中。我們需要一個更小的啟動代碼,這就是通常所說的NBOOT(NANDBOOT)。通過上面的介紹,我們知道了NBOOTEBOOT加載到內存并運行。在EBOOT開始執(zhí)行后,NBOOT在NBOOT的代碼實現(xiàn)中 CPU內部相關控制器,如設置GPIO,關閉WatchDog,關閉中 初始化NANDFlash,因為在MCU啟動時默認是AutoBootNANDFlashEBOOTNANDFlashMode 址是跟EBOOT有關,介紹EBOOT時再詳細說明。完 一般來說,前面兩個功能在startup.s中實現(xiàn),WinCE6.0 tartup.s的相關代碼。后面四個功能可在main.c中實現(xiàn)??傊?,在實現(xiàn)必備功能的情況下,盡可能減少代碼量,以將最后的NBOOT4K以內。NBOOT的編譯環(huán)境一般有兩種,ADS1.2(或RVDS)、 tformBuilder。用ADS1.2編譯NBOOT是比較方便的,需要注意的就是ROBase和RWBase的設置,ROBase必須設置為0x0。否則,系統(tǒng)啟動時NBOOT將不被運行。在Post-Linker中選擇ARMfromELF,在Linker——ARMfromELF——OutputFormat inBinary,這樣,編譯完成后最終生成NBoot.bin。該文件就可以 NANDFlash的第0個BLOCK中。 tformBuilder6.0是作為VS2005的插件來用的,所以,我們現(xiàn)在也可以用VS2005來編譯NBOOT,這樣就免得再安裝ADS或RVDS等軟件。用VS2005來編譯NBOOT也有兩種方法,第一種跟編譯EBOOT映像文件類似,第二種是自己寫makefile文件,然后用命令行的方式調用ARM編譯 法在編譯OS時,會自動編譯生成映像,而第二種方法可由ADS下的程序直接移植過來,不過,要寫好makefile文件是相當困下面就介紹如何用VS2005來編譯NBOOT首先修改BSP 2410"SRC"Bootloader"的dir文件,添加 在bootloader下創(chuàng)建NBOOT ,并創(chuàng)建makefile、makefile.inc、sources、nboot.bib文件,也可從EBOOT的 !IF"$(NOLINK)"==romimage$(ROMIMAGE_FLAGS)!IFcopy$(_ EBUG)"nboot.*$(_FLATRELEASEDIR) ;

Memory; LDEFINES=-subsystem:native/DEBUG/DEBUGTYPE:CV startup.s\ 再將對應的代碼文件拷貝到NBOOTmain.c中需要添加一個全局變量的定義,這在ADS1.2的工程代碼中是沒有的,也//GlobalsROMHDR*volatileconstpTOC=(ROMHDR*)-否則,最終生成的Nboot.bin就只有一個文件頭。做完相關代碼的修改之后,就可以編譯NBOOT了??梢钥吹?,最終編譯生成了Nboot.bin、NBOOT.nb0、NBOOT.nb1、NBOOT.nb2。上面我們提到用ADS1.2編譯最后可用的NBOOT映像為NBOOT.binNBOOT.bin,但這里我們卻得用NBOOT.nb1。對比一下ADS下生成的和Nboot.nb1最后,再看一下反匯編nboot.exe的樣子,將其跟startup.s至此,我們就完成了用至此,我們就完成了用VS2005編譯得到NBOOT當然,S3C2410&&WinCE6.0也可以用Nor,直接用為一個新的硬件設備定制WinCE6.0操作系統(tǒng),一般需要完成以下幾個主要步驟 針對特定的硬件設備創(chuàng)建板級支持包(BoardSupportPackage縮寫為BSP),BSP必須包括BOOTLOADER、OEM適配層(OEMAdaptationLayer縮寫為OAL)和一利用創(chuàng)建的BSP,定制一個系統(tǒng)設計(OSDesign)通過VS2005創(chuàng)建一 tformBuilder的工程。該針對板上的設備創(chuàng)建相關驅動,并添加到BSP中 CatalogItems的方式,修改OS 編譯OSDesign,編譯得到的運行時映像文件到目SDK(SoftwareDevelopmentKit),應用程序的開發(fā)人SDK編寫該設備的應用程序??梢钥闯?,在整個WinCE操作系統(tǒng)的移植過程中,BSP關鍵的一步。而創(chuàng)建BSP 創(chuàng)建BOOTLOADER。BOOTLOADER在開發(fā)的過程中 創(chuàng)建OAL。OAL最終被到內核映像文件,它主要完 修改運行時映像的配置文件。配置文件主要包括BIB、REG等文件。BOOTLOADEROS的啟動程序處。它的這一作用跟前一篇介紹的NBOOT的作用完全一致。BOOTLOADER獲取運行時映像(NK)一般有兩種方法。它可以通過有線連接的方式象網(wǎng)絡(Ethernet)、USB或串口從外部NK。它也可以從本地的器(Flash、HardDisk)中加載NK。通常,BOOTLOADER通過Ethernet操作系統(tǒng)映像故將其稱為EBOOT。在開發(fā)的過程中使用EBOOT,可以提高開發(fā)效率。通過使用EBOOT,你可以很快速的NK到目標設備中。而利用Flash編程工具或者是通過JTAG則很慢。在一些產品最終發(fā)布時,EBOOT是以去掉的,但也有一些則必須包括BOOTLOADERX86 初始化MCU。包括初始化MCU的相關寄存器、中斷、看門狗、系統(tǒng)時鐘、內存和MMU。前面幾項跟NBOOT基本一致,但這里增加了對MMU的初始化。BootloaderMain()。這個函數(shù)的定義在WinCE6.0中對 必須由EBOOT的代碼來實現(xiàn)。最終跳轉到OAL.exe的StartUp處,進而啟動。這里針對S3C2410EBOOT做幾點說明。前一篇介紹NBOOT加載EBOOT的方法時提到,NBOOTEBOOT放在內存中指定的位置,這個位置是EBOOT的來決定的。具體的,在EBOOT中的體現(xiàn)是boot.bibNBOOT加載EBOOT到內存的地址必須與此地址對應。由于在NBOOT中沒有使用MMU,所以NBOOT使用的實際地址應該為0x 常啟動。第二點,如果沒有采用NBOOT加載EBOOT的方法,而是將EBOOT直在NORFlashEBOOT的代碼中實現(xiàn)自加載的過程,即將NORFlashEBOOTRAM中,并執(zhí)行,實現(xiàn)代碼如下:; Copybootloaderto r9,pc,#0xFF000000 ;seeifweareinflashorinram ;goaheadifwearealreadyinram;Thisistheloopthatperform r0,=0x21000 ;offsetintotheRAM r0,r0,#PHYBASE ;addphysicalbase r1, ;(r1)copy r2,=0x0 ;(r2)flashstartedatphysicaladdress0 r3, ;counter r4,[r2],#4 r4,[r1], r3,r3, ;RestartfromtheRAMpositionaftercopying.movpc,r0;Shouldn'tgethere.本文粗略的介紹了WinCE6.0EBOOT的內容,但沒有涉及具體的代碼實現(xiàn), 10、S3C2410下WinCE6.0通過前兩篇文章的介紹,我們已經(jīng)知道通過前兩篇文章的介紹,我們已經(jīng)知道NBOOTEBOOT,繼而EBOOTWinCENK)。那么,WinCE6.0呢?本文基于S3C2410WinCE6.0MCUS3C2410PXA270ARMMCU,所以他們的啟動過程是類似的,可以說唯一的不同就在OALWinCEOALOAL(OEMAdaptationLayer)即OEM適配層,它的主要作用是在移植WinCE到新的硬 減少操作系統(tǒng)的修改,通俗的說就是為WinCE操作系統(tǒng)抹MCUMCUOALOALOAL內核和設備硬件之間的一個代碼層,是一個抽象的概念。物理上,OAL和其他一些庫一 成可執(zhí)行文件,在WinCE6.0中對應的文件是OAL.exe,這是的客觀存在。WinCE6.0OALOALOAL.exe,而內核則變成了Kernel.dll單獨升級OAL。但整體的OALOEMOALKernelNKGLOBAL下圖所示為WinCE6.0OAL在移植WinCE到新的硬 ,創(chuàng)建OAL是最復雜的任務之一。一般來說,最簡單的方法是拷貝一個跟新的硬件平臺類似的且 OAL,然后從EBOOTOAL.exeOEMLaunch()開始的,函數(shù)OEMLaunch()中調用Launch(dwPhysLaunchAddr),LEAF_ENTRY r2,= r3,=(VIR_RAM_START- r2,r2,r1,;Disablep15,0,r1,c1,c0,pc,;Jumpto;MMU&cachesnow處對應的是NK.exe,而這里的NK.exe至此,我們已經(jīng)知道EBOOT是如何跳轉到OAL.exe中的了。接下來繼續(xù)看OAL.exe的執(zhí)行過程。OALLEAF_ENTRY;ComputetheOEMAddressTable'sphysicaladdress r2, p15,0,r2,c8,c7, ;Flushthe pc, ;Jumptoprogramweare函數(shù)Launch()的參數(shù)為物理地址,因為在跳轉之前已將MMU關閉。該地址可通過VIEWBIN來查看,如下圖所示:如何確定這個地址對應的是NK.bin中的哪一個文件呢,先前說是 何在。在PB6.0中增加了瀏覽NK.bin的功能,我們可以利用此功能查看NK.bin的詳細情況,如下圖所示:;loaditintor0.KernelStartexpectsr0to;thephysicaladdressofthistable.TheMMU;turnedonuntilwellinto r0,pc,#g_oalAddressTable-(.+ OAL的啟動代碼和EBOOT的啟動代碼經(jīng)常復用,但為了代碼的簡潔,最好還是分開實現(xiàn),而且在EBOOTOAL的啟動代碼就可可以看出,OALKernelStart(),而這個函數(shù)是在文件C:\WINCE600\PRIVATE\WINCEOS\COREOS\NK\LDR\ARM\armstart.sLEAF_ENTRY r11, ;(r11)=&OEMAddressTable(save;figureoutthevirtualaddressof r1, ;(r1)=&OEMAddressTable(2ndargumentto r6, ;(r6)=VAof;convertbaseofPTstoPhysical r4, ;(r4)=virtualaddressof r0, ;(r0)=virtualaddressof r1, ;(r1)=&OEMAddressTable(2ndargumentto r10, ;(r10)=ptrtoFirstPT Zerooutpagetables&kerneldatar0,;(r0-r3)=0'stor1,r2,r3,r4,;(r4)=firstaddresstor5,r10,#KDEnd-;(r5)=lastaddress+ r4!,{r0-r4!,{r0-r4,;;readthearchitecture r5,r0LSR ;r5>>= r5,r5, ;r5&= f==architecture Setup2ndlevelpagetabletomapthehighmemoryareawhichcontains;firstlevelpagetable,2ndlevelpagetables,kerneldatapage, (r5)=architecture r4,r10,#HighPT- ;(r4)=ptrtohighpage r5, ;v6or; r0,r10,#PTL2_KRW+PTL2_SMALL_PAGE+;(r0)=PTEfor4K,kr/wu-/,uncachedunbuffered,;PRE r0,r10,#PTL2_KRW+(PTL2_KRW<<2)+(PTL2_KRW<<4)+(PTL2_KRW<<;NeedtoreplicateAPbitsintoall4 r0,r0,#PTL2_SMALL_PAGE+;(r0)=PTEfor4K,kr/wu-/,uncachedunbuffered,r0,[r4,;storetheentryinto4slotstomap16Kofprimarypager0,r0,;steponthephysicalr0,[r4,r0,r0,;steponthephysicalr0,[r4,r0,r0,;steponthephysical r0,[r4, r8,r10,#ExceptionVectors-PTs;(r8)=ptrtovector r0,r8, ;constructthePTE;;Theexceptionstacksandthevectorsaremappedasasinglekr/w;;Anyalternativewillusemorephysical;;Multiple sdon'tprovideanyrealprotection:ifthevectorswereinar/o;;theycouldstillbecorruptedviathekr/wsettingrequiredforthe r5, ;v6or; r0,r0,;PRE r0,r0,#PTL2_KRW+(PTL2_KRW<<2)+(PTL2_KRW<<4)+(PTL2_KRW<<;NeedtoreplicateAPbitsintoall4fieldsforpre-V6 r0,[r4, ;storeentryforexceptionstacksand;other3entriesnow r9,r10,#K ;(r9)=ptrtokdata r0,r9, ;(r0)=PTEfor4K;ARMV6_MMU(conditioncodesstill r0,r0, ;Nosubpageaccesscontrol,sowemustsetthisallto;PRE r0,r0,#(PTL2_KRW<<0)+(PTL2_KRW<<2)+(PTL2_KRW_URO<<;(r0)=setpermskr/wkr/wkr/w+ur/o r0,[r4, ;storeentryforkerneldata r0,r4, ;(r0)=1stlevelPTEforhighmemory r1,r10, r0,[r1,#- ;storePTEinlastslotof1stlevel Fillinfirstlevelpagetableentriestocreate"staticallymapped";fromthecontentsoftheOEMAddressTable; (r5)=architecture (r9)=ptrtoKData (r10)=ptrto1stlevelpage (r11)=ptrtoOEMAddressTable r10,r10, ;(r10)=ptrto1stPTEfor"unmapped r0, r0,r0, ;(r0)=PTEfor0:1MB(C=B=0,kernel r1, ;(r1)=ptrtoOEMAddressTablearrayr2,[r1],;(r2)=virtualaddresstomapBankr3,[r1],;(r3)=physicaladdresstomapr4,[r1],;(r4)=numMBto r4, ;Endof r12, r2,r2, ;VAneeds512MB,1MB r12, r3,r3, ;PAneeds4GB,1MBr2,r10,r2,LSRr0,r0,;(r0)=PTEfornextphysicalr0,[r2],r0,r0,;(r0)=PTEfornextphysical r4,r4, ;DecrementnumberofMB r4, ;Mapnext r0,r0, ;ClearSectionBaseAddress r0,r0, ;ClearSectionBaseAddress ;Getnext r10,r10, ;(r10)=restoreaddressof1stlevelpage;Theminimalpage saresetup.InitializetheMMUandturnit;therearesomeCPUswithpipelineissuesthatrequiresidentity beforeturningon;We'llcreateanidentity fortheaddresswe'lljumptowhenturningonMMUonand;the afterweturnonMMUandrunningonVirtual r12, ;(r12)=maskforsection r1,pc, ;physicaladdressofwherewe;NOTE:weassumethattheKernelStartfunctionneverspamacrossM r0,r1, r0,r0, ;(r0)=PTEfor1Mforcurrentphysicaladdress,C=B=0,kernel r7,r10,r1,LSR ;(r7)=1stlevelPTentryfortheidentity r8, ;(r8)=savedcontentofthe1st-level r0, ;createtheidentity r1, r1, ;Setupaccess 0andclear r10, ;setuptranslationbase(physicalof1stlevel r0, p15,0,r0,c8,c7, ;FlushtheI&D r1, r1,r1, ;changedtoread-mod-writeforARM920Enable:MMU,Align,DCache, r5, ;r5still; r1,r1, ;vectoradjust, r1,r1, ;V6-formatpage r1,r1, ;V6-setUbit,letAbitcontrolunalignment;PRE r1,r1, ;vectoradjust,ICache,ROMr0,r0,;makesurenostallon"movpc,r0"r1,;enabletheMMU&pc,;&jumptonewvirtual;MMU&cachesnow; (r10)=physcialaddressof1stlevelpage (r7)=entryin1stlevelPTforidentity (r8)=saved1stlevelPTsaveatVStart r2, ;(r2)=VAof1stlevel r7,r7, ;(r7)=offsetinto1st-level r8,[r2, ;restorethetemporaryidentity p15,0,r0,c8,c7, ;FlushtheI&D;;setupstackforeachmodes:currentmode=supervisor; sp, r4,sp,#KData- ;(r4)=ptrto;setupABORT r1, cpsr_c, ;switchtoAbortModew/IRQs sp,r4,#AbortStack-;setupIRQ r2, cpsr_c, ;switchtoIRQModew/IRQs sp,r4,#IntStack-;setupFIQ r3, cpsr_c, ;switchtoFIQModew/IRQs sp,r4,#FIQStack-;setupUNDEF r3, cpsr_c, ;switchtoUndefinedModew/IRQs sp, ;(sp_undef)=;switchbacktoSupervisor r0, cpsr_c, ;switchtoSupervisorModew/IRQs sp,;continueinitializationin r0,sp,#KData- ;(r0)=ptrto r6,[r0, ;storeVAofOEMAddressTablein ;callCfunctiontoperformtherestof;uponreturn,(r0)=entrypointof r12, r0, pc, ;jumptoentryof從上面的代碼可以看出,KernelStart()通過OEMAddressTable初始化了MMU,然后通過調用函數(shù)ARMInit()獲得kernel.dll 點,最后跳轉 點處為了找到Kernel.dll 點,用IDA反匯編kernel.dll文件,可以看到,Kernel.dll 點為NKStartupNKStartup()的實現(xiàn)在文件C:\WINCE600\PRIVATE\WINCEOS\COREOS\NK\KERNEL\ARMmdarm.c//NKStartup-entrypointof//NKLoadersetuponlytheminimal s,whichincludesARMHigharea,andthecachedstatic //with*EVERYTHINGUNCACHED*.Interruptvectorsarenotsetupeither.So,theinitsequence// datapassedfromnk//(2)Findentrypointofoal,exchangeglobals,findoutthecache//(3)fillintherestofstaticmappedarea -0xbfffffff),PSLfaultingaddress,interrupt modstacks,etc.Then,changethe'cached'static areatousecache,andflushI&D//(4)continuenormalloadingofkernel(findKITLdll,callOEMInitDebugSerial,voidNKStartup(structKDataStruct*{PFN_OEMInitGlobalsPFN_DllMainDWORDdwCpuId=GetCpuId// argumentsfromthenk = =(constROMHDR*)pKData-g_pOEMAddressTable=(PADDRMAP)pKData-/*getarchitectureidandupdatepageprotectionattributespKData->dwArchitectureId=(dwCpuId>>16)&if(pKData->dwArchitectureId>=ARMArchitectureV6)//v6orpKData->dwProtMask= = = = =}else//pre-pKData->dwProtMask= = = = =}//initializenk =(ROMHDR*) = =KInfoTable[KINX_PTOC]=KInfoTable[KINX_PAGESIZE]=g_ppdirNK=(PPAGEDIRECTORY)&ArmHigh-pKData->pNk=//(2)findentryofpfnInitGlob=(PFN_OEMInitGlobals)pKData-//nocheckinghere,ifOALentrypointdoesn'texist,wecan'tg_pOemGlobal=pfnInitGlobpKData->pOem=//setup //(3)setupvectors,UC s,modestacks,ARMSetup//cacheisenabledfromhere//(4)commonstartup//trytoloadKITLifif((pfnKitlEntry=(PFN_DllMain)g_pOemGlobal->pfnKITLGlobalInit)(pfnKitlEntry=(PFN_DllMain)FindROMDllEntry(pTOC,KITLDLL)))(*pfnKitlEntry)(NULL,DLL_PROCESS_ATTACH,(DWORD)}#ifdefCurMSec=dwPrevReschedTime=(DWORD)- //~3minutesbeforeOEMInitDebugSerial//debugchkonlyworksafterwehavesomethingtoprintDEBUGCHK(pKData==(structKDataStruct*)DEBUGCHK(pKData==&ArmHigh-OEMWriteDebugString/*CopyinterlockedapicodeintothekpageDEBUGCHK(sizeof(structKDataStruct)<=/*setupprocessorversioninformation =(dwCpuId>>4)& =CEProcessorRevision=(WORD)dwCpuId& = G(1,(L"ProcessorType=%4.4xRevision=%d\r\n",CEProcessorType, G(1,(L"OEMAddressTable=%8.8lx\r\n", //initialize//flushI&DOEMCacheRangeFlush(NULL,0,可以看到,這里調用了可以看到,這里調用了KernelInit()和FirstSchedule()這兩個函數(shù)。先說FirstSchedule(),它開始了WinCE6.0KernelStart()在同一文件中,而實現(xiàn)代碼跟WinCE5.0中,代碼如下://KernelInit-Kernelinitializationbeforeschedulingthe1stvoidKernelInit{#ifdefg_pNKGlobal->pfnWriteDebugString(TEXT("WindowsCEKernelInit\r\n"));APICallInit//setupAPIHeapInit//setupkernelInitMemoryPool//setupphysicalPROCInit//initializeVMInit//setupVMforTHRDInit//initializeMapfileInitDEBUGMSGDEBUGMSG(1,(TEXT("NKStartupdone,startingupKernelStart//neverreturnedDEBUGCHK(0);}()的實現(xiàn)在文件#ifdefg_pNKGlobal->pfnWriteDebugString(TEXT("Schedulingthefirst}這段代碼跟WinCE5.0WinCE6.0啟動最緊密的函數(shù)是THRDInit(),這之前都是做相應的初始化。THRDInit()的實現(xiàn)在文件C:\WINCE600\PRIVATE\WINCEOS\COREOS\NK\KERNEL\thread.c中,代碼如下://THRDInit-initializethreadhandling(calledatsystemvoidTHRDInit{ DEBUGLOG //don'tallowthreadcreateonememorydropbelow1%if(g_cMinPageThrdCreate< Count/100)g_cMinPageThrdCreate= Count/}//mapW32threadpriorityifOEMchooseif(g_pOemGlobal->pfnMapW32Priority)BYTEintmemcpy(prioMap,W32PrioMap,sizeof//validatethethepriorityismono-for(i=0;i<MAX_WIN32_PRIORITY_LEVELS-1;i++)if(prioMap[i]>=}DEBUGMSG((MAX_WIN32_PRIORITY_LEVELS-1)!=i,(L"ProcInit:InvalidprioritymapprovidedbyOEM,if((MAX_WIN32_PRIORITY_LEVELS-1)==i)memcpy(W32PrioMap,prioMap,sizeof}}//allocatememoryforthe1stpCurThread=AllocMemDEBUGCHKdwCurThId=(DWORD)HNDLCreateHandle hread, K)&DEBUGCHKInitThreadStruct(pCurThread,(HANDLE) K,if(g_pOemGlobal->cbCoProcRegSize)//checkthedebugregisterrelatedif(g_pOemGlobal->cbCoProcRegSize>MAX_COPROCREGSIZE)g_pOemGlobal->cbCoProcRegSize=g_pOemGlobal->fSaveCoProcReg=}elsePNAMEpTmp ame(g_pOemGlobal-DEBUGCHKg_dwCoProcPool=pTmp-Name}}elseg_pOemGlobal->fSaveCoProcReg=}DEBUGMSG(ZONE_SCHEDULE,(TEXT("cbCoProcRegSize=%d\r\n"),g_pOemGlobal-AddToDListHead t#ifdefOEMCacheRangeFlush(0,0,if(!OpenExecutable(NULL, K->oe,TOKEN_SYSTEM,NULL,0))LoadE32 K->e32,0,0,K->BasePtr= }//create/setuppStack=VMCreateStack K,pCurThread->dwOrigBase=(DWORD)pCurThread->dwOrigStkSize=pCurThread->tlsSecure=pCurThread->tlsNonSecure=pCurThread->tlsPtr=TLSPTR(pStack,pCurThread->hTok=//Saveoffthethread'sprogramcounterforgettingitsnamepCurThread->dwStartAddr=(DWORD)MDSetupThread(pCurThread,(LPVOID)SystemStartupFunc,0,TH_KMODE, K,DEBUGMSG(ZONE_SCHEDULE,(TEXT("Scheduler:Createdmasterthread}可以看到,這里開始了一個線程,線程處理函數(shù)為SystemStartupFunc(),其實現(xiàn)在文件C:\WINCE600\PRIVATE\WINCEOS\COREOS\NK\KERNEL\schedule.c,實現(xiàn)代碼如ulong){HANDLE//recordPendEventaddressforKInfoTable[KINX_PENDEVENTS]=(DWORD)//adjustalarmresolutionifitit'snotinif(g_pOemGlobal->dwAlarmResolution<g_pOemGlobal->dwAlarmResolution=elseif(g_pOemGlobal->dwAlarmResolution>g_pOemGlobal->dwAlarmResolution=VERIFY(LoaderInit//initializethecompiler -thismusthappenbeforeother//start PagePoolInit//Thiscanonlybedoneaftertheloader //InitializationforCeLog,profiler,code-coverage,SysDebugInit //initializeSystemDebugger(HWDebugstub,Kerneldumpcapture,SWKernelDebug//dothisnow,sothatwecontinuerunningafterwe'vecreatedthenew#ifdefhTh=HNDLCloseHandle K,pCleanupThread=hAlarmThreadWakeup=IntrEvents[SYSINTR_RTC_ALARM-SYSINTR_DEVICES]=LockIntrEvt//GivetheOEMafinalchancetodoamorefull-featuredinitbefore//appsareKernelIoctl(IOCTL_HAL_POSTINIT,NULL,0,NULL,0,InitMsgQueueInitWatchDog//createthepowerhandlereventandguardhEvtPwrHndlr=NKCreateEvent(NULL,FALSE,FALSE,DEBUGCHKhTh=CreateKernelThread(PowerHandlerGuardThrd,NULL,THREAD_PWR_GUARD_PRIORITY,HNDLCloseHandle K,//dirtypageevent,initiallyhEvtDirtyPage=NKCreateEvent(NULL,FALSE,TRUE,DEBUGCHK//wedon'twanttowasteathreadhere(createaseparateforcleaningdirty//Instead,RunAppsthread e"CleanDirtyPage"threadoncefilesyshTh=CreateKernelThreadHNDLCloseHandle K,#definewhile(1)}}這里創(chuàng)建了一個內核線程,處理函數(shù)為RunApps,繼續(xù) 件C:\WINCE600\PRIVATE\WINCEOS\COREOS\NK\KERNEL\kmisc.c中,代碼如下DWORDLPVOID){HMODULEDEBUGMSG(ZONE_ENTRY,(L"RunAppshFilesys=(HMODULE)NKLoadLibraryEx(L"filesys.dll",MAKELONG(LOAD_LIBRARY_IN_KERNEL,LLIB_NO_PAGING),if(hFilesys)FARPROCpfnMain=GetProcAddressA(hFilesys,(LPCSTR) //WinMainofHANDLEhFSReady,DEBUGCHKhFSReady=NKCreateEvent(NULL,TRUE,FALSE,hTh=CreateKernelThread((LPTHREAD_START_ROUTINE)pfnMain,hFilesys,THREAD_RT_PRIORITY_NORMAL,DEBUGCHK(hTh&&HNDLCloseHandle K,//IfpSignalStartedisNULL,wedon'thavefilesys(tinykern).Don'tbotherwaitingforif(pSignalStarted)NKWaitForSingleObject(hFSReady,DEBUGCHK//InitializeMUI-Resourceloader(requires//ReadsystemsettingsfromInitSystemSettingsInitSystemSettings//signalfilesysthatwe're(*pSignalStarted)}HNDLCloseHandleK,}else G(1,(L"Filesysdoesn'texist,noapp}//insteadofexiting,we'remakethisthreadcleaningdirtypagesinthe//should'veneverreturnedDEBUGCHK(0);NKExitThreadreturn}終于啟動filesys.dll了。這個過程簡單說明一下,啟動filesys.dll后等待其執(zhí)行的情況,在完成了文件系統(tǒng)的相應的初始化之后,這里繼續(xù)初始化MUI和系統(tǒng)設置,完成后再通知filesys這邊的工作已經(jīng)完成,filesys繼續(xù)啟動。這一部分的具體內容請參考MSDN,F(xiàn)ileSystemBootProcess:http://m us/library/aa912276.aspx。總之,filesys會完成WinCE的最后啟動過程,包括gwes.dll和explorer.exe等。至此,WinCE6.0啟動完成,如果有LCD且驅動能正常工作,現(xiàn)在就應該能看見可愛的WinCE6.0的界面了。本文通本文通 代碼的方式,介紹了WinCE6.0的啟動流程。流于表面了一點,很多細節(jié)應該進一步研究,以后再慢慢看吧。文中有不確切的地方,也請您11、WinCE6.0OALWinCE6.0WinCE6.0的OAL跟WinCE5.0中的有較大差別。了解這些差別,對我們移植部分很有幫助。本文將簡要介紹WinCE6.0OALWinCE5.0將內核、OAL和成一個內核可執(zhí)行文件NK.exeWinCE6.0將這三者分開,分別對應Kernel.dll、OAL.exe和KITL.dll。顯而易見,動全身的。WinCE5.0的OAL1WinCE6.0的OAL212CE6.0的OALCE5.0要包括初始化、中斷管理和要包括初始化、中斷管理和IOCTL2中增加了NKStub.lib、和OEMGLOBAL等內容。這對于WinCE6.0CE5.0核、OAL和KITL執(zhí)行。Kernel、OAL和KITL相互獨立,則消除了這個安全隱患。現(xiàn)在,它們之間的模塊導出列表NKGLOBAL表內核API以及共享的全局變量。OAL只能調用該列表中包括的內核API。為了方便OAL代碼的移植,微軟將函數(shù)指針列表封裝到NKStub.lib中。所以,我們在移植OAL代碼時沒有必要通過結構中的函數(shù)指針去調用內核API,OAL代碼保持原來的函數(shù)調用方式。簡單看一下NKStub.c的代碼實現(xiàn),下面是部分代碼:BOOLINTERRUPTS_ENABLE(BOOL{return{returng_pNKGlobal->pfnINT_ENABLE}可以看到,OAL中調用相應的內核API時,NKStub將執(zhí)行對應的結構中的函數(shù)指針。所以在編譯OAL時,添加NKStub.lib后就可以跟以前一樣使用這些內核函數(shù)。當然NKStub也包括了KITL中的相應函數(shù)列表,所以OAL也能使用KITL中的OAL導出了列表OEMGLOBALOAL函數(shù)指針和全局變量。其中是可選的。具體內容可查看PB幫助的相應部分。OEMGLOBAL的定義在文件:總結一下,CE6.0的OAL從內核中獨立出來,這樣方便OAL的單獨升級,也提高了安全性。由于內核、OAL和KITL相互獨立,所以引入了NKGLOBAL和提供了NKStub.lib和OEMStub.lib,他們做了從函數(shù)指針到函數(shù)的轉換工作。所以,在移植BSP時,原來的代碼可保持不變。到這里,我們已經(jīng)知道了WinCE6.0的OAL 組織。這里將5.0和6.0OAL部分 CE5.0 組對應文CE6.0 組b其中,其中,6.0的OALLIB5.0的OAL,OALEXE對應Kern,KITLKernkitl5.0的kernkitlprof6.0中一般放在oallib下。 組織上介紹了WinCE6.0OAL的特點在移植BSP時可作參考。有關OAL移植的具體實現(xiàn),后文將詳細介紹。另外,文中有不貼切的地方指正。12、WinCE6.0KITLKITLKITL(KernelIndependentTransportLayer)提供了一種調試WinCE的簡便方法。KITL來。所以我們在建硬件傳輸時就省去很麻,否則我們自己須實現(xiàn)與設進行數(shù)據(jù)交互的協(xié)。KL工作在硬件輸層之,因此,它無須心用于通信具體硬件,我們可以用UB、ral或者hrnt作為KL的調試通道。具體選擇哪一個,由硬件平和軟件資源定。有些設沒有hrnt和Srial接口,以只能采用UB,如 設備。如果系統(tǒng)采用了B,則建議使用hrnt作調試通道。這時配置KL的代價相對來說小。無論如何,KL相當大,在BP的移植過程中花一些時間實現(xiàn)KL的功能是完全值得的完成KL之后,你會發(fā)現(xiàn)所有的時間都沒有白花。由于KITL的實現(xiàn),后續(xù)的調試節(jié)省了很多時間。磨刀不誤砍柴工!工欲善其事,必先利其器!我深有體會!:-D以前沒有認識到KITL的強大,一直沒有碰它。最近在實現(xiàn)KITL的功能之后,隨即順利調通了幾個頑固的驅動。雖然問題本身不值一提,但沒有KITL時,驅動出了狀況,內核就掛了,不知道掛在哪里,無從下手,也不好分析。而KITL可以幫助我們定位出現(xiàn)問題的位 要的。BTW:按啟動順序來說,KITL啟動應該在OAL之后,內核之前。所以,必須先完成OAL的移植,才能進一步移植KITL。閑話少說,接下來介紹WinCE6.0KITL的基本情況。WinCE6.0中,KITLOAL中獨立出來,單獨編譯成kitl.dll。在BSP中 一為 kitl.c的文件,這是BSP中有關KITL的主要代碼所在 //tformentrypointforKITL.CalledwhenKITLIoctl(IOCTL_K )iscalled.BOOL{BOOLOAL_KITL_ARGS*pArgs,CHAR*szDeviceId,buffer[OAL_KITL_ID_SIZE];KITL_RETAIG(ZONE_KITL_OAL,("+OEMKitlStartup\r\n"));//Printbanner.WillremovewhenKITL-over-ethernetsupportisdropped//(inKITLOutputDebugString("*ThisimageusesKITL-over- KITLOutputDebugString("*PBConnectivityOptionsmustbesetto:*\n");KITLOutputDebugString("*Download:\"DeviceKITLOutputDebugString("*Transport://Lookforbootargsleftbythebootloaderorleftoverfromanearlierboot. =szDeviceId=//Ifwedon'thavebootargsinRAM,lookfirstinNORflashfortheinformation//otherwiselookontheSmartMediaNANDcard(incasewe'reperformingaNAND-only)boot.if(pArgs=={SectorInfosi;UINT8maccount=0;//GetMACaddressfromNANDif(FMD_Init(NULL,NULL,NULL)=={KITL_RETAIG(ZONE_ERROR,("ERR

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論