• Uboot之tftp流程


     int tftp_download(char *filename, ulong msec_max, int cnt_max, ulong addr)

    {

      ...

      TftpRRQTimeoutMSecs = msec_max;   //100

      TftpRRQTimeoutCountMax = cnt_max;  //0

      setenv("netretry", "no");

      load_addr = addr;             //下载到内存的地址

      copy_filename(BootFile, filename, sizeof(BootFile));

      size = NetLoop(TFTP);

      if(size < 0)

        return ERROR;

      else

        flush_cache(addr,size);

      ...

    }

    int NetLoop(proto_t protocol)

    {

      ...

      switch (protocol)
      {

        case TFTP:
          TftpStart();
          break;

        case DHCP:
          BootpTry = 0;
          NetOurIP = 0;
          DhcpRequest(); 
          break;
        case BOOTP:

          BootpTry = 0;
          NetOurIP = 0;
          BootpRequest ();
          break;

        case RARP:
          RarpTry = 0;
          NetOurIP = 0;
          RarpRequest ();
          break;
        case PING:
          PingStart();
          break;
        case NFS:
          NfsStart();
          break;
        case CDP:
          CDPStart();
          break;
        case NETCONS:
          NcStart();
          break;
        case SNTP:
          SntpStart();
          break;
        case DNS:
          DnsStart();
          break;

      }

      ...

    }

    void TftpStart (void)

    {

      ...

      //设置参数

      NetSetTimeout (TftpTimeoutMSecs * CFG_HZ, TftpTimeout);
      NetSetHandler (TftpHandler);

      ...

      //发送

      TftpSend ();

      ...

    }

    static void TftpSend (void)

    {

      ...

      //容错

      //开始组包

      pkt = NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE;

      //针对各种状态组包

      switch (TftpState) 

      {

        case STATE_RRQ:

          xp = pkt;

          s = (ushort *)pkt;
          if(TftpState == STATE_WRQ)
            *s++ = htons(TFTP_WRQ);
          else

            *s++ = htons(TFTP_RRQ);
          pkt = (uchar *)s;
          strcpy ((char *)pkt, tftp_filename);
          pkt += strlen(tftp_filename) + 1;
          strcpy ((char *)pkt, "octet");
          pkt += 5 /*strlen("octet")*/ + 1;
          strcpy ((char *)pkt, "timeout");
          pkt += 7 /*strlen("timeout")*/ + 1;
          sprintf((char *)pkt, "%lu", TftpTimeoutMSecs / 1000);
          pkt += strlen((char *)pkt) + 1;
          memcpy((char *)pkt, "tsize000", 8);
          pkt += 8;
          if(TftpState == STATE_WRQ)
            pkt += sprintf((char *)pkt,"blksize%c%d%c", 0,TftpBlkSizeOption,0);
          else
            pkt += sprintf((char *)pkt,"blksize%c%d%c", 0,TftpBlkSizeOption,0);
          if (!ProhibitMcast && (Bitmap=malloc(Mapsize)) && eth_get_dev()->mcast)
          {
            free(Bitmap);
            Bitmap=NULL;
            pkt += sprintf((char *)pkt,"multicast%c%c",0,0);
          }
          len = pkt - xp;
          break;

        case STATE_WRQ:

          ...

        case STATE_OACK:

          ...

        case STATE_DATA:

          ...

        case STATE_TOO_LARGE:

          ...

        case STATE_BAD_MAGIC:

          ...

        case STATE_ACK:

          ...

      }

      //发送

      NetSendUDPPacket(NetServerEther, TftpServerIP, TftpServerPort, TftpOurPort, len);

    }

    int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len)

    {

      //容错:目标IP 

      //容错:ether 发ARP

      if (memcmp(ether, NetEtherNullAddr, 6) == 0) 

      {

        NetArpWaitPacketIP = dest;
        NetArpWaitPacketMAC = ether;

        pkt = NetArpWaitTxPacket;
        pkt += NetSetEther (pkt, NetArpWaitPacketMAC, PROT_IP);

        NetSetIP (pkt, dest, dport, sport, len);
        memcpy(pkt + IP_HDR_SIZE, (uchar *)NetTxPacket + (pkt - (uchar *)NetArpWaitTxPacket) + IP_HDR_SIZE, len);

        NetArpWaitTxPacketSize = (pkt - NetArpWaitTxPacket) + IP_HDR_SIZE + len;

        NetArpWaitTry = 1;
        NetArpWaitTimerStart = get_timer(0);
        ArpRequest();
        return 1; 

      }

      //容错:time 发ARP

      if (times == 10000)
      {
        times = 0;

        NetArpWaitPacketIP = dest;

        NetArpWaitPacketMAC = ether;

        pkt = NetArpWaitTxPacket;
        pkt += NetSetEther(pkt, NetArpWaitPacketMAC, PROT_IP);

        NetSetIP(pkt, dest, dport, sport, len);
        memcpy(pkt + IP_HDR_SIZE, (uchar *)NetTxPacket + (pkt - (uchar *)NetArpWaitTxPacket) + IP_HDR_SIZE, len);

        NetArpWaitTxPacketSize = (pkt - NetArpWaitTxPacket) + IP_HDR_SIZE + len;

        NetArpWaitTry = 1;
        NetArpWaitTimerStart = get_timer(0);
        ArpRequest();
      }

      //组包发送

      times++;

      pkt = (uchar *)NetTxPacket;

      pkt += NetSetEther (pkt, ether, PROT_IP);
      NetSetIP (pkt, dest, dport, sport, len);
      (void) eth_send(NetTxPacket, (pkt - NetTxPacket) + IP_HDR_SIZE + len);

      ...

    }

    至此,(void) eth_send(NetTxPacket, (pkt - NetTxPacket) + IP_HDR_SIZE + len);开始转向各个网卡驱动的发送函数。

  • 相关阅读:
    Page6:关于能控性、能观性、能测性及其判据(1)[Linear System Theory]
    Page5:状态转移矩阵及性质、连续线性系统离散化及其性质[Linear System Theory]
    java线程学习之notify方法和notifyAll方法
    java线程学习之wait方法
    java线程学习之synchronized关键字
    java线程学习之Sleep方法
    java线程学习之线程创建
    用javaScript获取页面元素值
    用javaScript对页面元素进行显示和隐藏
    JDBC工具类
  • 原文地址:https://www.cnblogs.com/pokerface/p/6770220.html
Copyright © 2020-2023  润新知