您的位置:首页 >宏观经济 >

uboot中的协议栈有什么特点?

时间:2021-05-25 14:16:42 来源:

本篇是从0学ARM系列文章的最后一篇,后面暂无更新计划。

uboot中网络协议栈

网卡的驱动,对于上层协议来说,已经封装好了发送和接收数据的接口,那么上层协议栈只需要按照顺序调用对应的网卡驱动函数就可以进行网络数据的收发。

uboot中的协议栈相对来说比较简单,有以下几个特点:

传输层只支持UDP协议;目前只支持ICMP、TFTP、NFS、DNS、DHCP、CDP、SNTP等几种协议;网卡采用poll接收数据包,而不是中断方式;数据包的发送和接收操作是串行操作,不支持并发。

1. 网络协议栈架构

下面是uboot网络协议栈的函数调用流程:

2. 通过DNS命令来解析一个数据包的收发流程

uboot中,所有的命令都用宏U_BOOT_CMD来定义,dns命令的定义如下:

426 U_BOOT_CMD( 427 dns, 3, 1, do_dns,428 "lookup the IP of a hostname",429 "hostname [envvar]"430 );

当我们在uboot的命令终端输入命令dns后,命令解析函数就会调用dns执行函数do_dns()

389 int do_dns(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])390 { ……406 if (strlen(argv[1]) >= 255) {407 printf("dns error: hostname too long");408 return 1;409 }410 411 NetDNSResolve = argv[1];412 413 if (argc == 3)414 NetDNSenvvar = argv[2];415 else416 NetDNSenvvar = NULL;417 418 if (NetLoop(DNS) < 0) {419 printf("dns lookup of %s failed, check setup", argv[1]);420 return 1;421 }422 423 return 0;424 }

406行 判断参数字符串长度,大于255非法411行 参数1必须是要解析的主机,存储在NetDNSResolve 中413~416行 保存dns命令的环境参数,该参数可以没有418行 进入网络协议处理函数入口NetLoop(),并将对应的协议DNS传递给该函数

NetLoop()代码比较长,我们只分析其中比较重要的几段代码

316 ******************************************************************** 317 318 * Main network processing loop. 319 320 321 int NetLoop(enum proto_t protocol) 322 { 323 bd_t *bd = gd->bd; 324 int ret = -1; ………… 352 NetInitLoop(); ………… 367 switch (protocol) { 368 case TFTPGET: 369 #ifdef CONFIG_CMD_TFTPPUT 370 case TFTPPUT: 371 #endif 372 always use ARP to get server ethernet address 373 TftpStart(protocol); 374 break; ………… 426 #if defined(CONFIG_CMD_DNS) 427 case DNS: 428 DnsStart(); 429 break; 430 #endif 438 } ………… 461 for (;;) { 462 WATCHDOG_RESET(); 463 #ifdef CONFIG_SHOW_ACTIVITY 464 show_activity(1); 465 #endif 466 467 * Check the ethernet for a new packet. The ethernet 468 * receive routine will process it. 469 470 eth_rx(); 471 472 473 * Abort if ctrl-c was pressed. 474 475 if (ctrlc()) { 476 cancel any ARP that may not have completed 477 NetArpWaitPacketIP = 0; 478 479 net_cleanup_loop(); 480 eth_halt(); 481 Invalidate the last protocol 482 eth_set_last_protocol(BOOTP); 483 484 puts("Abort"); 485 include a debug print as well incase the debug 486 messages are directed to stderr 487 debug_cond(DEBUG_INT_STATE, "--- NetLoop Abort!"); 488 goto done; 489 } ………… 522 switch (net_state) { 523 524 case NETLOOP_RESTART: 525 NetRestarted = 1; 526 goto restart; 527 528 case NETLOOP_SUCCESS: 529 net_cleanup_loop(); 530 if (NetBootFileXferSize > 0) { 531 char buf[20]; 532 printf("Bytes transferred = %ld (%lx hex)", 533 NetBootFileXferSize, 534 NetBootFileXferSize); 535 sprintf(buf, "%lX", NetBootFileXferSize); 536 setenv("filesize", buf); 537 538 sprintf(buf, "%lX", (unsigned long)load_addr); 539 setenv("fileaddr", buf); 540 } 541 if (protocol != NETCONS) 542 eth_halt(); 543 else 544 eth_halt_state_only(); 545 546 eth_set_last_protocol(protocol); 547 548 ret = NetBootFileXferSize; 549 debug_cond(DEBUG_INT_STATE, "--- NetLoop Success!"); 550 goto done; 551 552 case NETLOOP_FAIL: 553 net_cleanup_loop(); 554 Invalidate the last protocol 555 eth_set_last_protocol(BOOTP); 556 debug_cond(DEBUG_INT_STATE, "--- NetLoop Fail!"); 557 goto done; 558 559 case NETLOOP_CONTINUE: 560 continue; 561 } 562 } 563 564 done: 565 #ifdef CONFIG_CMD_TFTPPUT 566 Clear out the handlers 567 net_set_udp_handler(NULL); 568 net_set_icmp_handler(NULL); 569 #endif 570 return ret; 571 }


郑重声明:文章仅代表原作者观点,不代表本站立场;如有侵权、违规,可直接反馈本站,我们将会作修改或删除处理。