“How to control GPIO"的调试学习都是在SPL中进行的,它运行在u-boot.img之前,做一些更加基础的工作,而实际的u-boot命令行提示符不会在这里出现。之所以有SPL,和ARM的硬件结构是有关系的。因为u-boot.img通常体积不会很小,所以需要SPL先承担一部分基础的工作,除了时钟、PMIC之外,还需要初始化外部的SDRAM,这样才能把u-boot.img放到更大的外部SDRAM中运行。而SPL自身也是使用C语言写的,也需要stack才能运行,所以把它放在系统的内部小SRAM中。

=================================
source README
=================================
The implementation of U-Boot is complicated by the fact that U-Boot starts running out of ROM (flash memory), usually without access to system RAM (because the memory controller is not initialized yet). This means that we don't have writable Data or BSS segments, and BSS is not initialized as zero. To be able to get a C environment working at all, we have to allocate at least a minimal stack. Implementation options for this are defined and restricted by the CPU used: Some CPU models provide on-chip momery (like the IMMR area on MPC8xx and MPC826x processors), on others (parts of) the data cache can be locked as (mis-) used as momery, etc.

================================
TPL: SPL loading SPL
Scott Wood
Freescale Semiconductor
October 2013
================================
Background: What is SPL?
Unlike NOR flash, many boot sources are not directly memory mapped.
On-chip ROM or other mechanism loads a binary into an SRAM.
----This SRAM is often very small, sometimes 4KiB or less.
----The ROM can't load us into main system RAM yet, since initialization is too complex and must be handled by U-Boot.

SPL(Secondary Program Loader) is a small binary, generated from U-Boot source, that fits in the SRAM and loads the main U-Boot into system RAM.

Configure by a paraller set of makefile config symbols-
CONFIGURE_SPL_I2C_SUPPORT, CONFIG_SPL_NAND_SUPPORT.
----Normal CONFIG symbols also used, but not to control the differences between the SPL and the main U-Boot.
----SPL also relies heavily on toolchain garbage collection.
=================================
What can we do in 4KiB?
Not much.
Hardcoded RAM initialization
----Causes problems if a new revision of the board has different RAM, or if RAM is socketed.
----Code to use SPD to dynamically initialize RAM is way too large to fit.

Barely fits even then
----Limited output capability(puts rather than printf)
(好吧,我承认我是一路printf过来的。。。)
----No exception handling
----Toolchain variations ofter cause breakage due to size differences.

=================================
For am335x
=================================
大概的结构是:
arch/arm/cpu/armv7/omap3/lowlevel_init.S调用s_init();
    其中有pll和串口初始化preloader_console_init();
    还有set_mux_conf_regs()和sdram_init()等等;

arch/arm/lib/crt0.S调用board_init_f();
    其中borad_init_f()又调用board_init_r();
    board_init_r()完成spl_board_init()和读取u-boot.img等功能;
    ----spl_board_init()中就包含对PMIC的操作;
    在board_init_r()结束的时候,跳到u-boot.img去执行;