
本次移植跟以往的不同之處是采用了spl來引導u-boot
本次移植跟以往的不同之處是采用了spl來引導u-boot,參考了部落格http://blog.csdn.net/fulinus/article/details/42738641
下載下傳連結:http://pan.baidu.com/s/1bnlRKgn
使用方法:
1、 編譯
make tq2440_defconfig
make
2、 然後會在u-boot根目錄下生成u-boot.bin,在spl目錄下會生成u-boot-spl.bin,目前的分區是:
u-boot-spl.bin
(1M)
u-boot.bin
kernel
(3M)
rootfs
(剩餘)
自己可以改動,在arch/arm/lib/crt0.S中:
#if defined(CONFIG_SPL_BUILD)
/* Read u-boot from Nandflash to SDRAM address $CONFIG_SYS_TEXT_BASE */
ldr r0, =CONFIG_UBOOT_MTD_ADDR /*u-boot鏡像在NandFlash中存儲位址*/
ldr r1, =CONFIG_SYS_TEXT_BASE /*u-boot在記憶體中的加載位址*/
ldr r2, =CONFIG_UBOOT_LENGTH /*u-boot鏡像的大小*/
bl copy_code_to_sdram
ldr pc, =CONFIG_SYS_TEXT_BASE
#else
bl board_init_f
#endif
3、目前支援NandFlash和DM9000。
4、為什麼要用spl來引導u-boot?
對于tq2440,采用的是S3C2440,當從NandFlash啟動時,上電時S3C2440内部固化的程式自動把NandFlash的前4KB程式拷貝到片内SRAM,然後執行IRAM中的程式,同時要保證這4KB中的程式是位置無關碼,在這4KB程式完成了記憶體的初始化,棧的設定,NandFlash的初始化,将u-boot鏡像從NandFlash中拷貝到記憶體中,将PC跳轉到記憶體中執行。
随着u-boot的更新,在u-boot的前4K已經無法完成上面這些事,在前4KB會執行位置相關碼,導緻u-boot無法正常運作。
為了解決這個問題,u-boot提供了SPL,用spl來引導u-boot,spl的體積很小,隻完成将u-boot從NandFlash中拷貝到記憶體中,然後跳轉到記憶體。
5、可能存在的問題:
由于從NandFlash啟動的時候,IRAM被映射到了0位址處,現在是用spl引導u-boot,是以IRAM中是spl,如果有中斷發生,PC執行的是spl中程式,而不是u-boot中的,可以考慮u-boot啟動後,在将u-boot的前4KB拷貝到IRAM中。
後來再次閱讀了u-boot代碼,發現上面的這個擔心純屬多餘,這個u-boot在代碼重定位,并且修改完相關的符号資訊後,緊接着又将中斷向量也進行了重定位,即将最終u-boot代碼段在記憶體中運作起始位址的前64位元組拷貝到了SRAM的0x0處,這樣如果發生了中斷也不用怕跳飛了。
下面我們簡單看一下:
相關代碼路徑:
中斷向量表:arch/arm/lib/vectors.S
複位異常入口:arch/arm/cpu/arm920t/start.S
_main: arch/arm/lib/crt0.S
board_init_f:common/board_f.c
relocate_code: arch/arm/lib/relocate.S
relocate_vectors: arch/arm/lib/relocate.S
board_init_r:common/board_r.c
main_loop: common/main.c
cli_loop: common/cli.c
parse_file_outer: common/cli_hush.c
crt0.S:
relocate_code 和 relocate_vectors:
這個關于relocation原理的解析參考部落格:
完!