在控制台执行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中!晕倒!!