以下例子都以project X项目tiny210(s5pv210平台,armv7架构)为例
[uboot] uboot流程系列:
[project X] tiny210(s5pv210)上电启动流程(BL0-BL2)
[project X] tiny210(s5pv210)从存储设备加载代码到DDR
[uboot] (第一章)uboot流程——概述
[uboot] (第二章)uboot流程——uboot-spl编译流程
[uboot] (第三章)uboot流程——uboot-spl代码流程
[uboot] (第四章)uboot流程——uboot编译流程
[uboot] (第五章)uboot流程——uboot启动流程
[uboot] (番外篇)global_data介绍
[uboot] (番外篇)uboot relocation介绍
建议先看《[uboot] (第五章)uboot流程——uboot启动流程》
=================================================================================
一、说明
命令行模式就是指uboot执行完一切必要的初始化过程之后,等待终端输入命令和处理命令的一个模式。
所以后面的章节,我们先介绍命令如何存储以及处理,再简单说明命令行模式是如何工作的
1、需要打开哪些宏
CONFIG_CMDLINE
表示是否支持命令行模式,定义如下:
./configs/bubblegum_defconfig:201:CONFIG_CMDLINE=y
./configs/tiny210_defconfig:202:CONFIG_CMDLINE=yCONFIG_SYS_GENERIC_BOARD
用于定义板子为通用类型的板子。打开这个宏之后,common/board_f.c和common/board_r.c才会被编译进去,否则,需要自己实现。
./configs/bubblegum_defconfig:7:CONFIG_SYS_GENERIC_BOARD=y
./configs/tiny210_defconfig:7:CONFIG_SYS_GENERIC_BOARD=y
打开之后,board_r.c中最终会执行run_main_loop进入命令行模式。具体参考《[uboot] (第五章)uboot流程——uboot启动流程》。CONFIG_SYS_PROMPT
命令行模式下的提示符。在tiny210中定义如下:
./configs/tiny210_defconfig:203:CONFIG_SYS_PROMPT=”TINY210 => “CONFIG_SYS_HUSH_PARSER
表示使用使用hush来对命令行进行解析。后续会继续说明。在tiny210中定义如下:
./include/configs/tiny210.h:121:#define CONFIG_SYS_HUSH_PARSER /* use “hush” command parser */对应命令需要打开对应命令的宏
以bootm命令为例,如果要支持bootm,则需要打开CONFIG_CMD_BOOTM宏,具体可以参考cmd/Makefile
./configs/bubblegum_defconfig:226:CONFIG_CMD_BOOTM=y
./configs/tiny210_defconfig:226:CONFIG_CMD_BOOTM=y
2、结合以下几个问题来看后面的章节
- 命令的数据结构,也就是代码里面如何表示一个命令?
- 如何定义一个命令,我们如何添加一个自己的命令?
- 命令的存放和获取?
- 命令行模式的处理流程?
3、API
- U_BOOT_CMD
#define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help)
定义一个命令。 - cmd_process
enum command_ret_t cmd_process(int flag, int argc, char * const argv[], int *repeatable, ulong *ticks)
命令的处理函数,命令是作为argv[0]传入。
具体参数意义和实现参考后面。
二、命令处理数据结构的存放
1、数据结构
uboot把所有命令的数据结构都放在一个表格中,我们后续称之为命令表。表中的每一项代表着一个命令,其项的类型是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 * const []);
char *usage; /* Usage message (short) */
#ifdef CONFIG_SYS_LONGHELP
char *help; /* Help message (long) */
#endif
};
typedef struct cmd_tbl_s cmd_tbl_t;
参数说明如下:
- name:定义一个命令的名字。 其实就是执行的命令的字符串。这个要注意。
- maxargs:这个命令支持的最大参数
- repeatable:是否需要重复
- cmd:命令处理函数的地址
- usage:字符串,使用说明
- help:字符串,帮助
2、在dump里面的表示
通过以下命令解析出dump。
arm-none-linux-gnueabi-objdump -D u-boot > uboot_objdump.txt
以bootm命令为例,提取一部分信息,加上了注释信息:
23e364cc <_u_boot_list_2_cmd_2_bootm>:
// bootm命令对应的数据结构符号是_u_boot_list_2_cmd_2_bootm,后续我们会说明,其起始地址是0x23e364cc
23e364cc: 23e2bbc2 mvncs fp, #198656 ; 0x30800
// 这里对应第一个成员name,其地址是0x23e2bbc2
23e364d0: 00000040 andeq r0, r0, r0, asr #32
// 这里对应第二个成员maxargs,maxargs=0x40
23e364