在uboot启动流程关键函数介绍(一)介绍_main函数的过程,至此以将uboot的代码拷贝到DDR中,下面主要讲解uboot命令的相关处理函数。
run_main_loop函数(在common/board_r.c中):uboot启动后3秒倒计时,如果在3秒倒计时结束前按下回车键,那么就会进入uboot的命令模式,如果没有按下回车键,那么就会自动启动linux内核。
先进入死循环,死循环中有一个main_loop函数(在common/main.c中定义)
main_loop函数:调用bootstage_mark_name函数,打印出启动进度,调用setenv函数将变量ver的值设为version_string,也就是设置版本号的环境变量。调用cli_init函数初始化命令,初始化hush shell相关的变量。Bootdelay_process函数用于读取环境变量bootdelay和bootcmd的内容,然后将bootdelay的值赋值给全局变量stored_bootdelay,返回bootcmd的值。
autoboot_command函数,此函数检查倒计时是否结束,倒计时结束前是否被打断。如果倒计时正常结束,就会执行run_command_list,此函数会执行参数s指定的一系列命令,也就是环境变量bootcmd的命令,bootcmd中保存着默认的启动命令,因此linux内核启动。如果在倒计时结束钱按下回车键,run_command_list就不会执行,相当于空函数,然后执行cli_loop函数,这个是命令行处理函数,负责接收处理输入命令。
总结一下main_loop函数,开始会调用一些函数,设置一些环境变量,初始化hush shell等,接着调用auto_command函数,用于判断倒计时前键盘是否按下,如果按下就执行cli_loop函数,如果没有按下,就直接启动linux内核。
cli_loop函数是uboot命令行处理函数,输入的各种命令,进行各种操作就是cli_loop函数来处理的,此函数定义在command/cli.c中
cli_loop会调用parse_file_outer函数
parse_file_outer先调用setup_file_str函数初始化input的成员变量;再调用parse_stream_outer函数,该函数就是 hush shell的命令解释器,使用do-while循环接收命令行输入,然后利用函数parse_stream函数解析,调用run_list函数在经过一系列函数调用cmd_process函数来处理命令。
cmd_process函数
在uboot中,命令是通过宏U-BOOT-CMD来定义,最终目的是为了定义一个cmd_tbl_t类型的变量,并初始化这个变量的各个成员。Uboot中的每个命令都存放在.uboot_boot_list段中,每个命令都有一个名为do_xxx(xxx为具体的命令名)的函数,这个do_xxx函数就是具体的命令处理函数。了解了uboot中命令的组成再来看一下cmd_process函数的处理过程。
cmd_process在common/command.c中定义。通过调用find_cmd函数在命令表中找到指定的命令,命令表其实就是cmd_tlb_t结构体数组,在find_cmd函数中通过函数ll_entry_start得到数组的第一个元素,也就是命令表起始地址,通过ll_entry_count得到数组长度,也就是命令表的长度,最后通过find_cmd_tlb在命令表中找到所需的命令。
在命令表中找到命令以后,就调用cmd_call函数来执行具体的命令