在U-boot目錄下,有個比較重要的目錄就是SPL的,SPL到底是什么呢?為什么要用它呢?
SPL(Secondary programloader)是uboot第一階段執行的代碼。主要負責搬移uboot第二階段的代碼到
系統內存(System Ram,也叫片外內存)中運行。SPL是由固化在芯片內部的ROM引導的。我們知道很多芯
片廠商固化的ROM支持從nandflash、SDCARD等外部介質啟動。所謂啟動,就是從這些外部介質中搬移一段
固定大小(4K/8K/16K等)的代碼到內部RAM中運行。這里搬移的就是SPL。在最新版本的uboot中,可以看到
SPL也支持nandflash,SDCARD等多種啟動方式。當SPL本身被搬移到內部RAM中運行時,它會從nandflash、
SDCARD等外部介質中搬移uboot第二階段的代碼到系統內存中。
SPL復用的是uboot里面的代碼.
SPL的主要功能就是銜接系統的硬件SRAM和u-boot之間的紐帶。
1.BasicArm Initialization
2.UART console initialization
3.Clocks and DPLL Locking(minimal)
4.SDRAM initialization
5.Mux(minimal)
6.Boot Device Initialization, based on where we are booting from MMC1, or MMC2,or Nand, or Onenand
7.Bootloading real u-boot from the Boot Device and passing control to it.
怎么編譯SPL呢?
上文中說道“SPL復用的是uboot里面的代碼”,那要生成我們所需要的SPL目標文件,我們又該如何下手呢?
很容易想到,通過編譯選項便可以將SPL和uboot代碼分離、復用。這里所說的編譯選項便是CONFIG_SPL_BUILD,
在make Kconfig的時候使能。最終編譯生成的SPL二進制文件有u-boot-spl,u-boot-spl.bin以及u-boot-spl.map。
源碼流程
從ARM的啟動流程上來看,可以看出SPL在哪一層的:
RomBoot --> SPL --> u-boot --> Linux kernel --> file system --> start application
(RomBoot是固化在SoC內部的。)
容易想到,通過編譯選項便可以將SPL和uboot代碼分離、復用。這里所說的編譯選項便是CONFIG_SPL_BUILD,
在make Kconfig的時候使能。最終編譯生成的SPL二進制文件有u-boot-spl,u-boot-spl.bin以及u-boot-spl.map。
SPL的啟動一般要從鏈接文件看,鏈接文件決定一個可執行程序的各個段的存儲(加載)地址,以及運行(鏈接)地址。
下面來看看SPL的鏈接文件U-boot-spl.lds:
4 OUTPUT_ARCH(arm) 5 ENTRY(_start) 6 SECTIONS 7 { 8 .text : 9 { 10 __start = .; 11 *(.vectors) 12 arch/arm/cpu/armv7/start.o (.text*) 13 *(.text*) 14 } >.sram
從lds的起始地址來看,這里面主要撒地方做了兩件事情,一個是
*(.vectors)是調用中斷向量表:arch/arm/lib/vectors.S 另外
一個就是運行啟動代碼:
arch/arm/cpu/armv7/start.o (.text*)
在啟動代碼start.S中,代碼的流程是什么樣的呢?
(reset) <arch/arm/cpu/armv7/start.S > (b lowlevel_init: arch/arm/cpu/armv7/lowlevel_init.S)
(b _main) --> <arch/arm/lib/crt0.S> (bl board_init_f) --> <arch/arm/lib/spl.c> (board_init_r)
--> <common/spl/spl.c> (jump_to_image_no_args去啟動u-boot)
到此SPL的生命周期結束。
到此SPL的分析流程結束了,這里只做個粗略的分析,后面再針對每個部分做詳細的介紹。
參考文檔:
1 http://blog.csdn.net/voice_shen/article/details/17373671
2 http://bbs.chinaunix.net/thread-4248378-1-1.html