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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章