[uboot] (第六章)uboot流程——命令行模式以及命令处理介绍
来源:互联网 发布:safari for windows 编辑:程序博客网 时间:2024/06/06 14:21
以下例子都以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。
数据结构如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
参数说明如下:
- name:定义一个命令的名字。 其实就是执行的命令的字符串。这个要注意。
- maxargs:这个命令支持的最大参数
- repeatable:是否需要重复
- cmd:命令处理函数的地址
- usage:字符串,使用说明
- help:字符串,帮助
2、在dump里面的表示
通过以下命令解析出dump。
- 1
以bootm命令为例,提取一部分信息,加上了注释信息:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
根据上述dump就可以把bootm命令的数据结构定义都找出来了。
3、命令数据结构在u-boot.map符号表中的位置定义
通过查看u-boot.map,过滤出和u_boot_list中cmd相关的部分,对应符号表如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
可以观察到命令表是被定义在0x23e3649c( .u_boot_list_2_cmd_1)到0x23e3673c( .u_boot_list_2_cmd_3)的位置中。
并且每一个项占用了24个字节,和cmd_tbl_t结构的大小是一致的。
注意,根据注释,.u_boot_list_2_cmd_1和.u_boot_list_2_cmd_3这两个符号是由链接器自己生成的。
这里简单有个印象,bootm命令对应的数据结构符号是u_boot_list_2_cmd_2_bootm
4、如何定义一个命令
(1)我们以bootm命令的定义为例:
cmd/bootm.c中
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
通过上面,可以看出是通过U_BOOT_CMD来定义了bootm命令对应的数据结构!!!
并且命令处理函数的格式如下:
- 1
当命令处理函数执行成功时,需要返回0.返回非0值
所以可以参照如上方式自己定义一个命令。
5、介绍一下U_BOOT_CMD的实现
include/common.h
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
三、命令的处理
1、简单流程说明:
假设传进来的命令是cmd。
* 获取命令表
* 从命令表中搜索和cmd匹配的项
* 执行对应项中的命令
后续我们我们分成“查找cmd对应的表项”、“执行对应表项中的命令”两部分进行说明
2、查找cmd对应的表项——find_cmd
通过find_cmd可以获取命令对应的命令表项cmd_tbl_t 。
(1)原理简单说明
前面我们知道了可以观察到命令表是被定义在 .u_boot_list_2_cmd_1到.u_boot_list_2_cmd_3的位置中。所以我们从这个区间获取命令表。
并且根据表项中的name是否和传进来的命令是否匹配来判断是否是我们需要的表项。
(2)对应代码
common/command.c
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
include/linker_lists.h
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
3、执行对应表项中的命令——cmd_call
通过调用cmd_call可以执行命令表项cmd_tbl_t 中的命令
common/command.c
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
4、命令处理函数——cmd_process
代码如下:
common/command.c
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
返回0表示执行成功,返回非0值表示执行失败。
后续需要执行一个命令的时候,直接调用cmd_process即可。
四、命令行模式的流程
命令行模式有两种简单的方式。正常模式是简单地获取串口数据、解析和处理命令。
hush模式则是指命令的接收和解析使用busybox的hush工具,对应代码是hush.c。
关于hush模式的作用和使用自己还不是很清楚,还要再研究一下。这里简单的写一点流程。
1、入口
通过《[uboot] (第五章)uboot流程——uboot启动流程》,我们知道了uboot在执行完所有初始化程序之后,调用run_main_loop进入主循环。
通过主循环进入了命令行模式。
common/board_r.c
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
main_loop实现如下:
这里了解一个缩写,cli,Command Line Interface,命令行接口,命令行界面。
common/main.c
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
通过调用cli_loop进入了命令行模式,并且不允许返回。
common/cli.c
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
最终通过cli_simple_loop进入通用命令行模式,或者通过parse_file_outer进入hush命令行模式。
因为通用命令行模式相对较为简单,所以这边先说明通用命令行模式。
2、通用命令行模式
代码如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
3、hush命令行模式
hush的实现自己也没搞太懂,简单的说明一下流程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
可以观察到,最终还是调用了cmd_process来对命令进行处理,上述第三节已经说明了,这里不重复说明了。
- [uboot] (第六章)uboot流程——命令行模式以及命令处理介绍
- [uboot] (第六章)uboot流程——命令行模式以及命令处理介绍
- uboot中命令行模式以及命令处理
- [uboot] (第二章)uboot流程——uboot-spl编译流程
- [uboot] (第三章)uboot流程——uboot-spl代码流程
- [uboot] (第四章)uboot流程——uboot编译流程
- [uboot] (第五章)uboot流程——uboot启动流程
- [uboot] (第二章)uboot流程——uboot-spl编译流程
- [uboot] (第三章)uboot流程——uboot-spl代码流程
- [uboot] (第四章)uboot流程——uboot编译流程
- [uboot] (第五章)uboot流程——uboot启动流程
- [uboot] (第一章)uboot流程——概述
- [uboot] (第一章)uboot流程——概述
- [uboot] (番外篇)uboot dm-gpio使用方法以及工作流程
- [uboot] (番外篇)uboot dm-gpio使用方法以及工作流程
- 常用uboot命令介绍
- 常用uboot命令介绍
- uboot相关命令介绍
- java排序Comparator基本用法
- Kafka(自带的zookeeper)集群搭建详细步骤
- Hadoop集群多用户部署
- MD5加密!对密码进行MD5加密和验证
- 微信小程序实现控制标题栏背景色
- [uboot] (第六章)uboot流程——命令行模式以及命令处理介绍
- mac修改mysql的账号密码 初始化账号密码
- SpringBoot集成dubbo
- Linux常用服务配置(Java开发) 一
- fastxml Jackson
- Unresolved compilation problem:
- Window、Activity、DecorView以及ViewRoot之间的关系
- CSS控制文本超出部分显示省略号(一行跟多行)
- 求大神解决,已困扰两天,python,unittest测试结果为Ran 0 tests in 0.000s