環境:
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中!暈倒!!