基于samsung的Exynos 4412,U-Boot版本为2010.03
在U-Boot启动之第一阶段中,我们知道了U-Boot是通过start_armboot这个函数进入第二阶段的,所以我们从这个函数开始分析。
init_fnc_t **init_fnc_ptr;
char *s;
int mmc_exist = 0;
定义一个二级指针,后面会用到
/* Pointer is writable since we allocated a register for it */
gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));
/* compiler optimization barrier needed for GCC >= 3.4 */
__asm__ __volatile__("": : :"memory");
memset ((void*)gd, 0, sizeof (gd_t));
gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
memset (gd->bd, 0, sizeof (bd_t));
定义一个gd数据结构用来存放一些信息,存放什么信息,感兴趣的自己进去看看,无非就是一些芯片、板子以及系统相关的信息
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang ();
}
}
这里有一个init_sequence,这是一个函数指针数组名,这个数组里面具体有哪些函数,自己去看吧,无非就是一些初始化、设置信息。将这个函数指针赋值给前面定义的二级指针。这段代码的意思就是执行init_sequence里面的初始化函数
for (;;) {
main_loop ();
}
直接到最后,到这里start_armboot这个函数就结束了,下面开始了main_loop
for (;;) {
#ifdef CONFIG_BOOT_RETRY_TIME
if (rc >= 0) {
/* Saw enough of a valid command to
* restart the timeout.
*/
reset_cmd_timeout();
}
#endif
len = readline (CONFIG_SYS_PROMPT);
flag = 0; /* assume no special flags for now */
if (len > 0)
strcpy (lastcommand, console_buffer);
else if (len == 0)
flag |= CMD_FLAG_REPEAT;
#ifdef CONFIG_BOOT_RETRY_TIME
else if (len == -2) {
/* -2 means timed out, retry autoboot
*/
puts ("\nTimed out waiting for command\n");
# ifdef CONFIG_RESET_TO_RETRY
/* Reinit board to run initialization code again */
do_reset (NULL, 0, 0, NULL);
# else
return; /* retry autoboot */
# endif
}
#endif
if (len == -1)
puts ("<INTERRUPT>\n");
else
rc = run_command (lastcommand, flag);
if (rc <= 0) {
/* invalid command or not repeatable, forget it */
lastcommand[0] = 0;
}
}
中间的配置,初始化什么的,我们不看,直接看最后。当我们进入u-boot模式后,其实就是进入了这个循环里面,这个循环的任务就是重复地扫描控制台信息,看看,我们有没有发来什么命令,如果有的话就执行,执行完继续循环扫描,直到我们采取了某些操作终止了这个循环。
u-boot第二阶段到这里就结束了,u-boot第二阶段的主要任务就是准备控制台环境,然后进入一个无限循环等待我们的命令
提示:
不要太在意中间那些初始化代码,因为,对于不同的芯片、不同的板子,这些初始化代码都不一样,所以看这些东西没有什么意义,但是,无论什么样的芯片,什么样的板子,只要是用了u-boot,上面我介绍的流程,它肯定是要经历的。