uboot 替代 eboot 燒寫、啟動 wince(轉)
我用的是utu2440的開發板,板子自帶的啟動檔案包括NBOOT1、NBOOT2、EBOOT、wince核心,各個檔案作用是:二、分析UBOOT啟動wince的可能性NBOOT1:S3C2440對於NAND FLash,最大載入4K的程式碼執行,可以直接執行這個程式,NBOOT1啟動後會從FLASH中載入NBOOT2
NBOOT2:主要實現從FLASH中讀取wince核心、載入eboot、顯示啟動畫面
EBOOT:實現對FLASH進行分割槽、格式化和燒寫WINCE核心映象檔案,這裡要注意的是EBOOT在燒寫 wince核心映象的過程中會把NK.bin解壓為NB.nb0再寫入到flash中。
對於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了。