【UBOOT】【run_main_loop】uboot 启动 linux 内核
common/board_r.c文件 run_main_loop 函数
static int run_main_loop(void)
{
/* main_loop() can return to retry autoboot, if so just run it again */
for (;;)
main_loop();
return 0;
}
/*************************************分析*************************************
************************************系统调用***********************************
**************************************结束************************************/
common/main.c 文件 main_loop 函数
void main_loop(void)
{
const char *s;
bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");
setenv("ver", version_string); /* set version variable */
cli_init();
s = bootdelay_process();
autoboot_command(s);
cli_loop();
}
/*************************************分析*************************************
1、设置 main_loop 函数执行标志位
2、设置环境变量 version
3、设置全局变量 top_vars
4、获取 bootdelay 和 bootcmd 环境变量
5、如果没有按键直接启动 linux
6、如果有按键走 cli_loop 函数进入 uboot 命令行模式
************************************系统调用***********************************
**************************************结束************************************/
common/cli.c 文件 cli_init 函数
// common/cli.c
void cli_init(void)
{
u_boot_hush_start();
}
// common/cli_hush.c
int u_boot_hush_start(void)
{
if (top_vars == NULL) {
top_vars = malloc(sizeof(struct variables));
top_vars->name = "HUSH_VERSION";
top_vars->value = "0.01";
top_vars->next = NULL;
top_vars->flg_export = 0;
top_vars->flg_read_only = 1;
}
return 0;
}
/*************************************分析*************************************
struct variables {
char *name;
char *value;
int flg_export;
int flg_read_only;
struct variables *next;
};
设置全局变量 top_vars
************************************系统调用***********************************
**************************************结束************************************/
common/autoboot.c 文件 bootdelay_process 函数
const char *bootdelay_process(void)
{
char *s;
int bootdelay;
s = getenv("bootdelay");
printf("%s:%d:s = %s\n", __func__, __LINE__, s);
bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
printf("Normal Boot\n");
debug("### main_loop entered: bootdelay=%d\n\n", bootdelay);
bootretry_init_cmd_timeout();
s = getenv("bootcmd");
printf("%s:%d:s = %s\n", __func__, __LINE__, s);
process_fdt_options(gd->fdt_blob);
stored_bootdelay = bootdelay;
return s;
}
/*************************************分析*************************************
************************************系统调用***********************************
**************************************结束************************************/
common/autoboot.c 文件 autoboot_command 函数
void autoboot_command(const char *s)
{
if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) {
printf("%s:%d:bootcmd= %s\n", __func__, __LINE__, s);
run_command_list(s, -1, 0);
}
}
/*************************************分析*************************************
stored_bootdelay 不会等于 -1,条件一直成立
s 是有值的,条件也一直成立
abortboot 函数如果按键返回 1,不走if分支
如果没有按键返回 0,走if 分支,调用 run_command_list 函数
run_command_list 函数启动 linux 内核
************************************系统调用***********************************
**************************************结束************************************/
common/autoboot.c 文件 abortboot 函数
static int abortboot(int bootdelay)
{
return abortboot_normal(bootdelay);
}
static int abortboot_normal(int bootdelay)
{
int abort = 0;
unsigned long ts;
bootdelay = 10;
while ((bootdelay > 0) && (!abort)) {
printf("%s:%d:bootdelay = %d,Waiting to choose whether to enter uboot...\n", __func__, __LINE__, bootdelay);
--bootdelay;
/* delay 1000 ms */
ts = get_timer(0);
do {
if (tstc()) {
abort = 1;
bootdelay = 0;
(void) getc();
break;
}
udelay(10000);
} while (!abort && get_timer(ts) < 1000);
}
return abort;
}
/*************************************分析*************************************
等待 10s, 如果有按键事件,返回 1,没有按键事件返回 0
************************************系统调用***********************************
**************************************结束************************************/
common/cli.c 文件 cli_loop 函数
void cli_loop(void)
{
parse_file_outer();
/* This point is never reached */
for (;;);
}
/*************************************分析*************************************
parse_file_outer 函数是命令行处理函数
************************************系统调用***********************************
**************************************结束************************************/