为了提高代码的可重用性,uboot-2012-10中将SPL模块标准化,叫做SPL framework.查看uboot-2012-10的README,发现如下:
- SPL framework
CONFIG_SPL
Enable building of SPL globally.
CONFIG_SPL_LDSCRIPT
LDSCRIPT for linking the SPL binary.
CONFIG_SPL_MAX_SIZE
Maximum binary size (text, data and rodata) of the SPL binary.
CONFIG_SPL_TEXT_BASE
TEXT_BASE for linking the SPL binary.
CONFIG_SPL_BSS_START_ADDR
Link address for the BSS within the SPL binary.
CONFIG_SPL_BSS_MAX_SIZE
Maximum binary size of the BSS section of the SPL binary.
CONFIG_SPL_STACK
Adress of the start of the stack SPL will use
CONFIG_SYS_SPL_MALLOC_START
Starting address of the malloc pool used in SPL.
CONFIG_SYS_SPL_MALLOC_SIZE
The size of the malloc pool used in SPL.
CONFIG_SPL_FRAMEWORK
Enable the SPL framework under common/. This framework
supports MMC, NAND and YMODEM loading of U-Boot and NAND
NAND loading of the Linux Kernel.
CONFIG_SPL_DISPLAY_PRINT
For ARM, enable an optional function to print more information
about the running system.
CONFIG_SPL_LIBCOMMON_SUPPORT
Support for common/libcommon.o in SPL binary
CONFIG_SPL_LIBDISK_SUPPORT
Support for disk/libdisk.o in SPL binary
CONFIG_SPL_I2C_SUPPORT
Support for drivers/i2c/libi2c.o in SPL binary
CONFIG_SPL_GPIO_SUPPORT
Support for drivers/gpio/libgpio.o in SPL binary
CONFIG_SPL_MMC_SUPPORT
Support for drivers/mmc/libmmc.o in SPL binary
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR,
CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS,
CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION
Address, size and partition on the MMC to load U-Boot from
when the MMC is being used in raw mode.
CONFIG_SPL_FAT_SUPPORT
Support for fs/fat/libfat.o in SPL binary
CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME
Filename to read to load U-Boot when reading from FAT
CONFIG_SPL_NAND_SIMPLE
Support for drivers/mtd/nand/libnand.o in SPL binary
CONFIG_SYS_NAND_5_ADDR_CYCLE, CONFIG_SYS_NAND_PAGE_COUNT,
CONFIG_SYS_NAND_PAGE_SIZE, CONFIG_SYS_NAND_OOBSIZE,
CONFIG_SYS_NAND_BLOCK_SIZE, CONFIG_SYS_NAND_BAD_BLOCK_POS,
CONFIG_SYS_NAND_ECCPOS, CONFIG_SYS_NAND_ECCSIZE,
CONFIG_SYS_NAND_ECCBYTES
Defines the size and behavior of the NAND that SPL uses
to read U-Boot with CONFIG_SPL_NAND_SIMPLE
CONFIG_SYS_NAND_U_BOOT_OFFS
Location in NAND for CONFIG_SPL_NAND_SIMPLE to read U-Boot
from.
CONFIG_SYS_NAND_U_BOOT_START
Location in memory for CONFIG_SPL_NAND_SIMPLE to load U-Boot
to.
CONFIG_SYS_NAND_HW_ECC_OOBFIRST
Define this if you need to first read the OOB and then the
data. This is used for example on davinci plattforms.
CONFIG_SPL_OMAP3_ID_NAND
Support for an OMAP3-specific set of functions to return the
ID and MFR of the first attached NAND chip, if present.
CONFIG_SPL_SERIAL_SUPPORT
Support for drivers/serial/libserial.o in SPL binary
CONFIG_SPL_SPI_FLASH_SUPPORT
Support for drivers/mtd/spi/libspi_flash.o in SPL binary
CONFIG_SPL_SPI_SUPPORT
Support for drivers/spi/libspi.o in SPL binary
CONFIG_SPL_RAM_DEVICE
Support for running image already present in ram, in SPL binary
CONFIG_SPL_LIBGENERIC_SUPPORT
Support for lib/libgeneric.o in SPL binary
可见,SPL framework有许多的配置项,CONFIG_SPL打开SPL,然后配置其他的选项才起作用
CONFIG_SPL_FRAMEWORK选项关系到common/spl/spl.c和arch/arm/lib/spl.c, 好像不是很好用,目前
CONFIG_SPL_FRAMEWORK时,函数调用顺序为start.S->board_init_f->board_init_r
我们可以不开启CONFIG_SPL_FRAMEWORK配置选项,而只是用配置CONFIG_SPL来打造我们自己的SPL过程,需要修改arch/arm/lib/Makefile
ntroduction:
=====
The idea is to build a mini u-boot(same as UBL in Davinci?) out of the u-boot tree that fits into SoC's internal SRAM (<=64K) and bootloads the real u-boot into the SDRAM, then the real u-boot will load the kernel into the SDRAM and boot it. :-).
Such a mini u-boot is typically called SPL(Second Program Loader) in u-boot terminology.
Duty of SPL:
=====
1> Basic ARM initialization
2> UART console initialization
3> Clocks and DPLL locking (minimal)
4> SDRAM initialization
5> Mux (minimal)
6> BootDevice initialization(based on where we are booting from.MMC1/MMC2/Nand/Onenand)
7> Bootloading real u-boot from the BootDevice and passing control to it.
BTW:
TI's X-loader is just one implemention of SPL out of the u-boot tree, And it depends on the u-boot source tree. same framework with u-boot. The u-boot guys will implement their own SPL in the tree. and then our system will boot without x-loader's help. :-)
参考文献2:http://blog.sina.com.cn/s/blog_60a38c850101og3r.htmlU-Boot SPL framework becomes generic
The 2012.10 release of U-Boot comes with an interesting change: the SPL framework that U-Boot has been using specifically for the OMAP SoC has become generic, and is now being used for other architectures and other ARM SoCs. Read on for a detailed explanation on why SPL is needed, what it is, and how it works in U-Boot.
Most modern SoCs contain a ROM code that is capable of loading a boot code from a non-volatile storage such as a NAND flash or a file located inside of SD card filesystem or USB storage filesystem. This feature removes the need for a flash that can be read directly by the CPU for code execution, such as a NOR flash, and allows to boot directly from cheaper and larger storage devices (NAND flash, SD cards, eMMC, etc.).
However, this ROM code typically creates two important constraints on the boot code:
- A limit in the total size of the boot code. Sometimes the boot code must be as small as a few kilo-bytes, usually a few dozens of kilo-bytes are now possible.
- The boot code cannot be loaded directly into the external RAM, because the ROM code has no idea what are the parameters to configure the SoC memory controller according to the external RAM being used on a particular board. Therefore, the ROM code generally loads the boot code in an SoC-internal memory, often called SRAM.
For those two reasons, the popular open-source bootloaders U-Boot or Barebox usually cannot be directly loaded by the ROM code of such SoCs. SoC vendors have therefore developed their own primary boot loaders, who job is to:
- Comply with the requirement of the ROM code of a particular SoC
- Initialize the memory controller in order to allow access to the external RAM
- Load the second stage bootloader, typically U-Boot or Barebox, into RAM, and execute them.
A few examples of first stage bootloaders in the ARM world are: AT91Bootstrap for AT91SAM9 SoCs from Atmel, X-Loader for OMAP SoCs from TI, imx-bootlets for some i.MX SoCs from Freescale, etc.
Unfortunately, many of those projects are not real open-source projects. Their source code is generally available in order to allow companies making custom boards to re-use them, but there is no version control system for them, no community, everybody keeps his local hacks and modifications and nobody benefits from changes done by others. A sad situation, indeed.
Amongst those first stage bootloaders, X-Loader (for OMAP SoCs) was a special beast: it is by itself a stripped-down version of U-Boot. It re-uses the existing U-Boot code, but removes enough feature (such as the shell, command interaction, and much more) in order to fit withinthe limitations of the ROM code. Originally, X-Loader was however a separate project from U-Boot, so it was a one-time fork and further improvements to U-Boot did not benefit to X-Loader and the X-Loader did not have a big community behind it.
Fortunately, over time the X-Loader mechanism, which mainly consists of selectively disabling parts of U-Boot, has been integrated into the mainline U-Boot. However, it has been done in an OMAP-specific way. This mechanism is called “SPL” as in “Secondary Program Loader”.
The recently released U-Boot version 2012.10 however contains changes from Tom Rini, the OMAP maintainer in U-Boot, and also the interim U-Boot maintainer, that make this SPL mechanism generic and usable by other SoC than OMAP and even other architectures.
After some preparation patches, the core of Tom Rini’s changes is to move the SPL code fromarch/arm/cpu/armv7/omap-common/
to common/spl/
(see this commit), which makes it usable by more platforms.
So for example, when you do:
make CROSS_COMPILE=arm-linux-gnueabi- omap3_beagle_config make CROSS_COMPILE=arm-linux-gnueabi- -j4
The U-Boot build process will actually run twice. First to generate the U-Boot image itself (stored as u-boot.bin
):
[...] arm-linux-gnueabi-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin [...]
Second to generate the U-Boot SPL (stored as spl/u-boot-spl.bin
):
[...] arm-linux-gnueabi-objcopy --gap-fill=0xff -O binary \ /home/thomas/projets/u-boot/spl/u-boot-spl \ /home/thomas/projets/u-boot/spl/u-boot-spl.bin [...]
Of course, the SPL is considerably smaller than the main U-Boot binary. The size of the SPL in the OMAP case is still quite large because it has support for a big number of devices, and support for the FAT filesystem as well.
$ ls -l u-boot.bin spl/u-boot-spl.bin -rwxrwxr-x 1 thomas thomas 46252 oct. 30 20:19 spl/u-boot-spl.bin -rw-rw-r-- 1 thomas thomas 344528 oct. 30 20:19 u-boot.bin
The SPL is built by compiling the code from common/spl/
and a few drivers and coreinfrastructure, but most of the U-Boot doesn’t get compiled. In particular, all the shell and commands are not compiled in. The SPL has a completely hardcoded behavior: it will load an image from a fixed location, to a fixed location in RAM, all those parameters being defined at compile time in the U-Boot board configuration file (include/configs/foo.h
). The core of
the SPL logic is implemented in common/spl/spl.c:board_init_r()
. For example,
if CONFIG_SPL_NAND_SUPPORT
is enabled, it will try to load a secondary bootloader image from NAND using the spl_nand_load_image()
function, implemented in common/spl/spl_nand.c
. In the typical case, the secondary boot loader is loaded from
offset CONFIG_SYS_NAND_U_BOOT_OFFS
in the NAND flash. Finally, execution is transferred to the secondary bootloader using jump_to_image_no_args()
. Of course, there are many other possibilities, like directly loading a Linux kernel from the SPL, without having to go through a full-featured second stage bootloader (see the CONFIG_SPL_OS_BOOT
configuration variable), or loading a file from a FAT filesystem located on a SD card.
Besides the OMAP support which was already using SPL, this mechanism is now being used for more U-Boot platforms:
- Used in the preliminary support for the Altera socfpga Cyclone 5 platform
- Stefan Roese has worked on making the SPL framework usable on PowerPC
- Allen Martin has worked to use the SPL framework for the Tegra ARM SoC family
- Stefano Babic has worked on using the SPL framework for MX35 boards
Hopefully, the existence of a proper SPL framework in U-Boot will encourage more SoC vendors to use this generic mechanism rather than relying on custom first stage bootloader that are veryoften poorly written and badly maintained.