GT2440--U-Boot分析(四)
来源:互联网 发布:局域网多线程编程 编辑:程序博客网 时间:2024/04/29 22:26
run_command()分析:
int run_command (const char *cmd, int flag){cmd_tbl_t *cmdtp;char cmdbuf[CFG_CBSIZE];/* working copy of cmd*/char *token;/* start of token in cmdbuf*/char *sep;/* end of token (separator) in cmdbuf */char finaltoken[CFG_CBSIZE];char *str = cmdbuf;char *argv[CFG_MAXARGS + 1];/* NULL terminated*/int argc, inquotes;int repeatable = 1;int rc = 0;clear_ctrlc();/* forget any previous Control C */if (!cmd || !*cmd) {return -1;/* empty command */}if (strlen(cmd) >= CFG_CBSIZE) {puts ("## Command too long!\n");return -1;}strcpy (cmdbuf, cmd);while (*str) {/* * Find separator, or string end * Allow simple escape of ';' by writing "\;" */for (inquotes = 0, sep = str; *sep; sep++) {if ((*sep=='\'') && (*(sep-1) != '\\'))inquotes=!inquotes;if (!inquotes && (*sep == ';') &&/* separator*/ ( sep != str) &&/* past string start*/ (*(sep-1) != '\\'))/* and NOT escaped*/break;}/* * Limit the token to data between separators */token = str;if (*sep) {str = sep + 1;/* start of command for next pass */*sep = '\0';}elsestr = sep;/* no more commands for next pass *//* find macros in this token and replace them */process_macros (token, finaltoken);/* Extract arguments */if ((argc = parse_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) {printf ("Usage:\n%s\n", cmdtp->usage);rc = -1;continue;}#if (CONFIG_COMMANDS & CFG_CMD_BOOTD)/* avoid "bootd" recursion */if (cmdtp->cmd == do_bootd) {if (flag & CMD_FLAG_BOOTD) {puts ("'bootd' recursion detected\n");rc = -1;continue;} else {flag |= CMD_FLAG_BOOTD;}}#endif/* CFG_CMD_BOOTD *//* OK - call function to do the command */if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) {rc = -1;}repeatable &= cmdtp->repeatable;/* Did the user stop this? */if (had_ctrlc ())return 0;/* if stopped then not repeatable */}return rc ? rc : repeatable;}
上述代码为删减后的run_command()函数代码并不是很难,且代码中有着较为详细的注释。其中应注意如下两句代码:
if ((cmdtp = find_cmd(argv[0])) == NULL)/* 在u_boot_com数据段下查询是否有这个指令 */
if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) /* 调用实现该指令的函数 */
下面进行find_cmd()函数的分析,这函数相对较为简短;
cmd_tbl_t *find_cmd (const char *cmd){cmd_tbl_t *cmdtp;cmd_tbl_t *cmdtp_temp = &__u_boot_cmd_start;/*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 = &__u_boot_cmd_start; cmdtp != &__u_boot_cmd_end; 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 */}
重点留意如下代码:
1、cmd_tbl_t结构体:
struct cmd_tbl_s {char*name;/* Command Name*/intmaxargs;/* maximum number of arguments*/intrepeatable;/* autorepeat allowed?*//* Implementation function*/int(*cmd)(struct cmd_tbl_s *, int, int, char *[]);char*usage;/* Usage message(short)*/#ifdefCFG_LONGHELPchar*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};typedef struct cmd_tbl_scmd_tbl_t;
2、查询u_boot_cmd数据段的for循环寻找合适的指令
for (cmdtp = &__u_boot_cmd_start; cmdtp != &__u_boot_cmd_end; cmdtp++)
要查询此数据段那则次数据段必须建立一组命令表,通过如下步骤建立这个表:
一、添加结构体定义
U_BOOT_CMD(menu,3,0,do_menu,"menu - display a menu, to select the items to do something\n"," - display a menu, to select the items to do something");
二、此命令的实现函数
int do_menu (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){menu_shell();return 0;}
其中上面循环中使用到的__u_boot_cmd_start与__u_boot_cmd_end均定义在u_boot.lds连接脚本中;
cmdtp = &__u_boot_cmd_start; /* u_boot_cmd数据段的__u_boot_cmd_start地址的内容取出存放至cmdtp中 */
此时进行.u_boot_cmd数据段查询的如下代码:
#define Struct_Section __attribute__ ((unused,section (".u_boot_cmd")))
并得到如下的宏定义:
#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}
例如增加一个toraloo命令,则上述宏可展开为:
cmd_tbl_t __u_boot_cmd_toraloo Struct_Section = {“toraloo”, 3, 1, do_toraloo, “string 1”, “string 2”};
toraloo命令可仿照menu命令编写如:
U_BOOT_CMD(toraloo3,1,do_toraloo,"toraloo - I am toraloo,HAHAHA.......\n"," TORALOO is toraloo,ToraLoo is toraloo");int do_menu (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){int i;printf(“this is a test! %d\n”,argc);for(i=0; i<argc; i++) { printf(“argv[%d] = %s\n”,i,argv[i]); }return 0;}
再此文件中添加部分头文件,在对/command/makefile下增加cmd_toraloo.o的编译项重新再编译一次u-boot,再将其下载即可看见toraloo这个命令了。
U-boot下的内核启动命令:bootm
输入bootm运行时相当于运行了bootcmd,其将会调度do_bootm()完成命令的功能在do_bootm(...)中再调度do_bootm_linux(....)完成内的内核启动前的设定与硬件参数的设定(如SDRAM地址大小等信息...)最终通过如下两句话实现内核的启动:
theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);theKernel (0, bd->bi_arch_number, bd->bi_boot_params);
(PS:还有注意一下关于镜像文件头结构体:
typedef struct image_header {uint32_tih_magic;/* Image Header Magic Number*/uint32_tih_hcrc;/* Image Header CRC Checksum*/uint32_tih_time;/* Image Creation Timestamp*/uint32_tih_size;/* Image Data Size*/uint32_tih_load;/* Data Load Address*/uint32_tih_ep;/* Entry Point Address*/uint32_tih_dcrc;/* Image Data CRC Checksum*/uint8_tih_os;/* Operating System*/uint8_tih_arch;/* CPU architecture*/uint8_tih_type;/* Image Type*/uint8_tih_comp;/* Compression Type*/uint8_tih_name[IH_NMLEN];/* Image Name*/} image_header_t;这种留意如下三个参数:uint32_tih_size;/* Image Data Size*/uint32_tih_load;/* Data Load Address*/uint32_tih_ep;/* Entry Point Address*/
)
- GT2440--U-Boot分析(四)
- GT2440--U-Boot分析(一)
- GT2440--U-Boot分析(二)
- GT2440--U-Boot分析(三)
- u-boot第一阶段分析(四)
- u-boot第二阶段分析(四)
- 移植u-boot-1.3.4到GT2440(第二版2.0)
- u-boot-1.1.6在GT2440开发板(S3C2440)上的移植
- u-boot移植总结(四)u-boot-2010.09框架分析
- U-BOOT之四:u-boot.lds分析
- U-Boot之四:u-boot.lds分析
- U-Boot之四:u-boot.lds分析
- 四极管:u-boot运行分析(四)(转帖)
- u-boot运行分析(四)(转帖) .
- OMPL138及U-Boot的启动过程分析(四)
- 四、U-boot.lds文件分析
- (四) u-boot 启动分析_第二阶段
- U-boot移植(四)
- malloc realloc创建动态数组
- GT2440--U-Boot分析(二)
- 黑马程序员-HTML学习总结
- GT2440--U-Boot分析(三)
- 飞鸽传书有关举证不够严谨
- GT2440--U-Boot分析(四)
- 革命的时刻-早起
- Use StringBuilder to create large string
- 七步教你制定网站SEO整体优化方案
- TNS-12541 TNS-12560 TNS-00511 Linux Error: 111 解决方法
- Excel MID函数截取文字
- 一个失败的作品,QQ找茬作弊器
- Windows Forms概述
- DNSPod和新网的解析