1. 程式人生 > >uboot 替代 eboot 燒寫、啟動 wince(轉)

uboot 替代 eboot 燒寫、啟動 wince(轉)

一、wince 啟動過程分析
    我用的是utu2440的開發板,板子自帶的啟動檔案包括NBOOT1、NBOOT2、EBOOT、wince核心,各個檔案作用是:

NBOOT1:S3C2440對於NAND FLash,最大載入4K的程式碼執行,可以直接執行這個程式,NBOOT1啟動後會從FLASH中載入NBOOT2

NBOOT2:主要實現從FLASH中讀取wince核心、載入eboot、顯示啟動畫面

EBOOT:實現對FLASH進行分割槽、格式化和燒寫WINCE核心映象檔案,這裡要注意的是EBOOT在燒寫 wince核心映象的過程中會把NK.bin解壓為NB.nb0再寫入到flash中。

二、分析UBOOT啟動wince的可能性
    對於NBOOT1、NBOOT2的功能完全可以用UBOOT代替,本身UBOOT已經實現NAND falsh 啟動,再就是wince核心檔案 NK.nb0 可以直接載入到記憶體的 0x30200000,然後使用 uboot的 go 指令直接執行wince核心檔案。

    比較難辦的就是eboot功能的uboot實現,eboot的分割槽功能在flash中建立了一個binfs的分割槽用於存放wince核心映象檔案,在 wince中可以直接支援binfs分割槽,可以看到映象檔案。如果要在uboot中實現這個功能,則必須為uboot新增對flash分割槽的功能,為了測 試實現的可能性花了兩天做了不少實現,發現要想做好這個功能實在是太花時間、精力了,只好作罷(如果哪位兄弟能提供幫助就太好了)。

    在去掉binfs支援後,uboot可以實現將NK.nb0燒寫到flash中,然後啟動時讀取到0x30200000位置,最後用go命令載入啟動 wince,這麼來看應該是很簡單的事了(後來證明此時的想法太。。。。。。)

三、測試可能性

    使用uboot將nk.nb0載入到0x3020000中,然後go 0x30200000,等了一會果真看到了wince的介面,這一步成功了,下一步就可以直接燒寫了。但是很快發現,使用這種方法啟動一次wince後就 無法再啟動uboot,通過讀取flash的內容發現,wince把uboot的flash塊給格式化了。是什麼原因呢?

    原來是因為這個wince核心有自動分割槽格式化功能,上面已經說了uboot中不實現分割槽格式化的功能,所以在wince中就必須新增這個功能。但是這樣 一來wince就會格式化uboot,通過閱讀eboot發現,eboot在格式化的時候會把eboot區標記為壞塊,這樣wince就不會進行格式化 了,看來必須首先解決這個問題。

四、FLASH 管理區域劃分

    我的FLASH大小是64M,wince 核心檔案加上uboot不超過32M,這樣就定義FLASH的前32M由uboot進行管理,這32M對wince來說是不存在的,後32M歸於 wince進行儲存,在wince中進行管理。

    如果要阻止wicne格式化前32M,可以再uboot中對前32M全部標記為壞塊,但是這樣一來uboot本身對flash所有操作也會首先做壞塊檢 測。如果這麼做的話,每次uboot對flash讀寫時取消壞塊標記,操作完成後在標記為壞塊。思路應該是可行的,但是感覺這麼做太麻煩了。當然條條大路 通羅馬,我們可以逆向思維一下,為何不能修改wince核心來遮蔽前32M flash空間呢?

    通過閱讀wince的bsp,發現有個很重要的巨集定義

loader.h中

// NAND Boot (loads into SteppingStone) @ Block 0

#define NBOOT_BLOCK 0
#define NBOOT_BLOCK_SIZE 1
#define NBOOT_SECTOR BLOCK_TO_SECTOR(NBOOT_BLOCK)

// TOC @ Block 1

#define TOC_BLOCK 1
#define TOC_BLOCK_SIZE 1
#define TOC_SECTOR BLOCK_TO_SECTOR(TOC_BLOCK)

// Eboot @ Block 2

#define EBOOT_BLOCK 2
#define EBOOT_SECTOR_SIZE FILE_TO_SECTOR_SIZE(EBOOT_RAM_IMAGE_SIZE)
#define EBOOT_BLOCK_SIZE SECTOR_TO_BLOCK(EBOOT_SECTOR_SIZE)
#define EBOOT_SECTOR BLOCK_TO_SECTOR(EBOOT_BLOCK)

//#define RESERVED_BOOT_BLOCKS (NBOOT_BLOCK_SIZE + TOC_BLOCK_SIZE + EBOOT_BLOCK_SIZE)/*這個引數是定義預覽 block 的數量,預設是NBOOT + TOC + EBOOT,我為了遮蔽前面32M空間,需要修改此定義*/

#define RESERVED_BOOT_BLOCKS SECTOR_TO_BLOCK(FILE_TO_SECTOR_SIZE(0x2000000))

// Images start after OEM Reserved Blocks

#define IMAGE_START_BLOCK RESERVED_BOOT_BLOCKS
#define IMAGE_START_SECTOR BLOCK_TO_SECTOR(IMAGE_START_BLOCK)

修改RESERVED_BOOT_BLOCKS 後重新編譯wince(由於我用的是win7,不支援wince5的編譯,只好用虛擬機器來編譯,速度真是 太折磨人了),希望能夠一次成功,重燒uboot,下載wince核心檔案NK.nb0,啟動wince,失望,還是失望,uboot依舊被擦除了。

    為了搞清楚問題的原因,開啟wince的除錯資訊, 特別是NAND FLash驅動的所有除錯資訊。重新編譯、下載執行。發現wince開始擦除的位置是正確的,在擦除未完時此時我復位了開發板,uboot可以正常啟動。 重來,等擦除操作完成了以後我再復位,發現uboot不能啟動了,這可真是奇怪了,開始擦除的位置是正確的,每次block會遞增,怎麼會擦除前面的 block 呢?再來一遍,發現問題了,wince的整個擦除起始位置是正確的,但是結束 block 是錯誤的,我的FLASH整個 block 是4096個,wince從正確的起始位置開始,擦除了 4096 個塊,估計就是這個原因導致把 uboot 給擦除了。

    閱讀了一下wince的fmd驅動,這裡初始化flash,發現有一句很不可理解

// pFlashInfo->dwNumBlocks            = NUM_BLOCKS ;/*這是原來的定義,修改為下面的值*/

pFlashInfo->dwNumBlocks            = NUM_BLOCKS - IMAGE_START_BLOCK 

按照道理來講,初始化flash block數量時至少應該遮蔽nbot eboot兩部分,但是這個bsp中未遮蔽,在網上查詢了一下,的確有的bsp是定義為
NUM_BLOCKS - IMAGE_START_BLOCK,我覺得這樣定義更合理。也許是bsp從三星出來到我手上中間經過不少人修改,留下了這個bug吧。

    重新編譯,載入,一切正常,wince可正常啟動。

    最後把wince核心檔案燒寫到flash中,uboot啟動時自動載入,一切正常。

    經過這樣修改以後,wince啟動時如果沒有檢測到有效的mbr,則會自動分割槽格式化,第二次再啟動時就不會再格式化了,剩餘的32M空間可以儲存使用者文 件。在wince的儲存管理中可以看到flash大小為32M,的確已經成功遮蔽了前面的32M空間。

至此,該工作告一段落,uboot可以正常燒寫、載入wince了。