UBOOT之main.c分析

更新时间:2023-05-17 11:21:24 阅读: 评论:0

UBOOT之main.c分析
main.c这个⽂件在common/main.c中定义
兄弟七八个/*******设置环境变量ver**************/
#ifdef CONFIG_VERSION_VARIABLE
{
extern char version_string[ ];
tenv ("ver", version_string);      //设置环境变量ver的值
}
#endif
version_string在lib_arm/board.c中定义:
const char version_string[ ] =鸟白居易的诗
U_BOOT_VERSION" (" U_BOOT_DATE " - " U_BOOT_TIME ")"CONFIG_IDENT_STRING;
数组中的那些都是⼀些已经定义好的宏
/****************初始化uboot_hush******************************/
u_boot_hush_start ();
#if defined(CONFIG_HUSH_INIT_VAR)
hush_init_var ();                                        //初始化hush
#endif
u_boot_hush_start 函数在common/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 = 0;
top_vars->flg_export = 0;
top_vars->flg_read_only = 1;
#ifndef CONFIG_RELOC_FIXUP_WORKS
u_boot_hush_reloc();                    //定义上⾯那个宏,这个函数不执⾏
#endif
}
return 0;
}
/*********************命令安装⾃动补全功能*******************************************************/
#ifdef CONFIG_AUTO_COMPLETE
install_auto_complete();
#endif
install_auto_complete这个函数在common/command.c中定义:
void install_auto_complete(void)
{
install_auto_complete_handler("printenv", var_complete);    //安装⾃动补全功能,var_complete就是实现⾃动补全功能的函数install_auto_complete_handler("tenv", var_complete);
#if defined(CONFIG_CMD_RUN)
install_auto_complete_handler("run", var_complete);
#endif
}
install_auto_complete_handler这个函数在common/command.c中定义:
static void install_auto_complete_handler(const char *cmd,
int (*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[]))
{
cmd_tbl_t *cmdtp;
cmdtp = find_cmd(cmd);            //查找要安装⾃动补全功能的命令
if (cmdtp == NULL)
return;
cmdtp->complete = complete;        //将⾃动补全功能的函数赋值给这个命令结构体中的complete成员
}
/******************设置bootdelay 的值********************/
#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
s = getenv ("bootdelay");            //获取环境变量bootdelay的值
bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;  //如果获取到的bootdelay值不为0,则将这个字符串                                                                                                                                    //转换成long型,否则使⽤CONFIG_BOOTDELAY s = getenv ("bootcmd");                    //获得环境变量bootcmd的值,也就是获取启动命令
if (bootdelay >= 0 && s && !abortboot (bootdelay)) {      //倒计时,如果倒计时内没有按下任何键,则执⾏if中的内容,启动内核
# ifndef CONFIG_SYS_HUSH_PARSER
run_command (s, 0);                //运⾏启动内核的命令
# el
par_string_outer(s, FLAG_PARSE_SEMICOLON  |  FLAG_EXIT_FROM_LOOP);  //运⾏启动内核的命令
# endif
}
abortboot 在common/main.c中定义:
static __inline__ int abortboot(int bootdelay)
{
int abort = 0;
#ifdef CONFIG_MENUPROMPT                        //此宏没有被定义
printf(CONFIG_MENUPROMPT);
#el
printf("Hit any key to stop autoboot: %2d ", bootdelay);    //打印出倒计时的信息
#endif
#if defined CONFIG_ZERO_BOOTDELAY_CHECK
if (bootdelay >= 0) {                                        //
if (tstc()) {  /* we got a key press  */      //tstc主要⽤于检查是否有输⼊
(void) getc();  /* consume input  */      //如果有输⼊则⽤getc消耗这个输⼊
puts ("\b\b\b 0");                                    //当有⼀个输⼊后,倒计时的数⽴刻变为0
党校学习总结
abort = 1;  /* don't auto boot  */    //将abort置1,这样函数返回后,就不会执⾏if中的语句,也就不会⾃动启动内核
}
}
#endif
while ((bootdelay > 0) && (!abort)) {            //这⾥开始真正的倒计时,只要bootdelay⼤于0,且abort没有被置1,那么就会
int i;                                                          //循环倒计时
--bootdelay;                                        //每当进来⼀次,bootdelay的值减1
/* delay 100 * 10ms */
qwordfor (i=0; !abort && i<100; ++i) {                //循环检测是否有输⼊
if (tstc()) {  /* we got a key press  */      //tstc主要⽤于检查是否有输⼊
abort  = 1;  /* don't auto boot  */        //如果有输⼊,则将abort置1
bootdelay = 0;  /* no more delay*/    //并且将bootdelay的值赋值为0
(void) getc();  /* consume input  */        //消耗这个输⼊
# endif
break;                                                        //跳出循环
}
udelay(10000);                    //延时
}
printf("\b\b\b%2d ", bootdelay);            //打印倒计时的值
}
putc('\n');    //打印⼀个换⾏符
return abort;
}
run_command 函数在common/main.c中定义:
int run_command (const char *cmd, int flag)
{
cmd_tbl_t *cmdtp;
char cmdbuf[CONFIG_SYS_CBSIZE];  /* working copy of cmd  */
char *token;  /* start of token in cmdbuf  */
char *p;  /* end of token (parator) in cmdbuf */
char finaltoken[CONFIG_SYS_CBSIZE];
char *str = cmdbuf;
char *argv[CONFIG_SYS_MAXARGS + 1];  /* NULL terminated  */
int argc, inquotes;
int repeatable = 1;
int rc = 0;
clear_ctrlc();  /* forget any previous Control C */        //清除ctrl+c
if (!cmd || !*cmd) {                            //如果命令为空,则返回
return -1;  /* empty command */
}
if (strlen(cmd) >= CONFIG_SYS_CBSIZE) {        //如果命令的长度⼤于规定的最⼤长度,返回puts ("## Command too long!\n");
return -1;
}
strcpy (cmdbuf, cmd);                    //将命令复制到cmdbuf中
/* 分隔命令循环:根据’;’ 将命令序列分隔成多条命令,结果放⼊token */
while (*str) {
/*
* Find parator, or string end
* Allow simple escape of ';' by writing "\;"
*/
for (inquotes = 0, p = str; *p; p++) {
if ((*p=='\'') &&
(*(p-1) != '\\'))
inquotes=!inquotes;
if (!inquotes &&
(*p == ';') &&  /* parator  */
桃运青年
( p != str) &&  /* past string start  */
(*(p-1) != '\\'))  /* and NOT escaped  */
break;
}
/*
* Limit the token to data between parators
*/
token = str;
if (*p) {
str = p + 1;  /* start of command for next pass */
*p = '\0';
}
el
str = p;  /* no more commands for next pass */
#ifdef DEBUG_PARSER
printf ("token: \"%s\"\n", token);
#endif
/* find macros in this token and replace them */
process_macros (token, finaltoken);            //处理命令中的宏替换
/* Extract arguments */
qq登陆记录if ((argc = par_line (finaltoken, argv)) == 0) {    //解析命令参数
rc = -1;  /* no command at all */
continue;
}
/* Look up command in command table */
if ((cmdtp = find_cmd(argv[0])) == NULL) {        //在命令表中寻找命令
printf ("Unknown command '%s' - try 'help'\n", argv[0]);    //找不到就打印这句话rc = -1;  /* give up after bad command */
continue;                                                //返回继续分割命令
}
/* found - check max args */
if (argc > cmdtp->maxargs) {    //判断命令最⼤参数个数
cmd_usage(cmdtp);        //如果超出命令最⼤参数个数,打印⽤法信息
rc = -1;借龟拒虾是啥意思
continue;                      //返回继续分割命令
}
/* bootd命令处理*/
#if defined(CONFIG_CMD_BOOTD)
/* avoid "bootd" recursion */
if (cmdtp->cmd == do_bootd) {
#ifdef DEBUG_PARSER
printf ("[%s]\n", finaltoken);
#endif
if (flag & CMD_FLAG_BOOTD) {
puts ("'bootd' recursion detected\n");
rc = -1;
continue;
} el {
flag |= CMD_FLAG_BOOTD;
}
}
#endif
/* OK - call function to do the command */
if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) {    //执⾏命令的处理函数rc = -1;
}
repeatable &= cmdtp->repeatable;        //设置可重复执⾏标记
/* Did the ur stop this? */
if (had_ctrlc ())                        //判断⽤户是否终⽌,ctrl+c
return -1;  /* if stopped then not repeatable */
}
return rc ? rc : repeatable;
}
/****************进⼊交互模式************************/
奇葩说选手#ifdef CONFIG_SYS_HUSH_PARSER
par_file_outer();
/* This point is never reached */
for (;;);
#el
for (;;) {
#ifdef CONFIG_BOOT_RETRY_TIME
if (rc >= 0) {
/* Saw enough of a valid command to
* restart the timeout.
*/
ret_cmd_timeout();
}
#endif
len = readline (CONFIG_SYS_PROMPT);
flag = 0;  /* assume no special flags for now */
if (len > 0)
strcpy (lastcommand, console_buffer);
el if (len == 0)
flag |= CMD_FLAG_REPEAT;
#ifdef CONFIG_BOOT_RETRY_TIME
el 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_ret (NULL, 0, 0, NULL);
# el
return;  /* retry autoboot */
# endif

本文发布于:2023-05-17 11:21:24,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/907876.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:命令   补全   倒计时   功能   启动   参数   打印   返回
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图