U-boot两个修改:ARP支持和UDP校验支持

amc

正如上一篇文章所说,需要对U-boot的UDP做一些小修改。
本文地址:https://segmentfault.com/a/1190000005182243


ARP支持

原文件:文件net.cNetReceive()函数

代码位置:搜索“case ARPOP_REPLY:”行并且找到其return;语句。

修改
#ifdef CONFIG_NETCONSOLE以下修改为:

#ifdef CONFIG_NETCONSOLE
    (*packetHandler)(0, 0, 0, 0);
#endif
    /** if Arp response by TFTP,
     ** send "TFTP Read Request"
     ** packet immediately */
    extern int TftpStarted;
    if (1 == TftpStarted) 
    {
        NetArpWaitPacketIP = 0;
        NetArpWaitTxPacketSize = 0;
        NetArpWaitPacketMAC = NULL;
        TftpSend();
    }
    else if (NetArpWaitTxPacketSize)
    {
        NetSendUDPPacket(NetArpWaitPacketMAC,
                         NetArpWaitPacketIP,
                         NetArpWaitDPort,        // 注
                         NetArpWaitSPort,
                         NetArpWaitTxPacketSize);
        NetArpWaitPacketIP = 0;
        NetArpWaitTxPacketSize = 0;
        NetArpWaitPacketMAC = NULL;
    }
    else
    {
        /* no arp request pending now */
    }

注:NetArpWaitDPortNetArpWaitSPort都是新定义的全局变量。当然,也需要在NetSendUDPPacket将这两个值赋值。


UDP校验和支持

U-boot默认不用UDP校验和(置零)。但是在OS X中,UDP校验和不正确的话,UDP包将会被系统丢弃。所以需要添加如下:

位置:文件net.c中的NetSetIp()函数

修改
首先,在NetSetIp()中的“ip->udp_xsum = 0;”后面加上:

unsigned int tmpSum = 0;
tmpSum = NetUdpCksum(ip, len);
ip->udp_xsum = htons((ushort)(~tmpSum));

然后,在前面添加Cksum函数:

#define DB_UDP_XSUM(x)
unsigned NetUdpCksum(IP_t *ip, int len)
{
    ulong xsum = 0;
    uchar *data;
    len += 8;
    
    ip->udp_xsum = 0;
    
    /* sum IP data */
    data = &(ip->src);
    xsum += ((ulong)(*(data + 0))) << 8;
    xsum += ((ulong)(*(data + 1))) << 0;
    xsum += ((ulong)(*(data + 2))) << 8;
    xsum += ((ulong)(*(data + 3))) << 0;
    xsum += ((ulong)(*(data + 4))) << 8;
    xsum += ((ulong)(*(data + 5))) << 0;
    xsum += ((ulong)(*(data + 6))) << 8;
    xsum += ((ulong)(*(data + 7))) << 0;
    DB_UDP_XSUM(printf("sum: 0x%04X IP\n", xsum));
    
    /* sum IP protocol */
    xsum += (ushort)(ip->ip_p);
    
    /* sum UDP length */
    data = &(ip->udp_len);
    xsum += ((ulong)(*(data + 0))) << 8;
    xsum += ((ulong)(*(data + 1))) << 0;
    
    /* sum UDP content */
    data = &(ip->udp_src);
    while(len > 1)
    {
        xsum += ((ulong)(*(data + 0))) << 8;
        xsum += ((ulong)(*(data + 1))) << 0;
        data += 2;
        len -= 2;
    }
    
    if (len)    /* 1 == len */
    {
        xsum += ((ulong)(*(data + 0))) << 8;
    }
    
    xsum = (xsum & 0x0000FFFF) + (xsum >> 16);
    xsum = (xsum & 0x0000FFFF) + (xsum >> 16);
    
    return (xsum & 0x0000FFFF);
}
阅读 3.5k

后台 / 嵌入式全栈之路
曾经的嵌入式 / 后台开发一枚,现在开始走向架构。本专栏没有高深技术,只讲基础组件、工具,请放心食用

电子和互联网深耕多年,拥有丰富的嵌入式和服务器开发经验。现负责腾讯心悦俱乐部后台开发

864 声望
198 粉丝
0 条评论

电子和互联网深耕多年,拥有丰富的嵌入式和服务器开发经验。现负责腾讯心悦俱乐部后台开发

864 声望
198 粉丝
文章目录
宣传栏