实现uboot 命令自动补全 及 修正设置环境变量时自启动内核
2014-09-29 14:01
381 查看
语文地址:http://blog.csdn.net/liukun321/article/details/6641478
习惯了了linux下的命令自动补全,换做uboot下的单个字符的输入长串命令,实在是不太习惯。常常在uboot下习惯性的按TAB键。为了习惯,下面来实现uboot的命令的自动补全。
这个功能的实现非常容易,只是在/include/configs/开发板头文件.h(我的是micro2440.h)添加一个配置宏:
#define CONFIG_CMDLINE_EDITING//#ifdef CONFIG_CMDLINE_EDITING
//#undef CONFIG_AUTO_COMPLETE
//#else
#define CONFIG_AUTO_COMPLETE //开启命令自动补全函数的编译
编译,运行,功能实现
另外还碰到了一个奇怪的问题,把我卡了很久。每次在我执行这个命令后
setenv bootcmd "nand read 31000000 0x60000 500000;bootm 31000000"
会出现uboot立即自启动内核,也就是立即执行了bootm 31000000 这个命令。
原因找了很久,最后定为在/include/configs/开发板头文件.h(我的是micro2440.h)这个文件。这个文件某个宏定义有问题或者是未定义导致这个问题的出现。是哪一个宏呢?
看uboot 源码 不难找到问题所在 文件/cmmon/main.c
[cpp] view
plaincopyprint?
#ifdef <span style="color:#ff0000;">CFG_HUSH_PARSER</span>
parse_file_outer();
/* This point is never reached */
for (;;);
#else
for (;;) {
<span style="color:#ff0000;">#ifdef CONFIG_BOOT_RETRY_TIME
if (rc >= 0) {
/* Saw enough of a valid command to
* restart the timeout.
*/
reset_cmd_timeout();
}
#endif
len = readline (CFG_PROMPT);
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);
if (rc <= 0) {
/* invalid command or not repeatable, forget it */
lastcommand[0] = 0;
}</span>
}
#endif /*
如果不定义宏 CFG_HUSH_PARSER 就将执行红色部分代码,分析这部分代码在CFG_PROMPT>=0时执行strcpy (lastcommand, console_buffer);函数,即等待串口缓冲区得数据 ,如果有数据,将把数据复制到lastcommand这个串中,然后执行rc = run_command (lastcommand, flag);而恰恰就是run_command (lastcommand, flag);这个函数有问题,函数内把带有
; 号的命令作为下一个命令执行了,所以出现了bootm 自启动内核的问题.
而定义 CFG_HUSH_PARSER 宏将执行parse_file_outer();函数,函数内最后调用,cmmon/hush.c 文件的int parse_stream_outer(struct in_str *inp, int flag)函数
[cpp] view
plaincopyprint?
<span style="color:#ff0000;">do</span> {
ctx.type = flag;
initialize_context(&ctx);
update_ifs_map();
if (!(flag & FLAG_PARSE_SEMICOLON) || (flag & FLAG_REPARSING)) mapset((uchar *)";{1}|", 0);
inp->promptmode=1;
rcode = parse_stream(&temp, &ctx, inp, '\n');
#ifdef __U_BOOT__
if (rcode == 1) flag_repeat = 0;
#endif
if (rcode != 1 && ctx.old_flag != 0) {
syntax();
#ifdef __U_BOOT__
flag_repeat = 0;
#endif
}
if (rcode != 1 && ctx.old_flag == 0) {
done_word(&temp, &ctx);
done_pipe(&ctx,PIPE_SEQ);
#ifndef __U_BOOT__
run_list(ctx.list_head);
#else
code = run_list(ctx.list_head);
if (code == -2) { /* exit */
b_free(&temp);
code = 0;
/* XXX hackish way to not allow exit from main loop */
if (inp->peek == file_peek) {
printf("exit not allowed from main input shell.\n");
continue;
}
break;
}
if (code == -1)
flag_repeat = 0;
#endif
} else {
if (ctx.old_flag != 0) {
free(ctx.stack);
b_reset(&temp);
}
#ifdef __U_BOOT__
if (inp->__promptme == 0) printf("<INTERRUPT>\n");
inp->__promptme = 1;
#endif
temp.nonnull = 0;
temp.quote = 0;
inp->p = NULL;
free_pipe_list(ctx.list_head,0);
}
b_free(&temp);
} <span style="color:#ff0000;">while (rcode != -1 && !(flag & FLAG_EXIT_FROM_LOOP)); </span>
会发现条件rcode != -1 && !(flag & FLAG_EXIT_FROM_LOOP)是一直满足的,就进入了另一个命令提示输入循环,这个循环避免上面那个现象。
代码没看的太仔细,分析的可能还存在问题,希望遇到同样问题的朋友如果发现分析错误能够多多指正。
习惯了了linux下的命令自动补全,换做uboot下的单个字符的输入长串命令,实在是不太习惯。常常在uboot下习惯性的按TAB键。为了习惯,下面来实现uboot的命令的自动补全。
这个功能的实现非常容易,只是在/include/configs/开发板头文件.h(我的是micro2440.h)添加一个配置宏:
#define CONFIG_CMDLINE_EDITING//#ifdef CONFIG_CMDLINE_EDITING
//#undef CONFIG_AUTO_COMPLETE
//#else
#define CONFIG_AUTO_COMPLETE //开启命令自动补全函数的编译
编译,运行,功能实现
另外还碰到了一个奇怪的问题,把我卡了很久。每次在我执行这个命令后
setenv bootcmd "nand read 31000000 0x60000 500000;bootm 31000000"
会出现uboot立即自启动内核,也就是立即执行了bootm 31000000 这个命令。
原因找了很久,最后定为在/include/configs/开发板头文件.h(我的是micro2440.h)这个文件。这个文件某个宏定义有问题或者是未定义导致这个问题的出现。是哪一个宏呢?
看uboot 源码 不难找到问题所在 文件/cmmon/main.c
[cpp] view
plaincopyprint?
#ifdef <span style="color:#ff0000;">CFG_HUSH_PARSER</span>
parse_file_outer();
/* This point is never reached */
for (;;);
#else
for (;;) {
<span style="color:#ff0000;">#ifdef CONFIG_BOOT_RETRY_TIME
if (rc >= 0) {
/* Saw enough of a valid command to
* restart the timeout.
*/
reset_cmd_timeout();
}
#endif
len = readline (CFG_PROMPT);
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);
if (rc <= 0) {
/* invalid command or not repeatable, forget it */
lastcommand[0] = 0;
}</span>
}
#endif /*
如果不定义宏 CFG_HUSH_PARSER 就将执行红色部分代码,分析这部分代码在CFG_PROMPT>=0时执行strcpy (lastcommand, console_buffer);函数,即等待串口缓冲区得数据 ,如果有数据,将把数据复制到lastcommand这个串中,然后执行rc = run_command (lastcommand, flag);而恰恰就是run_command (lastcommand, flag);这个函数有问题,函数内把带有
; 号的命令作为下一个命令执行了,所以出现了bootm 自启动内核的问题.
而定义 CFG_HUSH_PARSER 宏将执行parse_file_outer();函数,函数内最后调用,cmmon/hush.c 文件的int parse_stream_outer(struct in_str *inp, int flag)函数
[cpp] view
plaincopyprint?
<span style="color:#ff0000;">do</span> {
ctx.type = flag;
initialize_context(&ctx);
update_ifs_map();
if (!(flag & FLAG_PARSE_SEMICOLON) || (flag & FLAG_REPARSING)) mapset((uchar *)";{1}|", 0);
inp->promptmode=1;
rcode = parse_stream(&temp, &ctx, inp, '\n');
#ifdef __U_BOOT__
if (rcode == 1) flag_repeat = 0;
#endif
if (rcode != 1 && ctx.old_flag != 0) {
syntax();
#ifdef __U_BOOT__
flag_repeat = 0;
#endif
}
if (rcode != 1 && ctx.old_flag == 0) {
done_word(&temp, &ctx);
done_pipe(&ctx,PIPE_SEQ);
#ifndef __U_BOOT__
run_list(ctx.list_head);
#else
code = run_list(ctx.list_head);
if (code == -2) { /* exit */
b_free(&temp);
code = 0;
/* XXX hackish way to not allow exit from main loop */
if (inp->peek == file_peek) {
printf("exit not allowed from main input shell.\n");
continue;
}
break;
}
if (code == -1)
flag_repeat = 0;
#endif
} else {
if (ctx.old_flag != 0) {
free(ctx.stack);
b_reset(&temp);
}
#ifdef __U_BOOT__
if (inp->__promptme == 0) printf("<INTERRUPT>\n");
inp->__promptme = 1;
#endif
temp.nonnull = 0;
temp.quote = 0;
inp->p = NULL;
free_pipe_list(ctx.list_head,0);
}
b_free(&temp);
} <span style="color:#ff0000;">while (rcode != -1 && !(flag & FLAG_EXIT_FROM_LOOP)); </span>
会发现条件rcode != -1 && !(flag & FLAG_EXIT_FROM_LOOP)是一直满足的,就进入了另一个命令提示输入循环,这个循环避免上面那个现象。
代码没看的太仔细,分析的可能还存在问题,希望遇到同样问题的朋友如果发现分析错误能够多多指正。
相关文章推荐
- 实现uboot 命令自动补全 及 修正设置环境变量时自启动内核
- uboot环境变量的实现和读取设置
- 内核配置命令行参数以及Uboot设置环境变量bootargs里面的init=/linuxrc解析
- uboot环境变量设置好后烧写启动内核,文件系统出现的问题
- cmd环境下实现:为命令设置别名、启动cmd时自动执行bat
- 设置KSH的自动补全和历史命令功能
- jdk环境变量自动设置工具
- javac不是内部命令解决方案 (环境变量设置)
- Java自动设置环境变量
- perl实现设置环境变量并运行程序
- SET命令--环境变量设置
- Linux下设置环境变量命令--export
- java自动设置环境变量
- vc2008 cl命令环境变量设置的简介与内容
- 使用set命令设置环境变量
- 设置环境变量实现使用“运行“快速打开QQ等程序
- Linux进入系统时自动设置环境变量的方法
- 自动设置JAVA环境变量的脚本转自(JAVA中文世界---紫叶)
- solaris下安装自动安装工工具以及环境变量设置
- uboot环境变量与内核MTD分区关系