U-Boot中部分cmd執行時死機問題分析

環境:

    WRTNode開發板

問題概述:

    在控制檯執行print,死機。執行httpd則可以運行。發現部分靠後的命令執行時會導致整個uboot死掉。

 

分析過程:

    通過分析uboot源碼,決定從find_cmd函數開始調試,還是老規矩,加入診斷輸出代碼。

    printf("cmd_tp[%p] = %s\n",cmdtp, cmdtp->name);

輸入print命令之後,控制檯輸出如下:

MT7620 # print
[RUN_COMMAND] cmd[83fe2e90]="print"
[PROCESS_SEPARATORS] print
token: "print"
cmd_start = 83fcbbfc,cmd_end = 83fcbe0c
cmd_tp[83fcbbfc] = rf
cmd_tp[83fcbc14] = mdio
cmd_tp[83fcbc2c] = erase
cmd_tp[83fcbc44] = cp
cmd_tp[83fcbc5c] = reset
cmd_tp[83fcbc74] = go
cmd_tp[83fcbc8c] = bootd
cmd_tp[83fcbca4] = boot
cmd_tp[83fcbcbc] = bootm
cmd_tp[83fcbcd4] = loadb
cmd_tp[83fcbcec] = tftpboot
cmd_tp[83fcbd04] = httpd
cmd_tp[83fcbd1c] = nm
cmd_tp[83fcbd34] = mm
cmd_tp[83fcbd4c] = md
cmd_tp[83fcbd64] = run
cmd_tp[83fcbd7c] = saveenv
cmd_tp[83fcbd94] = setenv
cmd_tp[83fcbdac] = printenv
cmd_tp[83fcbdc4] = ?
cmd_tp[83fcbddc] = help
cmd_tp[83fcbdf4] = version
bootcmd=run usbargs;usb start;fatload usb 0 0x80c00000 uimage;bootm 0x80c00000
usbargs=setenv bootargs root=8:2 rootdelay=5 rootfstype=ext4 rw eth=${ethaddr} console=ttyS0,${baudrate}
ethaddr="00:11:22:33:44:55"
stdin=serial
stdout=serial
stderr=serial

逐個命令測試,發現到help的時候,輸出一半,死掉。version,直接死掉。用md顯示相關內存,整理如下:

83fcbbfc: 83fc7178 00000004 00000001 83fae7dc    xq..............
83fcbc0c: 83fc717c 83fc71a0 83fc8984 00000004    |q...q..........
83fcbc1c: 00000001 83fb5e38 83fc898c 83fc89bc    ....8^..........
83fcbc2c: 83fc8dc4 00000002 00000001 83fb7ac4    .............z..
83fcbc3c: 83fc8dcc 83fc8df0 83fc8e68 00000002    ........h.......
83fcbc4c: 00000001 83fb7998 83fc8e6c 83fc8e84    .....y..l.......
83fcbc5c: 83fc9388 00000001 00000000 83fc3760    ............`7..
83fcbc6c: 83fc9390 00000000 83fc93b4 00000010    ................
83fcbc7c: 00000001 83fb8560 83fc93b8 83fc93e8    ....`...........
83fcbc8c: 83fc9494 00000001 00000001 83fb8640    ............@...
83fcbc9c: 83fc949c 00000000 83fc9c48 00000001    ........H.......
83fcbcac: 00000001 83fb8640 83fc94cc 00000000    ....@...........
83fcbcbc: 83fc94fc 00000010 00000001 83fb8c70    ............p...
83fcbccc: 83fc9504 83fc9534 83fc9a88 00000003    ....4...........
83fcbcdc: 00000000 83fb9994 83fc9a90 83fc9acc    ................
83fcbcec: 83fc9c44 00000003 00000001 83fba018    D...............
83fcbcfc: 83fc9c50 83fc9c88 83fc9ca8 00000001    P...............
83fcbd0c: 00000001 83fb9fe0 83fc9cb0 00000000    ................
83fcbd1c: 83fc9d74 00000002 00000001 83fbabd8    t...............
83fcbd2c: 83fc9d78 83fc9da4 83fc9de8 00000002    x...............
83fcbd3c: 00000001 83fbac20 83fc9dec 83fc9e1c    .... ...........
83fcbd4c: 83fc9e60 00000003 00000001 83fba508    `...............
83fcbd5c: 83fc9e64 83fc9e80 83fc9f04 00000010    d...............
83fcbd6c: 00000001 83fb8468 83fc9f08 83fc9f3c    ....h.......<...
83fcbd7c: 83fc9f84 00000001 00000000 83fbb814    ................
83fcbd8c: 83fc9f8c 00000000 83fc9fc8 00000010    ................
83fcbd9c: 00000000 83fbb6c8 83fc9fd0 83fc9ff8    ................
83fcbdac: 83fca074 00000010 00000001 83fbad14    t...............
83fcbdbc: 83fca080 83fca0a8 83fca20c 00000010    ................
83fcbdcc: 00000001 83fbba0c 83fca210 00000000    ................
83fcbddc: 83fca22c 00000010 00000001 83fbba0c    ,...............
83fcbdec: 83fca234 83fca254 83fca384 00000001    4...T...........
83fcbdfc: 00000001 c7fabfff c7fabfff c7fabfff    ................
83fcbe0c: 00000000 00000000 00000000 00000000    ................
83fcbe1c: 00000000 00000000 83f6b000 83fac000    ................

着重觀察help、version命令對應的內存:.

83fcbddc: 83fca22c 00000010 00000001 83fbba0c    ,...............
83fcbdec: 83fca234 83fca254 83fca384 00000001    4...T...........
83fcbdfc: 00000001 c7fabfff c7fabfff c7fabfff    ................
83fcbe0c: 00000000 00000000 00000000 00000000    ................
83fcbe1c: 00000000 00000000 83f6b000 83fac000    ................
83fcbe2c: 83f6f000 00000000 00000000 00000000    ................

help基本正常,version就很不對勁了。c7fabfff這個內存,顯然是非法的!

這個值是哪裏來的呢?分析了一下cmd_tp的結構:

struct cmd_tbl_s {
    char        *name;        /* Command Name            */
    int        maxargs;    /* maximum number of arguments    */
    int        repeatable;    /* autorepeat allowed?        */
                    /* Implementation function    */
    int        (*cmd)(struct cmd_tbl_s *, int, int, char *[]);
    char        *usage;        /* Usage message    (short)    */
#ifdef    CFG_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
};

CONFIG_AUTO_COMPLETE沒有定義,因此一個cmd_tp對應的數據是 int * 6

繼續分析,在board.c的void board_init_r (gd_t *id, ulong dest_addr)中,發現了分配cmd_tp的代碼,打開DEBUG開關,在uboot控制檯下,輸出了這樣的內容:

monitor_flash_len =130748 
ommand "rf": 0xbc002820 => 0x83fae820
ommand "mdio": 0xbc009e78 => 0x83fb5e78
ommand "erase": 0xbc00bb04 => 0x83fb7b04
ommand "cp": 0xbc00b9d8 => 0x83fb79d8
ommand "reset": 0xbc0177a0 => 0x83fc37a0
ommand "go": 0xbc00c5a0 => 0x83fb85a0
ommand "bootd": 0xbc00c680 => 0x83fb8680
ommand "boot": 0xbc00c680 => 0x83fb8680
ommand "bootm": 0xbc00ccb0 => 0x83fb8cb0
ommand "loadb": 0xbc00d9d4 => 0x83fb99d4
ommand "tftpboot": 0xbc00e058 => 0x83fba058
ommand "httpd": 0xbc00e020 => 0x83fba020
ommand "nm": 0xbc00ec18 => 0x83fbac18
ommand "mm": 0xbc00ec60 => 0x83fbac60
ommand "md": 0xffffffff => 0xc7fabfff

輸出到md命令的時候,內存地址就不對了,此時,uboot也掛掉了。

看來應該是部分命令沒有分配到.u_boot_cmd節

在command.h中,有如下定義:

#define Struct_Section  __attribute__ ((unused,section (".u_boot_cmd")))
 
#ifdef  CFG_LONGHELP
 
#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}
 
#else    /* no long help info */
 
#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage}
 
#endif    /* CFG_LONGHELP */

不會又是我的編程器的BUG吧?總會有最後那麼一些字節,無法寫入到flash中!暈倒!!

image

發佈了59 篇原創文章 · 獲贊 12 · 訪問量 43萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章