uboot执行顺序main_loop

来源:互联网 发布:安卓手机变电脑软件 编辑:程序博客网 时间:2024/06/08 00:40
uboot执行过程中会经过common/main.c
在main.c中会有一个main_loop函数,是main.c中的出口函数,被arch/arm/lib/start_armboot函数调用会解析bootdelay变量,并延时    在延时中如果被中断,则会执行一个循环,循环中readline并执行 run_command    如果没被中断,会解析变量boot_cmd里面的变量,并执行
run_command    1/判断了长度    2/依据;截取字符串,得到一个一个的命令    3/去掉宏,得到一个解析过的命令    4/分析一个命令得到 命令名 和 参数    5/依次将 命令名 和 结构体数组 中的结构体成员的第一个参数 name 进行比较,判断是否相等.相等说明是合法命令    6/判断合法命令的 参数个数 是否合法    7/调用命令在上述序列中, 步骤 5 最难理解
其实步骤5中的结构体数组并没有在程序中定义.而是依靠段的用法将这些结构体存到了指定的段中.然后在链接的时候将各个文件的这个段 连接到一个输出文件的 段中,也就是将这些结构体放到了一起,所以就像我之前说的结构体数组.下面分为两个部分说1/输入文件中的段    它是用宏函数 U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) 做的   宏函数的定义在include/command.h中    #define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}  假设这个命令是bootm  U_BOOT_CMD(bootm, 16, 1, do_bootm, “bootm--usage”, “help”)  最后展开会成为这个样子  cmd_tbl_t  __u_boot_cmd_ bootm  __attribute__ ((unused,section (".u_boot_cmd"))) = {“bootm”, 16, 1, do_bootm, “bootm--usage”}上面的这一句是这么解释的,定义一个结构体 变量 ,类型为  cmd_tbl_t ,初始化为{“bootm”, 16, 1, do_bootm, “bootm--usage”} ,至于这些  __u_boot_cmd_ bootm  __attribute__ ((unused,section (".u_boot_cmd")))  我还不会很清楚,明天再查查,但是section (".u_boot_cmd")这一句话,是要求把这个变量放到 中间目标文件的 u_boot_cmd 段2/输出文件中的段  连接的时候会读取链接文件include/u-boot/u-boot.lds  连接文件被这样解释  按照连接顺序 依次 将输入文件中的 u_boot_cmd 段 放入 输出文件中的  u_boot_cmd 段   include/u-boot/u-boot.lds __u_boot_cmd_start = .; .u_boot_cmd : { *(.u_boot_cmd) } __u_boot_cmd_end = .;

后面的是参考

uboot中的tftp
TftpStart函数是tftp.c的出口函数,被net.c中的NetLoop函数调用netloop函数被 do_bootvx调用
main.c中的  main_loop  调用了readline  然后调用了run_command    然后判断了长度,街区字符串,将宏去掉,得到一个命令      然后分析得到命令和参数,    并和表里面的命令进行比较,判断是否为合法命令,(是否在表中)cmd_tbl_t *find_cmd (const char *cmd){    int len = &__u_boot_cmd_end - &__u_boot_cmd_start;    return find_cmd_tbl(cmd, &__u_boot_cmd_start, len);}    判断出来合法后,判断命令的参数个数是否正确,然后,调用函数        if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) {            rc = -1;        }__u_boot_cmd_start 这个东西在哪里----  #define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}  /*************************************************************************** * find command table entry for a command */cmd_tbl_t *find_cmd_tbl (const char *cmd, cmd_tbl_t *table, int table_len){    cmd_tbl_t *cmdtp;    cmd_tbl_t *cmdtp_temp = table;  /*Init value */    const char *p;    int len;    int n_found = 0;    /*     * Some commands allow length modifiers (like "cp.b");     * compare command name only until first dot.     */    len = ((p = strchr(cmd, '.')) == NULL) ? strlen (cmd) : (p - cmd);    for (cmdtp = table;         cmdtp != table + table_len;         cmdtp++) {        if (strncmp (cmd, cmdtp->name, len) == 0) {            if (len == strlen (cmdtp->name))                return cmdtp;   /* full match */            cmdtp_temp = cmdtp; /* abbreviated command ? */            n_found++;        }    }    if (n_found == 1) {         /* exactly one match */        return cmdtp_temp;    }    return NULL;    /* not found or ambiguous command */}cmd_tbl_t * cmdtp;typedef struct cmd_tbl_s    cmd_tbl_t;  struct cmd_tbl_s {    char        *name;      /* Command Name         */    int     maxargs;    /* maximum number of arguments  */    int     repeatable; /* autorepeat allowed?      */                    /* Implementation function  */    int     (*cmd)(struct cmd_tbl_s *, int, int, char *[]);    char        *usage;     /* Usage message    (short) */#ifdef  CONFIG_SYS_LONGHELP    char        *help;      /* Help  message    (long)  */#endif#ifdef CONFIG_AUTO_COMPLETE    /* do auto completion on the arguments */    int     (*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[]);#endif};

http://blog.chinaunix.net/uid-20672257-id-2899526.html

U_BOOT_CMD(    tftp,   4,  1,  do_tftp,    "tftp\t- download or upload image via network using TFTP protocol",    "[loadAddress] [bootfilename] <upload_size>");int do_tftp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){    return netboot_common (TFTP, cmdtp, argc, argv);}NetLoop  TftpStart
所以,底层被TftpStart封装起来了TftpStart函数是tftp.c的出口函数,被net.c中的NetLoop函数调用netloop函数被 do_bootvx调用
原创粉丝点击