今天下载了个较新版本的uboot,发现和之前工作用到的uboot的差别还是不小的,但是因为总体框架和流程不会改变,所有用新版本的uboot做分析和记录;
用到的uboot版本是2016.09,当时开发用的是x210,cpu为s5pv210,cortex-a8架构,按道理来说,uboot是应该选择和当时开发板出厂时间差不多的版本,当时因为只做知识点的记录,还是用这个新版本的uboot来分析;
关于uboot的目录结构网上有太多分析,这里不做记录了,以三星的s5pv210开发板为例,建立source insight的时候主要是注意筛选arch和board目录,选择加入公共的代码和 arch/arm/cpu/armv7,arch/arm/mach-XXXX,board/samsung/smdkc100;
代码的关键是arch/arm/cpu/armv7/start.S和u-boot.lds;
启动流程的分析这边博文介绍的不错,记录一下:http://blog.csdn.net/sinat_24088685/article/details/51933374
1 命令体系分析
命令的添加比较容易,参考cmd中的help命令来进行添加命令,help的实现如下:
static int do_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
#ifdef CONFIG_CMDLINE
cmd_tbl_t *start = ll_entry_start(cmd_tbl_t, cmd);
const int len = ll_entry_count(cmd_tbl_t, cmd);
return _do_help(start, len, cmdtp, flag, argc, argv);
#else
return 0;
#endif
}
U_BOOT_CMD(
help, CONFIG_SYS_MAXARGS,1,do_help,
"print command description/usage",
"\n"
" - print brief description of all commands\n"
"help command ...\n"
" - print detailed usage of 'command'"
);
只需要定义一个U_BOOT_CMD(xxxxxxxxxx),然后实现命令的实现函数即可;
命令体系的底层实现主要是配合链接脚本的属性,uboot的命令解析部分根据链接脚本的属性找到所有命令的存放的起始和结束地址,根据起始和结束地址查找到相关的命令,进行函数调用;主要涉及的函数和流程:
① U_BOOT_CMD宏定义在include/command.h 逐步展开
U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help)
↓
U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, NULL)
↓
ll_entry_declare(cmd_tbl_t, _name, cmd) =
\
U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd,\
_usage, _help, NULL);
↓
cmd_tbl_t _u_boot_list_2_cmd_2__name __aligned(4)__attribute__((unused,section(".u_boot_list_2_cmd_2_"#_name)))=
{ _name,
_maxargs,
_rep,
_cmd,
_usage,
_help##_comp
}
↓
相当于定义了一个全局的结构体,它的链接属性是.u_boot_list_2_cmd_2_"#_name
这个属性会被链接脚本集中到某一位置,分析链接脚本发现其中的 KEEP(*(SORT(.u_boot_list*))); 所有的.u_boot_list被排序后放入
然后分析find_cmd函数
cmd_tbl_t *start = ll_entry_start(cmd_tbl_t, cmd);是找到属性为 .u_boot_list_2_cmd_1 的地址
cmd_tbl_t *end = ll_entry_end(_type, _list);是找到属性为 .u_boot_list_2_cmd_3的地址
刚分析命令是按名字排序链接的,所以中间就是我们所有的cmd命令,具体可查看linux/linker_list.h中的说明
分析出的函数的调用关系如下
main_loop()
----------cli_loop()
--------------------parse_file_outer()
------------------------------parse_stream_outer()
----------------------------------------run_list()
--------------------------------------------------run_list_real()
------------------------------------------------------------run_pipe_real()
----------------------------------------------------------------------cmd_process
cmd_process函数调用find_cmd(argv[0])查找命令,然后调用cmd_call(cmdtp, flag, argc, argv)执行命令
本文档详细介绍了如何在U-Boot中添加和实现新命令,通过分析uboot的源码,展示了命令添加过程,包括U_BOOT_CMD的使用,以及命令解析流程。主要涉及到U-Boot的链接脚本属性和命令查找机制。

4万+

被折叠的 条评论
为什么被折叠?



