tag 标签: spl

相关博文
  • 热度 12
    2014-8-27 14:55
    1417 次阅读|
    0 个评论
    “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去执行;
  • 热度 19
    2014-8-27 14:55
    3216 次阅读|
    2 个评论
    U-Boot for AM335x (8) spl如何调用u-boot.img am335x的mainline里面,有一个EEPROM,spl会使用I2C协议,读取存储在EEPROM里面的配置header,然后根据这个header来进行之后的操作。header是出厂的时候由厂家外部写入的,Forlinx的OK335xD板虽然也配有EEPROM芯片,但是里面的内容是空的。因此使用mainline来调试OK335xD板的时候,需要将有关EEPROM的内容去掉,将实际的硬件内容替换进入。 根据自己的硬件修改SPL,相对来说并不复杂。因为u-boot的mainline里面基本上包含了所有主流硬件的参数,只需传递和自己的硬件对应的就行,比如DDR时钟频率,PMIC的型号和输出,以及GPIO的MUX外设配置初始化等等。 到使用I2C0、设置PMIC都是比较简单的,真正麻烦的地方在于spl结束的时候读取u-boot.img。在前面的(6)spl中已经简单的提到了启动流程,而读取u-boot.img的关键在于common/spl/spl.c中的board_init_r函数: void board_init_r(gd_t *dummy1, ulong dummy2) ---- spl_mmc_load_image(); -------- if (spl_start_uboot() || spl_load_image_fat_os(mmc-block_dev, CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION)) (在这个函数中会试图读取CONFIG_SYS_SPL_ARGS_ADDR(=0x80F80000)的args文件,如果这个文件不存在,则退出这个函数,继续执行spl_mmc_load_image) -------- err = spl_load_image_fat(mmc-block_dev,                 CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION,                 CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME); (在这个函数中会试图读取CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME,也就是u-boot.img。CONFIG_SYS_TEXT_BASE的值为0x80800000,而AM335x的存储器映射,分配给SDRAM的正是0x80000000。这里会调用file_fat_read函数读取两次u-boot.img,这应该和u-boot.img在SD卡上的存储方式有关。anyway,读取完成之后,跳出这个函数。) ---- jump_to_image_no_args(spl_image); -------- image_entry((u32 *)gd-arch.omap_boot_params); (跳到u-boot.img去执行。这里需要插入一个小tip,关于weak关键字的使用:) ======================================== http://www.valvers.com/programming/c/gcc-weak-function-attributes ======================================== 插入一段gcc中weak关键字的用法: 若两个或两个以上全局符号(函数或变量名)名字一样,而其中之一声明为weak symbol(弱符号),则这些全局符号不会引发重定义错误。链接器会忽略弱符号,去使用普通的全局符号来解析所有对这些符号的引用,但当普通的全局符号不可用时,链接器会使用弱符号。当有函数或变量名可能被用户覆盖时,该函数或变量名可以声明为一个弱符号。弱符号也称为weak alias(弱别名)。 ======================================== jump_to_image_no_args实际上在两个地方都有定义,分别是: common/spl/spl.c:104 arch/arm/cpu/armv7/omap-common/boot-common.c:113 通过添加打印信息,能够观察到被调用的是后者。 通过添加打印信息,能够观察到gd-arch.omap_boot_params的值,为0x40302868,它正好属于AM335x外部SRAM的存储器映射地址空间。spl此时完成了它的使命,除了初始化基本的GPIO、DDR、PMIC之外,还将u-boot.img搬到了SRAM(DDR3)中。