文章目录
1、对ping命令分析
1.1、基本流程
uboot中存在命令ping,在uboot当中运行该命令,通过wireshark进行抓包,可以直观的看到以下内容。
TI的IP为172.16.89.4
VM的IP为172.16.89.2
- 1、TI发送广播,寻求IP为172.16.89.2的设备
- 2、VM返回信息,告知TI自己的mac地址
- 3、TI发送ICMP包,请求返回信息
- 4、VM接收ICMP包,返回信息
以上完成了一次完整的ping命令,通过对以上步骤的分析,完成uboot对于网络包的解析流程分析。
static int do_ping(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
if (argc < 2)
return -1;
NetPingIP = string_to_ip(argv[1]);
if (NetPingIP == 0)
return CMD_RET_USAGE;
if (NetLoop(PING) < 0) {
printf("ping failed; host %s is not alive\n", argv[1]);
return 1;
}
printf("host %s is alive\n", argv[1]);
return 0;
}
do_ping完成了从命令深入net.c的任务,通过进入NetLoop,完成关于网络的一系列数据处理,一般关于网络传输的命令都是由NetLoop完成。
下面将分析NetLoop如何执行。
int NetLoop(enum proto_t protocol)
{
bd_t *bd = gd->bd;
int ret = -1;
NetRestarted = 0;
NetDevExists = 0;
NetTryCount = 1;
debug_cond(DEBUG_INT_STATE, "--- NetLoop Entry\n");
bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start");
net_init();
if (eth_is_on_demand_init() || protocol != NETCONS) {
eth_halt();
eth_set_current();
if (eth_init(bd) < 0) {
eth_halt();
return -1;
}
} else
eth_init_state_only(bd);
restart:
net_set_state(NETLOOP_CONTINUE);
/*
* Start the ball rolling with the given start function. From
* here on, this code is a state machine driven by received
* packets and timer events.
*/
debug_cond(DEBUG_INT_STATE, "--- NetLoop Init\n");
NetInitLoop();
//前期进行了一系列的初始化和状态的设置
switch (net_check_prereq(protocol)) {
//此处检查当前网络是否准备好
case 1:
/* network not configured */
eth_halt();
return -1;
case 2:
/* network device not configured */
break;
case 0:
NetDevExists = 1;
NetBootFileXferSize = 0;
switch (protocol) {
//此处判断要实现的功能
case TFTPGET:
case TFTPPUT:
/* always use ARP to get server ethernet address */
TftpStart(protocol);
break;
...
#if defined(CONFIG_CMD_PING)
case PING:
ping_start();//本次主要研究对象,后面展开讲述。
break;
#endif
···
}
···
}
···
for (;;) {
WATCHDOG_RESET();