實現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 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);
- elseif (len == 0)
- flag |= CMD_FLAG_REPEAT;
- #ifdef CONFIG_BOOT_RETRY_TIME
- elseif (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)是一直滿足的,就進入了另一個命令提示輸入迴圈,這個迴圈避免上面那個現象。
程式碼沒看的太仔細,分析的可能還存在問題,希望遇到同樣問題的朋友如果發現分析錯誤能夠多多指正。