程克非,付學(xué)恕,涂 剛
(1.重慶郵電大學(xué) 計算機(jī)學(xué)院,重慶400065;2.華中科技大學(xué) 計算機(jī)學(xué)院,湖北 武漢430074)
微軟的 Microsoft Visual Studio 2005和Platform Builder開發(fā)工具使得開發(fā)和定制 WinCE 6.0變得簡單而且功能強(qiáng)大。由于WinCE 6.0具有可定制、多平臺、實時性、網(wǎng)絡(luò)功能、多媒體和多語言等諸多優(yōu)點(diǎn),其應(yīng)用極為廣泛[1]。在嵌入式操作系統(tǒng)中Bootloader是系統(tǒng)上電后首先執(zhí)行的代碼,對于原生WinCE 6.0系統(tǒng)來說,從打開電源到系統(tǒng)完全啟動期間,LCD(液晶顯示屏)沒有任何視頻或圖像輸出,導(dǎo)致其用戶體驗有所欠缺。而此前的研究成果基本可以分為兩類:一類是在開機(jī)時顯示單一色彩的圖片或一些字符,使開機(jī)界面不夠美觀;另一類則是直接采用一個超大數(shù)組存放圖片數(shù)據(jù)而使得移植困難。本文正是基于以上原因,在認(rèn)真分析和研究了以前的成果基礎(chǔ)上,通過對WinCE 6.0的Bootloader代碼進(jìn)行分析和設(shè)計,將符合LCD分辨率的開機(jī)Logo數(shù)據(jù)直接固化在Flash上并在Bootloader啟動時讀出,使得系統(tǒng)開機(jī)后馬上就有漂亮的彩色圖像輸出,同時更換Logo也變得簡單方便,從而滿足用戶對嵌入式產(chǎn)品要求的友好界面及美觀性?;谠摲椒▽崿F(xiàn)的WinCE 6.0系統(tǒng)的手持式第二代居民身份證閱讀器使用的顯示屏是信利(Truly)半導(dǎo)體有限公司的4.8英寸分辨率為800×480的TFT LCD。
Bootloader是用來管理目標(biāo)設(shè)備啟動過程的特定程序,是在操作系統(tǒng)內(nèi)核加載之前設(shè)備首先運(yùn)行的一小段程序[2]。其主要工作包括設(shè)備硬件平臺的初始化,內(nèi)存地址空間映射的建立,以及從非易失存儲器(Nand Flash或 Nor Flash,本文中設(shè)備采用的是Nand Flash)上或者網(wǎng)絡(luò)上加載操作系統(tǒng)映像文件并引導(dǎo)運(yùn)行等。
UBoot(universal Bootloader): 它 起 源 于 開 源 項 目PPCBoot,后來ARMBoot也合并進(jìn)來,再加入其他一些Bootloader,于是 UBoot誕生了[3]。2002年12月17日UBoot 0.2.0發(fā)布,它是UBoot的第一個發(fā)布版本。從那以后,UBoot又陸續(xù)修改和更新了6次之多。從2008年8月后,UBoot采用日期作為版本號。截至目前為止,最新版本號為 UBoot-2011.06。UBoot的支持是不間斷的。UBoot有引導(dǎo)啟動(Bootloading)模式和下載運(yùn)行(downloading)模式,并具有大型Bootloader所應(yīng)該具備的所有功能。它是GPL(general public license)下資源代碼最完整的一個通用Bootloader。UBoot支持的處理器架構(gòu)包括PowerPC,ARM,MIPS和X86等。UBoot支持大量的外設(shè)驅(qū)動,支持多種不同的文件系統(tǒng),還附帶有腳本和調(diào)試等工具,專門針對Linux的支持做了優(yōu)化,并特別為板級移植做了很多的支持。其主要特性為:以太網(wǎng)支持,IP/MAC預(yù)置功能,在線讀寫Flash,支持串口下載代碼,識別二進(jìn)制及其它格式的內(nèi)核,監(jiān)控命令集,支持看門狗(WatchDog)時鐘,支持LCD顯示Logo等。
Redboot:它是Redhat公司的一個開源項目,是伴隨ECOS發(fā)布的一個獨(dú)立運(yùn)行在嵌入式系統(tǒng)上的Bootloader方案[4]。Redboot廣泛支持各種處理器架構(gòu),諸如:Power-PC、MIPS、ARM和X86等,功能非常完善。Redboot采用了ECOS的硬件抽象層并以此為基礎(chǔ),繼承了ECOS的簡潔和穩(wěn)定可靠的優(yōu)點(diǎn),同時又可以靈活的配置。它不僅支持Ymodem或者Xmodem協(xié)議通過串口下載映像,也支持以太網(wǎng)口使用TFTP的方式下載映像文件,常用于系統(tǒng)初始化、引導(dǎo)內(nèi)核映像和調(diào)試支持。Redboot自啟動后,會提供一個可交互的命令行,用來管理本地映像,映像下載和運(yùn)行,Bootloader配置以及其它各種外部硬件設(shè)備等。Redboot的引導(dǎo)腳本文件保存在本地Flash上,主要用作從TFTP服務(wù)器端或本地Flash下載系統(tǒng)映像并將其加載運(yùn)行。
Blob(boot loader object):它是由Jan-Derk Bakker and Erick Mouw發(fā)布的,是專門針對StrongARM構(gòu)架下的LART(Linux advanced radio terminal)設(shè)計的一個 Bootloader[5]。Blob提供兩種工作模式,在啟動時處于引導(dǎo)加載模式,但是它有10s的等待時間,當(dāng)用戶按下任意鍵,則Blob立刻切換到下載運(yùn)行模式。如果10s內(nèi)沒有按鍵響應(yīng),則Blob啟動并加載儲存在本地的Linux內(nèi)核。Blob主要是通過串口跟主機(jī)通信,速度慢而且效率低下,同時其支持的CPU結(jié)構(gòu)也很有限。Blob最新的版本是Blob 2.0.5。
VIVI:它是由韓國mizi公司開發(fā)設(shè)計的一個專門針對ARM 9嵌入式處理器的Bootloader。與其它的Bootloader相比VIVI具有容易理解,易于移植等優(yōu)點(diǎn)[6]。VIVI也具有兩種工作模式:引導(dǎo)啟動模式和下載運(yùn)行模式。引導(dǎo)啟動模式是VIVI的默認(rèn)工作模式,它可在一段用戶自定義的時間流逝后自行引導(dǎo)和啟動Linux內(nèi)核。在非默認(rèn)的下載運(yùn)行模式下,VIVI會為用戶提供一個電腦終端命令行接口,通過該接口可以利用主機(jī)的串口來使用VIVI提供的操作命令和VIVI進(jìn)行通信。
一個典型的WinCE 6.0系統(tǒng)的啟動流程如圖1所示。
圖1 WinCE 6.0系統(tǒng)啟動流程
采用分級Bootloader(NBoot和EBoot)設(shè)計,可以方便代碼維護(hù)和修改,并且將核心硬件和外圍硬件初始化分開完成,提高了代碼執(zhí)行效率和復(fù)用率,同時使得代碼便于移植[7]。所以本文中的第二代居民身份證閱讀器就是采用 NBoot(Nand Flash Bootloader) 和 EBoot(Ethernet Bootloader)的兩級Bootloader模式。
1.2.1 NBoot分析
NBoot位于 Nand Flash的block 0(每block大小為1MB)上,通過Platform Builder編譯為block0.nb0映像文件[8]。該文件固定大小為72KB。系統(tǒng)上電時首先即自動加載 Nand Flash的block 0上的前4KB代碼[9],它是 NBoot的匯編初始化代碼。匯編代碼完成最基本的硬件初始化之后,就跳轉(zhuǎn)到C語言入口開始執(zhí)行后續(xù)代碼[10],后續(xù)代碼所完成的主要工作就是將EBoot從Nand Flash的block 3上拷貝到RAM(內(nèi)存)并加載運(yùn)行。整個NBoot的主要執(zhí)行流程如圖2所示。
圖2 NBoot執(zhí)行流程
1.2.2 EBoot分析
EBoot位于 Nand Flash的block 3上。大小控制在512KB以內(nèi)(本設(shè)備為391KB)。EBoot主要由Blcommon、OEM代碼和網(wǎng)絡(luò)驅(qū)動等組成[11]。它有兩種工作模式:燒寫模式完成將Bootloader自身和內(nèi)核映像(NK.bin)固化到Nand Flash的指定block上;下載模式完成將內(nèi)核映像從Nand Flash下載到RAM指定地址處加載運(yùn)行。
本設(shè)計主要利用EBoot的main()函數(shù)中包含的BootloaderMain()函數(shù)實現(xiàn)。在BootloaderMain()中調(diào)用了OEMPlatformInit()函數(shù)來完成硬件平臺的初始化過程,包括LCD的初始化。本文中實現(xiàn)開機(jī)Logo的功能即是在這兩個函數(shù)中添加C語言代碼實現(xiàn)的。首先通過EBoot的燒寫模式將Logo下載到Nand Flash的指定block中,然后開機(jī)時再通過EBoot的下載模式將Logo從Nand Flash讀到RAM中的LCD緩沖區(qū)顯示。EBoot簡化后的執(zhí)行流程如圖3所示。
圖3 EBoot執(zhí)行流程
由于Bootloader執(zhí)行效率和硬件關(guān)聯(lián)度高,并且開機(jī)Logo的顯示相對于普通的視頻輸出從實現(xiàn)方式和顯示內(nèi)容并不完全一樣[12]。所以在Bootloader中添加的實現(xiàn)開機(jī)Logo的代碼要相對簡單且執(zhí)行效率高,同時必須和底層的硬件以及LCD密切相關(guān)。
本文中的設(shè)備上使用的LCD是信利(truly)半導(dǎo)體公司生產(chǎn)的型號為 TFT800480-30-E 4.8英寸 TFT LCD,分辨率為800×480,32位色彩顯示[13]。硬件核心采用的是三星電子(samsung electronics)的 ARM11架構(gòu)的S3C6410嵌入式處理器,主頻為667MHz。S3C6410的顯示控制器時序如圖4所示[14]。
圖4 LCD RGB接口時序
在 WinCE 6.0自帶的 Bootloader中并沒有初始化S3C6410的LCD控制器的代碼,LCD的初始化發(fā)生在內(nèi)核的加載啟動之后。所以在Bootloader運(yùn)行的這段時間內(nèi),LCD上沒有任何視頻輸出。因此為了產(chǎn)品的美觀性和交互性,本設(shè)備在Bootloader中添加了實現(xiàn)開機(jī)Logo的代碼,使得系統(tǒng)一啟動就有視頻圖像輸出并顯示系統(tǒng)開機(jī)進(jìn)度條,Logo包含有公司的信息和圖標(biāo)等。其中Logo是BMP(位圖)格式的圖片,分辨率為800×480,其顏色位值為24,大小固定為1152054字節(jié)。通過Bootloader燒寫到Nand Flash的block 5和block 6上,并在系統(tǒng)啟動后由Bootloader讀取位圖數(shù)據(jù),然后將數(shù)據(jù)直接拷貝到RAM的LCD輸出緩沖區(qū)中,LCD就會原樣顯示出Logo。Logo在Nand Flash上的存儲位置如圖5所示。
圖5 Logo存儲分布
實現(xiàn)開機(jī)顯示Logo的具體過程如下:
(1)從SD卡中讀取Logo數(shù)據(jù)到RAM:在Bootloader的燒寫工作模式下,添加從SD卡讀取Logo的C語言代碼,在BootloaderMain()函數(shù)中添加如下函數(shù):
LogoReadFromSD();從SD卡中讀取Logo信息,包括Logo存放的起始地址和長度等。其主要代碼如下:
這兩段代碼分別指明了Logo將要讀取到RAM中的地址值和對Logo數(shù)據(jù)進(jìn)行分析和處理,為讀取SD卡中的Logo到RAM做準(zhǔn)備。
DownloadImage(DWORD dwImageStart, DWORD dwImageLength,DWORD dwLaunchAddr);這3個入口參數(shù)分別是映像存儲起始地址,映像長度和映像加載地址。主要功能是從SD卡下載Logo數(shù)據(jù)到RAM。它會調(diào)用它所 包 含 的 OEMReadData(DWORD dwData,PUCHAR pData)函數(shù)來完成具體的Logo數(shù)據(jù)下載工作,其中2個入口參數(shù)分別指:映像數(shù)據(jù)長度和映像存儲緩沖區(qū)。
(2)將RAM中的Logo燒寫到 Nand Flash:這是在Bootloader燒寫工作模式下實現(xiàn)整個開機(jī)Logo設(shè)計與顯示過程中最關(guān)鍵的一部分,主要由 WinCE 6.0自帶的底層Flash訪問函數(shù)完成。該函數(shù)具有便于移植,代碼復(fù)用率高和執(zhí)行效率高的優(yōu)點(diǎn),并且可以不加修改直接運(yùn)用于其它基于 WinCE 6.0的嵌入式設(shè)備上。
OEMLaunch(DWORD dwImageStart,DWORD dwImage-Length,DWORD dwLaunchAddr,const ROMHDR *pRomHdr);這4個入口參數(shù)分別是映像存儲起始地址,映像長度,映像加載地址和TOC分區(qū)標(biāo)識符。主要功能是將下載到RAM中的Logo燒寫到Nand Flash的指定block上。
OEMLaunch()調(diào)用 WriteRawImageToBootMedia
(DWORD dwImageStart,DWORD dwImageLength,DWORD dwLaunchAddr)函數(shù)完成具體燒寫過程。其入口參數(shù)分別指:映像存儲起始地址,映像長度和映像加載地址。其主要功能就是執(zhí)行下面的底層Flash訪問函數(shù)代碼:
dwBlock=LOGO_BLOCK;指定了Logo將要燒寫到的Nand Flash起始block數(shù)。
pLowFuncTbl=FIL_GetFuncTbl();直接訪問底層Nand Flash的函數(shù),可以直接對Nand Flash進(jìn)行訪問和修改等操作,其中最重要3個底層操作如下:
pLowFuncTbl-> Read(UINT32nBank, UINT32 nPpn, UINT32nSctBitmap, UINT32nPlaneBitmap,UINT8 *pDBuf,UINT8 *pSBuf,BOOL32bECCIn,BOOL32bCleanCheck);直接讀Nand Flash數(shù)據(jù)。其參數(shù)分別指:block數(shù),Nand Flash頁數(shù),扇區(qū)映射位,Nand Flash平面映射位,目標(biāo)數(shù)據(jù)緩沖區(qū),源數(shù)據(jù)緩沖區(qū),ECC校驗碼標(biāo)識位和Nand Flash數(shù)據(jù)清除標(biāo)識位。
pLowFuncTbl->W(wǎng)rite(UINT32nBank,UINT32nPpn,UINT32nSctBitmap,UINT32nPlaneBitmap,UINT8*pDBuf,UINT8*pSBuf);直接寫Nand Flash數(shù)據(jù)。其參數(shù)分別指:block數(shù),Nand Flash頁數(shù),扇區(qū)映射位,Nand Flash平面映射位,目標(biāo)數(shù)據(jù)緩沖區(qū)和源數(shù)據(jù)緩沖區(qū)。
pLowFuncTbl-> Erase(UINT32nBank, UINT32 nPbn,UINT32nPlaneBitmap);直接擦除Nand Flash數(shù)據(jù)。其參數(shù)分別指:block數(shù),Nand Flash頁數(shù)和Nand Flash平面映射位。
(3)設(shè)置 LCD寄存器[15]:
設(shè)置LCD主要在Bootloader的下載模式中完成。首先在OEMPlatformInit()函數(shù)中調(diào)用LCD初始化函數(shù)InitializeDisplay()來設(shè)置CPU的控制LCD輸出的GPIO口:
然后在InitializeDisplay()中實現(xiàn)重要函數(shù):LDI_fill_output_device_information(void*pDevInfo);其參數(shù)指針指向一個系統(tǒng)定義的視頻設(shè)備信息結(jié)構(gòu)體。該函數(shù)功能為:初始化LCD設(shè)備基本信息,像素時鐘采樣頻率33.33MHz,位數(shù)模式24BPP,輸出圖像格式8:8:8,像素點(diǎn)時鐘下降沿采樣,幀率為60,水平、垂直同步信號低電平有效。在該函數(shù)中還要設(shè)置如下重要參數(shù):
以上代碼分別指:幀后、幀前等待計數(shù)分別為31、1個行時鐘,垂直脈沖寬度為2個行時鐘,行后、行前等待計數(shù)分別為86、1個像素點(diǎn)時鐘,水平同步時鐘寬度為128個像素點(diǎn)時鐘。
(4)將Logo數(shù)據(jù)拷貝到RAM的LCD輸出緩沖區(qū):
將Logo從Nand Flash拷貝到RAM中,主要是靠在下載模式下通過OEMPlatformInit()中添加的如下3個函數(shù)完成的:
ShadowLogo()函數(shù)主要將Logo數(shù)據(jù)從Nand Flash對應(yīng)block讀取到RAM指定地址中。其中包含如下重要代碼:
pBuffer=(UINT8*)EBOOT_BINFS_BUFFER_UA_START;指向Logo在RAM中的儲存起始地址,這是一個通過 MMU(Memory Management Unit)映射后的虛擬地址。
dwStartBlock=LOGO_START_BLOCK;指向Logo在Nand Flash存儲的起始block。
dwNumBlock=LOGO_BLOCK_SIZE;指向Logo在Nand Flash上所占據(jù)的block數(shù)。
CopyLogoPicSeg(S32xPos,S32yPos,S32nWidth,S32nHight,PU08pBuf);其各個參數(shù)分別指:Logo在LCD屏幕上開始顯示的橫坐標(biāo)和縱坐標(biāo),二維圖像數(shù)組寬和高,以及Logo在RAM的起始地址值。其中包含如下重要參數(shù)設(shè)置:
U32*tmp=EBOOT_FRAMEBUFFER_UA_START;指向RAM中的LCD輸出緩沖區(qū),這也是一個經(jīng)過MMU映射的虛擬地址,Logo數(shù)據(jù)信息將被拷貝至此地址處,然后在LCD上完整的顯示出來。
顯示內(nèi)核加載進(jìn)度的進(jìn)度條也是顯示Logo的一部分,該功能主要由函數(shù)progress_draw_v(int_top_left,int_top_right,int _width,int _h(yuǎn)eigth,int _color)完成,其入口參數(shù)分別指:進(jìn)度條位于LCD的橫坐標(biāo)和縱坐標(biāo),LCD屏幕寬度和高度,以及進(jìn)度條的顏色。
(5)顯示示例Logo:
打開Platform Builder編譯生成本項目下的BSP(board support package)包,會得到EBoot.bin和EBoot.nb0兩個Bootloader映像文件。將EBoot.bin燒寫到本設(shè)備的Nand Flash的block 3上,啟動設(shè)備,即可看到如圖6所示示例Logo及位于LCD下方的開機(jī)進(jìn)度條。
圖6 開機(jī)Logo
本文通過對WinCE 6.0的Bootloader啟動流程進(jìn)行分析,針對實際的硬件平臺,完成了基于 WinCE 6.0系統(tǒng)和三星S3C6410硬件平臺的開機(jī)Logo的設(shè)計與實現(xiàn)。對比其它類似設(shè)計與實現(xiàn)不能快速準(zhǔn)確顯示彩色圖片,不易于移植以及不能隨意且方便的更換Logo的局限性,本文中的設(shè)計與實現(xiàn)代碼簡潔高效,方便移植,Logo可以隨意更換,而且代碼可以不加修改而直接運(yùn)用于其它基于 WinCE 6.0系統(tǒng)的嵌入式設(shè)備上。經(jīng)過反復(fù)測試,該設(shè)計與實現(xiàn)可以準(zhǔn)確快速的將Logo原樣顯示在LCD上。本文中的第二代居民身份證閱讀器正是采用了上述設(shè)計實現(xiàn)了開機(jī)顯示Logo的功能,該設(shè)備已進(jìn)入量產(chǎn)和實際應(yīng)用階段。
[1]HE Zongjian.Windows CE embedded system [M].Beijing:Beihang University Press,2006:7-10(in Chinese).[何宗健.Windows CE嵌入式系統(tǒng) [M].北京:北京航空航天大學(xué)出版社,2006:7-10.]
[2]ZHANG Dongquan,TAN Nanlin.Windows CE practical development technology [M].Beijing:Publishing House of Electronics Industry,2006(in Chinese).[張東泉,譚南林.Windows CE實用開發(fā)技術(shù) [M].北京:電子工業(yè)出版社,2006.]
[3]YANG Fumin,WANG Pengyu,TU Gnag.Design and implementation of BSP in the embedded Linux [J].Computer Engineering and Science,2005(in Chinese). [陽富民,王朋羽,涂剛.嵌入式Linux系統(tǒng)BSP的設(shè)計與實現(xiàn) [J].計算機(jī)工程與科學(xué),2005,27(1):64-66.]
[4]ZHENG Kelong.Design and application of RedBoot based ARM-Linux embedded system [D].Xi'an:Xidian University Library,2009(in Chinese).[鄭克龍.基于 ARM-Linux嵌入式系統(tǒng)RedBoot的設(shè)計與應(yīng)用 [D].西安:西安電子科技大學(xué)圖書館,2009.]
[5]Startup code analyze of BLOB and research of Bootloader porting[D]. Wuhan: Wuhan University of Science and Technology Library,2010(in Chinese). [李 昂.基 于 S3C44BOX 的Bootloader-BLOB移植研究 [D].武漢:武漢科技大學(xué)圖書館,2010.]
[6]KU Shaoping,TIAN Yunfang.Analysis &improvement of VIVI BootLoader based on Nand Flash [J].Control and Automation Publication Group,2009,26(8):76-78(in Chinese).[庫少平,田云芳.基于Nand Flash的VIVI裝載器的分析于改進(jìn) [J].微計算機(jī)信息,2009,26(8):76-78.]
[7] WANG Yagang.Analysis and transplant of embedded Boot-Loader mechanism [J].Computer Engineering,2010,36(6):267-269(in Chinese). [王亞剛.嵌入式 Bootloader機(jī)制分析與移植 [J].計算機(jī)工程,2010,36(6):267-269.]
[8]Platform builder for microsoft Windows CE 6.0help [Z].Microsoft Corporation,2006.
[9]QI Yun,ZHANG Yongrui.Design and implementation of Boot-Loader based on PXA255processor in WinCE [J].Electronic Science and Technology,2005,(10):58-61(in Chinese).[齊云,張永瑞.PXA255處理器在 WinCE系統(tǒng)下的Boot-Loader設(shè)計與實現(xiàn) [J].電子科技,2005,(10):58-61.]
[10]ZHANG Fei,BAI Ruilin,LU Lin.Design and implementation of WinCE 5.0Bootloader [J].Computer Engineering,2009(in Chinese).[張飛,白瑞林,陸林.WinCE 5.0Bootloader的設(shè)計與實現(xiàn) [J].計算機(jī)工程,2009,35(7):232-234.]
[11]GONG Nan,CAO Ling,GAO Zhiying.Design and development of Windows CE 5.0Boot Loader based on Sansung S3C2440Aprocessor [J].Journal of Xi'an Institute of Posts and Telecommunications,2008,13(5):45-47(in Chinese).[弓楠,曹凌,高志英.基于Sansung S3C2440A處理器 Windows CE 5.0Boot Loader的設(shè)計與開發(fā) [J].西安郵電學(xué)院學(xué)報,2008,13(5):45-47.]
[12]ZHANG Zhi,JIANG Zhilong.Implementation of Boot Logo in Bootloader based on Windows CE and S3C2410 [J].Electronic Measurement Technology,2010,33(2):87-90(in Chinese).[張智,江志農(nóng).基于S3C2410和Windows CE的Bootloader啟動圖片的實現(xiàn) [J].電子測量技術(shù),2010,33(2):87-90.]
[13]TFT800480-30-E Specification [Z]. Truly Semiconductors LTD,2009.
[14]S3C6410XUser's Manual [Z].Samsung Electronics,2009.
[15]ZHANG Genbao,YANG Feng,TIAN Ze,et al.Development of Eboot Based on Windows CE.NET [J].Measurement and Control Technology,2007,26(7):53-55(in Chinese).[張根寶,楊峰,田澤,等.Windows CE.NET系統(tǒng)下Eboot開發(fā) [J].測控技術(shù),2007,26(7):53-55.]