S3C6410 SD卡啓動uboot分析(詳細)

6410的手冊上說,能夠從nandflash、onenand、SD卡啓動,沒有專用的燒錄工具的狀況下,只有SD卡啓動是能夠考慮 的。手冊上看到,SD卡啓動,其實是先執行片內IROM中的一段程序,該程序從SD卡中讀取代碼,寫到stepping stone 中,stepping stone是位於0x0c000000、size爲8K的片內內存,代碼寫入stepping stone後,跳到 0x0c000000處繼續執行程序。那麼,要實現從SD卡啓動,就必須弄清楚:  
一、8K的代碼保存在SD卡的什麼位置。  
二、代碼以什麼格式存儲。  

   把編譯好的代碼寫入到最後芯片末尾偏移-9216字節處,插入SD卡座,把開關撥到SD0卡啓動的位置,上電


這裏使用的uboot並不是uboot官方發佈的uboot代碼,而是爲三星定製的一個uboot版本

s3c-u-boot-1.1.6,其代碼做者就包括了三星的程序員與denx的員工。這個版本支持

SD啓動,不過默認是nand啓動,使它支持uboot須要作如下事情:

一、  雖然支持uboot啓動,可是uboot代碼裏不叫SD啓動方式,而是叫movinand啓動

方式,在incluede/configs/smdk6410.h中就有這個選項,因此在這個文件裏關閉nand

啓動,打開movinand啓動就能夠了:

//#define CONFIG_BOOT_NOR

//#define CONFIG_BOOT_NAND       註釋nand啓動

#define CONFIG_BOOT_MOVINAND   打開movinand啓動

//#define CONFIG_BOOT_ONENAND

//#define CONFIG_BOOT_ONENAND_IROM

#define     CONFIG_NAND

//#define CONFIG_ONENAND

#define CONFIG_MOVINAND         打開movinand選項,使uboot支持movinand的操做

二、若是單純是作上面的改動,仍是不夠的,在運行的時候會發現到了必定的時候

uboot就死掉了,其實這是由於uboot中假設SMDK6410在使用SD方式的時候是從CH0啓

動的,可是手上的這個板子是經過CH1啓動,那麼在運行被複制到SRAM中的8K代碼時

候沒辦法在CH0檢測到SD,更沒辦法將SD 裏的代碼複製到SDRAM中。修改辦法是在

incluede/

movi.h中HSMMC_CHANNEL修改成1。

三、而後若是將上述修改後編譯出來的u-boot.bin經過IROM_Fusing_tools直接燒寫到

SD中也是沒辦法啓動的,須要運行如下的命令進行處理:

cat u-boot.bin >> temp

cat u-boot.bin >> temp

split -b 256k temp

mv xaa u-boot_256k.bin

split -b 8k u-boot.bin

mv xaa u-boot_8k.bin

cat u-boot_256k.bin >> u-boot_mmc.bin

cat u-boot_8k.bin >> u-boot_mmc.bin

通過這些處理,其實是將u-boot.bin內容重複一次後(爲了保證達到256K,若是這

個bin更小,那麼可能須要重複3次、4次,直到超過 256K 爲止),將前256K製成u-

boot_256k.bin,再將前8K製成u-boot_8k.bin,最後將u-boot_256k.bin +u-

boot_8k.bin合併成一個256K+8K大小的文件u-boot_mmc.bin,這個文件前256K就是u-

boot_256k.bin 然後8K就是u-boot_8k.bin。把這個u-boot_mmc.bin經過

IROM_Fusing_tools燒寫到SD卡就能夠成功啓動系統了。

爲何要作這樣的處理這個bin文件呢?下面經過分析IROM_Fusing_tools、uboot的

源碼來揭示其中的由來。

從網上能夠下載到IROM_Fusing_tools的源碼,在按下這個軟件的start控件後,先是

讀取這個SD卡的第一個扇區,也就是這個磁盤的MBR 扇區,判斷是否是FAT32格式的

磁盤(這也是爲何用來作啓動的SD必須格式化爲FAT32格式),接着獲取總的扇區

數目TOTAl_SECOTR,並將所要燒寫的bin文件燒寫到磁盤的這個扇區:TOTAL_SECTOR –

2 - SIZE_OF_IMAGE/512。其中TOTAl_SECTOR是這個磁盤總的扇區數目;

SIZE_OF_IMAGE/512是這個bin文件將要佔據的扇區數(這裏是以512爲扇區大小的,

所以對於扇區更大的SD卡也就沒辦法使用了,而如今的大容量SD均可能使用了2K甚至

4K的扇區,除非修改這個程序,並同步地在uboot中修改程序);至於2則是保留的2

個扇區,至於爲何要保留這2個扇區,須要分析uboot的源碼狀況,下面將作進一步

的闡述。

在SD啓動方式下,S3C6410內部的IROM程序BL0首先運行,並將SD中的最後18個扇區開

始的16個扇區內容複製到片內的8K SRAM,也就是SteppingStone,接着跳轉到這塊

SRAM的開始地址開始運行,這8K的代碼實際上就是上面u-boot_mmc.bin這個文件的最

後8K,也是u-boot.bin的最開始8K代碼,這段代碼也叫BL1。從BL0跳轉到BL1的時候

uboot也就接管了CPU。

Uboot的入口在start.S這個文件,cpu/s3c64x0/start.S中有這樣一段代碼:

#ifdef CONFIG_BOOT_MOVINAND

ldr   sp, _TEXT_PHY_BASE

bl     movi_bl2_copy

b     after_copy

#endif

這段代碼是實現SD啓動的關鍵。到了這裏後就執行movi_bl2_copy,這個函數負責將

SD內的uboot完整地複製到SDRAM,這時候完整的uboot也叫BL2,而這個函數其實是

調用瞭如下函數:

CopyMovitoMem(HSMMC_CHANNEL, MOVI_BL2_POS, MOVI_BL2_BLKCNT, (uint *)

BL2_BASE, MOVI_INIT_REQUIRED);

HSMMC_CHANNEL這是SD/MMC通道號,手上板子使用的是CH1,而默認是CH0,因此須要

對這個進行修改。

MOVI_BL2_POS 是須要拷貝的數據位於SD的起始扇區,其計算辦法是這樣的,先獲得

這個SD的總扇區數TOTAL,再減去256K的BL2和8K的BL1所佔的扇區數,最後減去0.5K

的eFuse和0.5K的保留區所佔的扇區數,而這裏還定義SD的扇區爲512B。從這裏能夠

看到和IROM_Fusing_tools對SD卡的處理是徹底對應的。這裏還有一個問題,總扇區

數TOTAL是如何獲得的?從程序來看是從(TCM_BASE - 0x4)這個地址讀取到的,至於

TOTAL是如何被放到這裏的就只能從BL0的代碼找答案了。

MOVI_BL2_BLKCNT是須要複製的扇區數目,這裏就是定義爲256K,這也是爲何必須

把u-boot.bin轉換成256K的文件。

BL2_BASE是目的地址,也就是SDRAM中的地址。這裏定義爲0x57E00000,就是128M 的

SDRAM的最後2M,由於到這裏爲止MMU還沒有打開,所以這裏使用的是物理地址。

MOVI_INIT_REQUIRED這個參數的意義是什麼暫時沒有任何資料說明。

而CopyMovitoMem這個函數的定義是這樣的:

#define CopyMovitoMem(a,b,c,d,e)     (((int(*)(int, uint, ushort, uint *,

int))(*((uint *)(TCM_BASE + 0x8))))(a,b,c,d,e))

這個定義其實是調用了位於TCM_BASE + 0x8這個地址的函數指針,其中TCM_BASE的

值爲0x0C004000,至於這個地址放的是什麼,也沒資料說明。

當複製完BL2後便會跳轉到BL2的start_armboot這個C語言函數中運行了,此後的運行

過程就不須要再分析了
相關文章
相關標籤/搜索