uboot源码分析(1)uboot 命令解析流程简析
uboot 命令解析流程简析
uboot正常启动后,会调用main_loop(void)函数,进入main_loop()之后,如果在规定的时间(CONFIG_BOOTDELAY)内,没有检查到任何按键事件的发生,就会去加载OS,并启动系统,比如把linux内核压缩镜像从nand flash中读到sdram ,然后执行它。
如果在CONFIG_BOOTDELAY时间内,用户按下键盘上的任意一个按键,uboot就会进入与用户交互的状态。如果用户在配置文件中定义了CONFIG_SYS_HUSH_PARSER,就会通过parse_file_outer(),去接收并解析用户命令,否则进入一个for(;;)循环中,通过
readline (CONFIG_SYS_PROMPT)接收用户命令,然后调用run_command(cmd,flag)去解析并执行命令。代码如下:
void main_loop(void)
{
..............................
#ifdef CONFIG_SYS_HUSH_PARSER
parse_file_outer();
/* This point is never reached */
for (;;);
#else
for (;;)
{
#ifdef CONFIG_BOOT_RETRY_TIME
if (rc >= 0) {
/* Saw enough of a valid command to
* restart the timeout.
*/
reset_cmd_timeout();
}
#endif
len = readline (CONFIG_SYS_PROMPT);
printf("after readline:%d\n",len);
flag = 0; /* assume no special flags for now */
if (len > 0)
strcpy (lastcommand, console_buffer);
else if (len == 0)
flag |= CMD_FLAG_REPEAT;
#ifdef CONFIG_BOOT_RETRY_TIME
else if (len == -2) {
/* -2 means timed out, retry autoboot
*/
puts ("\nTimed out waiting for command\n");
# ifdef CONFIG_RESET_TO_RETRY
/* Reinit board to run initialization code again */
do_reset (NULL, 0, 0, NULL);
# else
return; /* retry autoboot */
# endif
}
#endif
if (len == -1)
puts ("<INTERRUPT>\n");
else
rc = run_command (lastcommand, flag);
.....................................
}
如果定义了CONFIG_SYS_HUSH_PARSER,命令接收和解析讲采用busybox 中的hush(对应hush.c)工具来实现,与uboot原始的命令解析方法相比,该工具更加智能。这里主要讲uboot中基于hush的命令解析流程。不过hush的实现太过复杂 ,鉴于自己水平太次,只是简单追踪下流程。
当在配置文件中定义了CONFIG_SYS_HUSH_PARSER,main_loop会调用parse_file_outer(),进入hush,然后里面是一大堆和hush相关的机制,暂时不做分析,最终会调用到hush中的run_pipe_real(struct pipe *pi),在该函数中经过一些列解析 ,最终会调用到对应的命令执行函数,代码如下:
static run_pipe_real(struct pipe *pi)
{
........................................
rcode = (cmdtp->cmd)(cmdtp, flag,child->argc-i,&child->argv[i]);
if ( !cmdtp->repeatable )
flag_repeat = 0;
...................................
}
cmdtp 是对应命令的结构指针,cmd就是该命令对应的执行函数指针。在uboot中,对所有的命令,有一个cmd_tbl_t的结构,定义如下:
struct cmd_tbl_s
{
char *name; /* Command Name */
int maxargs; /* maximum number of arguments */
int repeatable; /* autorepeat allowed? */
int (*cmd)(struct cmd_tbl_s *, int, int, char *[]); /* Implementation function */
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
};
typedef struct cmd_tbl_s cmd_tbl_t;
#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage}
对于uboot支持的每一个命令,是通过U_BOOT_CMD宏定义的,他定义了该命令对应的名称name,支持的最大参数rep,重复次数,实现函数cmd,以及输入help命令时,显示的帮助信息usage。例如,在cmd_nand中,定义nand命令的方法如下:
U_BOOT_CMD(nand, CONFIG_SYS_MAXARGS, 1, do_nand,
"NAND sub-system",
"info - show available NAND devices\n"
"nand device [dev] - show or set current device\n"
"nand read - addr off|partition size\n"
"nand write - addr off|partition size\n"
" read/write 'size' bytes starting at offset 'off'\n"
" to/from memory address 'addr', skipping bad blocks.\n"
"nand erase [clean] [off size] - erase 'size' bytes from\n"
" offset 'off' (entire device if not specified)\n"
#if defined(ENABLE_CMD_NAND_YAFFS)
"nand read[.yaffs[1]] is not provide temporarily!\n"
"nand write[.yaffs[1]] addr off size - write the `size' byte yaffs image starting\n"
" at offset `off' from memory address `addr' (.yaffs1 for 512+16 NAND)\n"
#endif
"nand bad - show bad blocks\n"
"nand dump[.oob] off - dump page\n"
"nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n"
"nand markbad off [...] - mark bad block(s) at offset (UNSAFE)\n"
"nand biterr off - make a bit error at offset (UNSAFE)"
#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
"\n"
"nand lock [tight] [status]\n"
" bring nand to lock state or display locked pages\n"
"nand unlock [offset] [size] - unlock section"
#endif
);
命令名称为nand,支持的最大参数个数为CONFIG_SYS_MAXARGS,命令重复次数为1,对应的实现函数为do_nand,后面的是用户输入nand -help时,将显示的帮助信息。
在执行函数cmd中,第一个参数对应该命令结构本身的指针,第二个参数对应flag标记,第三个参数对应参数数目,第四个参数是指针数组,里面存储的是对应参数的指针。比如我们输入命令“nand read 30008000 0x80000 300000”,在run_pipe_real中,解析到该命令为nand ,有五个参数,这些参数对应的指针存储在argv数组中,nand命令对应的实现函数cmd为do_nand,在实现函数do_nand中,会从argv中取得对应的参数并解析,然后执行相应的命令。这些实现在do_nand函数中都可以看到。
uboot源码分析(1)uboot 命令解析流程简析相关推荐
- linux uboot 源码分析,UBoot源码分析1.pdf
UBoot源码分析1 • UBoot源码解析(一) 主要内容 • 分析UBoot是如何引导Linux内核 • UBoot源码的一阶段解析 BootLoader概念 • Boot Loader 就是在操 ...
- 嵌入式之uboot源码分析-启动第二阶段学习笔记(下篇)
接上部分---->嵌入式之uboot源码分析-启动第二阶段学习笔记(上篇) 注:如下内容来自朱老师物联网大讲堂uboot课件 3.2.14 CFG_NO_FLASH (1)虽然NandFlash ...
- uboot源码分析(基于S5PV210)之启动第一阶段
目录 一.start.S引入 1.u-boot.lds中找到start.S入口 2.SourceInsight中如何找到文件 3.SI中找文件技巧 二.start.S解析 1.不简单的头文件包含 2. ...
- X210之uboot源码分析
uboot源码分析 Makefile分析1 自己参考源码. Makefile分析2 ifdef O ifeq ("$(origin O)", "command line& ...
- 【OpenHarmony-v3.2代码分析】02 - device目录 uboot源码分析
[OpenHarmony-v3.2代码分析]02 - device目录 uboot源码分析 1. device 目录分析 从本文开始 ,我们正式来分析OpenHarmony-V3.2的源码的 uboo ...
- Spark源码分析之Sort-Based Shuffle读写流程
一 概述 我们知道Spark Shuffle机制总共有三种: # 未优化的Hash Shuffle:每一个ShuffleMapTask都会为每一个ReducerTask创建一个单独的文件,总的文件数是 ...
- 【SA8295P 源码分析】18 - Camera Bringup 流程 及 源码分析
[SA8295P 源码分析]18 - Camera Bringup 流程 及 源码分析 一.Camera Bringup 流程 1.1 CameraConfigSA8295.c 配置文件解析 1.2 ...
- HBase源码分析之HRegion上compact流程分析(三)
在<HBase源码分析之HRegion上compact流程分析(二)>一文中,我们没有讲解真正执行合并的CompactionContext的compact()方法.现在我们来分析下它的具体 ...
- 【Redis源码分析】Redis命令处理生命周期
运营研发团队 李乐 前言 本文主要讲解服务器处理客户端命令请求的整个流程,包括服务器启动监听,接收命令请求并解析,执行命令请求,返回命令回复等,这也是本文的主题"命令处理的生命周期" ...
最新文章
- TIOBE 11 月编程语言:Java 首次跌出前二,Python 势不可挡
- oracle数据库数据导入导出步骤(入门)
- NYOJ 143 第几是谁?
- Centos6.8上httpd配置腾讯云SSL证书
- UE4学习-创建基于C++的场景
- 如何使用python给PDF文件加水印
- 【转】解决WCF大数据量传输 ,System.Net.Sockets.SocketException: 远程主机强迫关闭了一个现有的连接...
- 动态照片制作html模板
- 使用AppFabric 承载WCF和WF服务-安装和使用
- IBM面试题试解(关于50条狗、50个人、病狗)
- 9.Maven之(九)依赖关系
- 字符集与编码系列:Unicode字符集
- 基于Vue+AntDesign实现的JAVA前后端分离后台管理系统
- html取消父元素样式,CSS以防止子元素继承父样式
- opencv 将视频流转换成帧图像(支持asf,mp4,avi)
- 联合利华、微软、Brooks、Neste、ITV等另外13家公司加入《气候宣言》
- win10上成功运行faster-rcnn.pytorch-1.0
- scrapy---拉勾网Ajax爬虫
- C盘里的HTML是什么文件,C盘Windows下的winsxs是什么文件可以删除吗
- PetShop全版本(2.0-5.0)
热门文章
- SpringMCV整合配置文件
- 时间复杂度o(n^0.5)_算法基础1.1:算法复杂度计算(二)
- java 读取mysql日志_如何在MySQL中查看日志文件?
- cheat engine 将选中目标的函数_EXCEL函数与公式剖析:IF
- java 格式化 浮点数_DecimalFormat的用法 Java 浮点数 Float Double 小数 格式化 保留小数位后几位等...
- 守护你一生-守护线程(Java)
- git中如何提交空目录
- QT-提示“database not open”
- Nginx学习笔记(二) Nginx--connectionrequest
- Hadoop之分布式存储HDFS和离线计算MapReduce