一直以來都不知道sd卡中的uboot和nandflash中的uboot有什麼區別?今天終於看到一篇文章,介紹了一下兩者的區別,和如何用原生uboot製作sd卡uboot,記錄下來以供後面查閱。
找到了原出處:
6410的手冊上說,可以從nandflash、onenand、sd卡啟動,沒有專用的燒錄工具的情況下,只有sd卡啟動是可以考慮 的。手冊上看到,sd卡啟動,實際上是先執行片內irom中的一段程式,該程式從sd卡中讀取**,寫到stepping stone 中,stepping stone是位於0x0c000000、size為8k的片內記憶體,**寫入stepping stone後,跳到 0x0c000000處繼續執行程式。那麼,要實現從sd卡啟動,就必須弄清楚:
1、8k的**儲存在sd卡的什麼位置。
2、**以什麼格式儲存。
把編譯好的**寫入到最後晶元末尾偏移-9216位元組處,插入sd卡座,把開關撥到sd0卡啟動的位置,上電
這裡使用的uboot並非uboot官方發布的uboot**,而是為三星定製的乙個uboot版本
s3c-u-boot-1.1.6,其**作者就包括了三星的程式設計師與denx的員工。這個版本支援
sd啟動,不過預設是nand啟動,使它支援uboot需要做以下事情:
1、 雖然支援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的操作
2、如果單純是做上面的改動,還是不夠的,在執行的時候會發現到了一定的時候
uboot就死掉了,其實這是因為uboot中假設smdk6410在使用sd方式的時候是從ch0啟
動的,但是手上的這個板子是通過ch1啟動,那麼在執行被複製到sram中的8k**時
候沒辦法在ch0檢測到sd,更沒辦法將sd 裡的**複製到sdram中。修改辦法是在
incluede/
movi.h中hsmmc_channel修改為1。
3、然後如果將上述修改後編譯出來的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的
原始碼來揭示其中的由來。
讀取這個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語言函式中執行了,此後的執行
過程就不需要再分析了
使uboot支援S3C6410的SD啟動
這裡使用的uboot並非uboot官方發布的uboot 而是為三星定製的乙個uboot版本s3c u boot 1.1.6,其 作者就包括了三星的程式設計師與denx的員工。這個版本支援sd啟動,不過預設是nand啟動,使它支援uboot需要做以下事情 1 雖然支援uboot啟動,但是uboot 裡...
使uboot支援S3C6410的SD啟動
這裡使用的uboot並非uboot官方發布的uboot 而是為三星定製的乙個uboot版本s3c u boot 1.1.6,其 作者就包括了三星的程式設計師與denx的員工。這個版本支援sd啟動,不過預設是nand啟動,使它支援uboot需要做以下事情 1 雖然支援uboot啟動,但是uboot 裡...
使uboot支援S3C6410的SD啟動
這裡使用的uboot並非uboot官方發布的uboot 而是為三星定製的乙個uboot版本s3c u boot 1.1.6,其 作者就包括了三星的程式設計師與denx的員工。這個版本支援sd啟動,不過預設是nand啟動,使它支援uboot需要做以下事情 1 雖然支援uboot啟動,但是uboot 裡...