uboot支持S3C6410的SD啓動

這裏使用的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啓動ui

  #define CONFIG_BOOT_MOVINAND   打開movinand啓動指針

  //#define CONFIG_BOOT_ONENAND同步

  //#define CONFIG_BOOT_ONENAND_IROM源碼

  #define     CONFIG_NANDit

  //#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語言函數中運行了,此後的運行過程就不須要再分析了。

相關文章
相關標籤/搜索