uboot是一个非常优秀的开源项目。不仅仅可以学习bootloader,嵌入式,各种总线协议。还可以了解网络协议栈。在嵌入式开发中,经常使用uboot的tftp和nfs来加快开发的效率。那么在tftp可以使用之前,我们要保证host和pcDuino3可以ping通。在uboot下可以ping通host,但是host不能ping通uboot,这是因为uboot不是操作系统,我们需要做了个命令来循环等待来自host的ping命令。
在为uboot添加命令接受来自host的ping之前,我们先了解一下ping的过程:
硬件环境:host主机的ip是192.168.1.11,mac地址是5c:26:0a:5c:91:50.
pcDuino3的ip是192.168.1.188,mac地址是12:34:56:78:11:22.
我们从uboot往host发送ping 192.168.1.188时,这个过程可以用wireshark抓下来:
首先是广播发送一个ARP请求,然后host会回复该请求,这样uboot端就得到了host的mac地址;
接下来就是发送ICMP协议的Echo request,收到Echo reply,就表示ping通了。
其实从host往pcDuino3发送ping过程也是一样的,我们仅仅需要添加几行简单的代码就可以了,
为uboot添加一条recvping命令:
static int recv_ping(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { printf("recv ping command excute \n"); if (NetLoop(RECVPING) < 0) { printf("ping failed; "); return 1; } printf("host is alive\n"); return 0; } U_BOOT_CMD( recvping, 2, 1, recv_ping, "recv ICMP ECHO_REQUEST from network host", "wait the ping from other host" );
接着在NetLoop中添加处理RECVPING的处理分支:
case RECVPING: recvping_start(); break;
void recvping_start(void) { printf("Using %s device\n", eth_get_name()); NetSetTimeout(100000UL, ping_timeout); }
因为host会发送四次ICMP包,所以就有多次Echo request。
这么一看,网络协议栈也蛮简单清晰的,透过这个过程,仅仅为了对网络协议栈的理解,而不仅仅是会UNIX网络编程中的socket,listen,bind等。