转载 : http://blog.csdn.net/u014381531/article/details/52062257
本人用的是friendlyarm smart4418的板子,用的也是从其github clone下来的uboot-nanopi2的源码,感觉这个uboot特别的复杂,跟网上很多其余板子的教程有很多地方不同,此篇博客是学习的一点记录,欢迎广大网友指正。
上面的一篇博客给了很大帮助,也有别的很多优秀的博客,就没有一一列举。
UBOOT分为两个阶段,第一个阶段主要是汇编代码在START.S文件中实现。在stage1的最后初始化堆栈等操作为stage2C语言的运行提供了环境,最后程序跳入C语言。
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
sub sp, #GD_SIZE /* allocate one GD above SP */
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
mov r9, sp /* GD is above SP */
mov r0, #0
bl board_init_f
mov sp, r9 /* SP is GD's base address */
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
sub sp, #GENERATED_BD_INFO_SIZE /* allocate one BD above SP */
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
mov r0, r9 /* gd_t *gd */
ldr r1, TEXT_BASE /* ulong text */
mov r2, sp /* ulong sp */
bl gdt_reset
/* call board_init_r(gd_t *id, ulong dest_addr) */
mov r0, r9 /* gd_t */
ldr r1, =(CONFIG_SYS_MALLOC_END) /* dest_addr for malloc heap end */
/* call board_init_r */
ldr pc, =board_init_r /* this is auto-relocated! */
#else /* CONFIG_RELOC_TO_TEXT_BASE */
bl _main
#endif
上图是我所用的uboot-nanopi2下arch/arm/cpu/slsip/s5p4418/start.s文件,跟网上的很多教程相比很相似,但是细究起来差别也蛮大的,就上面的代码来说,在擦除了bss后设置可sp指针,然后就跳入board_init_f();函数,在board_init.f函数里面,完成了一系列初始化后再调回来。gdt_reset进行gd结构体的初始化,最后进入到了board_init_r();函数,这个函数就是最后载入内核或者开始uboot命令行的操作。
board_init_f();board_init_r();函数在arch/arm/lib/目录下,board_init_r();函数的一系列初始化操作就不说了,因为我也还没有弄懂具体的初始化机制和原由,直奔主题-------怎么进去的内核。
下图是我粘贴的board_init_r();的完整内容,可以直接略过。
/************************************************************************
*
* This is the next part if the initialization sequence: we are now
* running from RAM and have a "normal" C environment, i. e. global
* data can be written, BSS has been cleared, the stack size in not
* that critical any more, etc.
*
************************************************************************
*/
void board_init_r(gd_t *id, ulong dest_addr)
{
ulong malloc_start;
#if !defined(CONFIG_SYS_NO_FLASH)
ulong flash_size;
#endif
gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */
bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r");
monitor_flash_len = (ulong)&__rel_dyn_end - (ulong)_start;
/* Enable caches */
enable_caches();
debug("monitor flash len: %08lX\n", monitor_flash_len);
board_init(); /* Setup chipselects */
/*
* TODO: printing of the clock inforamtion of the board is now
* implemented as part of bdinfo command. Currently only support for
* davinci SOC's is added. Remove this check once all the board
* implement this.
*/
#ifdef CONFIG_CLOCKS
set_cpu_clk_info(); /* Setup clock information */
#endif
serial_initialize();
debug("Now running in RAM - U-Boot at: %08lx\n", dest_addr);
#ifdef CONFIG_LOGBUFFER
logbuff_init_ptrs();
#endif
#ifdef CONFIG_POST
post_output_backlog();
#endif
/* The Malloc area is immediately below the monitor copy in DRAM */
malloc_start = dest_addr - TOTAL_MALLOC_LEN;
mem_malloc_init (malloc_start, TOTAL_MALLOC_LEN);
#ifdef CONFIG_ARCH_EARLY_INIT_R
arch_early_init_r();
#endif
#ifndef CONFIG_PMIC_REG_DUMP
power_init_board();
#endif
#if !defined(CONFIG_SYS_NO_FLASH)
puts("Flash: ");
flash_size = flash_init();
if (flash_size > 0) {
# ifdef CON