U-boot移植遇到的一些问题

U-Boot,全称 Universal Boot Loader,是遵循GPL条款的开放源码项目。U-Boot的作用是系统引导。U-Boot从FADSROM、8xxROM、PPCBOOT逐步发展演化而来。其源码目录、编译形式与Linux内核很相似,事实上,不少U-Boot源码就是根据相应的Linux内核源程序进行简化而形成的,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点。-----百度百科

U-boot源码分析

移植U-boot之前,我们首先需要弄明白U-boot本身是怎么运行的,移植的时候需要修改那些东西,这些实际都可以通过阅读源代码实现,这里我们下载的是Emcraft的源码包,因为最终是要在cortex-M系列的处理器上实现。

之所以下载emcraft的源码包是因为里面已经做了一些相关的porting工作了,比如针对cortex-m系列的启动函数就在cpu/arm-cortexm3/start.c,下面就是一个简化的_start函数:

void _start(void)
{
#if !defined(CONFIG_HW_WATCHDOG)
#if !defined(CONFIG_SYS_M2S)
    wdt_disable();
#endif
#else
    wdt_enable();
#endif

    /*
     * Make sure interrupts are disabled.
     */
    __disable_irq();
    /*
     * Copy data and initialize BSS
     * This is in lieu of the U-boot "conventional" relocation
     * of code & data from Flash to RAM.
     * With Cortex-M3, we execute from NVRAM (internal Flash),
     * having relocated data to internal RAM (and having cleared the BSS
     * area in internal RAM as well)
     * Stack grows downwards; the stack base is set-up by the first
     * value in the first word in the vectors.
     */
    memcpy(&_data_start, &_data_lma_start, &_data_end - &_data_start);
    memset(&_bss_start, 0, &_bss_end - &_bss_start);

    /*
     * Copy RAMCODE separately, if it is separated
     */
#if defined(CONFIG_MEM_RAMCODE_BASE) && defined(CONFIG_MEM_RAMCODE_LEN)
    memcpy(&_ramcode_start, &_ramcode_lma_start,
        &_ramcode_end - &_ramcode_start);
#endif
    /*
     * In U-boot (armboot) lingvo, "go to the C code" -
     * in fact, with M3, we are at the C code from the very beginning.
     * In actuality, this is the jump to the ARM generic start code.
     * ...
     * Note initialization of _armboot_start below. The ARM generic
     * code expects that this variable is set to the upper boundary of
     * the malloc pool area.
     * For Cortex-M3, where we do not relocate the code to RAM, I set
     * the malloc pool right behind the stack. See how armboot_start
     * is defined in the CPU specific .lds file.
     */
    _armboot_start = (unsigned long)&_mem_stack_base;
    start_armboot();

}  

这里就是一个比较基本的memor初始化,之后就跳转到和具体CPU以及板子相关的start_armboot函数中去了,在start_armboot中,uboot首先会初始化一个全局变量gdbd,它们占用内存的一段固定区域。再后面就是一系列的初始化函数,这些函数根据不同的板子也有不同,不过基本都是:

  1. arch_cpu_init --- CPU clock init
  2. board_init --- pin相关的init
  3. interrupt
  4. timer_init
  5. get_clocks
  6. env_init -- 初始化环境变量,这个对u-boot非常重要,我为了简单就没有把环境变量放到Flash里面,而是直接编译的时候弄好,直接放在ram里面,这样就不支持变量的保存操作了。
  7. init_baudrate
  8. serial_init --- 串口的初始化,这个我为了简单也是直接用了固定的串口波特率。
  9. console_init_f --- 基本平台无关,可以直接调用
  10. dram_init --- 初始化SDRAM,因为一般cortex-M系列处理器RAM都比较小,所以程序需要在SDRAM里面运行,所以要对SDRAM进行初始化,当然如果支持DDR这里就是初始化DDR了。
    11.NULL --- 结束初始化循环的一个标志

在初始化完成这个序列之后,我i们还可以选择是不是将堆栈改到SDRAM上去,另外如果系统支持LCD显示等,还需要对显存空间进行必要的初始化操作了。

所有的初始化函数执行完成这之后就会跳转到main_loop,他是在一个死循环中不停的执行的。也是最终u-boot执行的一个循环,提供一个用户终端界面,可以对用户命令进行解析,启动系统镜像以及对参数配置等等。

总结

以上就是对uboot启动流程的一个非常简单的介绍,其实uboot关键的还是在最后的一个大的循环上面,另外一个就是内存的分配,总的来说u-boot还是比较简单的,后面有时间我们再来看看main_loop里面究竟执行了哪些程序,以及u-boot是如何实现系统的启动的。

你可能感兴趣的:(U-boot移植遇到的一些问题)