实现uboot 命令自动补全 及 修正设置环境变量时自启动内核

语文地址: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 plain copy print ?
  1. #ifdef CFG_HUSH_PARSER  
  2.     parse_file_outer();  
  3.     /* This point is never reached */  
  4.     for (;;);  
  5. #else  
  6.     for (;;) {  
  7. "color:#ff0000;">#ifdef CONFIG_BOOT_RETRY_TIME  
  8.         if (rc >= 0) {  
  9.             /* Saw enough of a valid command to 
  10.              * restart the timeout. 
  11.              */  
  12.             reset_cmd_timeout();  
  13.         }  
  14. #endif  
  15.         len = readline (CFG_PROMPT);  
  16.   
  17.         flag = 0;   /* assume no special flags for now */  
  18.         if (len > 0)  
  19.             strcpy (lastcommand, console_buffer);  
  20.         else if (len == 0)  
  21.             flag |= CMD_FLAG_REPEAT;  
  22. #ifdef CONFIG_BOOT_RETRY_TIME  
  23.         else if (len == -2) {  
  24.             /* -2 means timed out, retry autoboot 
  25.              */  
  26.             puts ("\nTimed out waiting for command\n");  
  27. # ifdef CONFIG_RESET_TO_RETRY  
  28.             /* Reinit board to run initialization code again */  
  29.             do_reset (NULL, 0, 0, NULL);  
  30. # else  
  31.             return;     /* retry autoboot */  
  32. # endif  
  33.         }  
  34. #endif  
  35.   
  36.         if (len == -1)  
  37.             puts ("\n");  
  38.         else  
  39.             rc = run_command (lastcommand, flag);  
  40.   
  41.         if (rc <= 0) {  
  42.             /* invalid command or not repeatable, forget it */  
  43.             lastcommand[0] = 0;  
  44.         }  
  45.     }  
  46. #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 plain copy print ?
  1. "color:#ff0000;">do {  
  2.         ctx.type = flag;  
  3.         initialize_context(&ctx);  
  4.         update_ifs_map();  
  5.         if (!(flag & FLAG_PARSE_SEMICOLON) || (flag & FLAG_REPARSING)) mapset((uchar *)";{1}|", 0);  
  6.         inp->promptmode=1;  
  7.         rcode = parse_stream(&temp, &ctx, inp, '\n');  
  8. #ifdef __U_BOOT__  
  9.         if (rcode == 1) flag_repeat = 0;  
  10. #endif  
  11.         if (rcode != 1 && ctx.old_flag != 0) {  
  12.             syntax();  
  13. #ifdef __U_BOOT__  
  14.             flag_repeat = 0;  
  15. #endif  
  16.         }  
  17.         if (rcode != 1 && ctx.old_flag == 0) {  
  18.             done_word(&temp, &ctx);  
  19.             done_pipe(&ctx,PIPE_SEQ);  
  20. #ifndef __U_BOOT__  
  21.             run_list(ctx.list_head);  
  22. #else  
  23.             code = run_list(ctx.list_head);  
  24.             if (code == -2) {   /* exit */  
  25.                 b_free(&temp);  
  26.                 code = 0;  
  27.                 /* XXX hackish way to not allow exit from main loop */  
  28.                 if (inp->peek == file_peek) {  
  29.                     printf("exit not allowed from main input shell.\n");  
  30.                     continue;  
  31.                 }  
  32.                 break;  
  33.             }  
  34.             if (code == -1)  
  35.                 flag_repeat = 0;  
  36. #endif  
  37.         } else {  
  38.             if (ctx.old_flag != 0) {  
  39.                 free(ctx.stack);  
  40.                 b_reset(&temp);  
  41.             }  
  42. #ifdef __U_BOOT__  
  43.             if (inp->__promptme == 0) printf("\n");  
  44.             inp->__promptme = 1;  
  45. #endif  
  46.             temp.nonnull = 0;  
  47.             temp.quote = 0;  
  48.             inp->p = NULL;  
  49.             free_pipe_list(ctx.list_head,0);  
  50.         }  
  51.         b_free(&temp);  
  52.     } "color:#ff0000;">while (rcode != -1 && !(flag & FLAG_EXIT_FROM_LOOP));     

会发现条件rcode != -1 && !(flag & FLAG_EXIT_FROM_LOOP)是一直满足的,就进入了另一个命令提示输入循环,这个循环避免上面那个现象。

代码没看的太仔细,分析的可能还存在问题,希望遇到同样问题的朋友如果发现分析错误能够多多指正。


你可能感兴趣的:(bootloader,bootloader)