海思3716c在uboot时tftp总不成功分析

来源:互联网 发布:shell脚本和linux命令 编辑:程序博客网 时间:2024/05/22 04:35

现象:

在uboot下运行tftp 82000000 kernel时,一直停在“Downloading: *”


分析:

在另外一台PC上测试tftp能否正常下载,运行tftp 192.168.111.6 -c get kernel,没有停顿,很快能下载下来。

根据网上搜索,可能的原因如下:

1,tftp程序处理有问题(可能性不大,不过hpa的tftp/tftpd代码很少,加打印调试也很方便)

2,服务器有防火墙ufw或者iptables等(可能性不大,如果有问题,另外一台PC应该不能访问)

3,tftp配置有问题(可能性不大,如果有问题,另外一台PC不能访问)

4,其他问题


上面1-3个可能原因基本上不可能,为了快速查找问题,只能在代码中加打印,判断成功与失败的流程在哪里不同。

tftpd.c中tftp_sendfile函数负责发送数据给客户端。在此函数中加如下打印,并在/var/log/syslog中观测打印内容。

发现失败时,recv_time会超时并跳转到sigsetjmp()处重新执行。成功时,recv_time会继续往下走,并不会跳转到sigsetjmp()处。问题在于为什么recv_time会超时。

        (void)sigsetjmp(timeoutbuf, 1);        r_timeout = timeout;+    syslog(LOG_NOTICE, "windsome %s %d\n",__func__, __LINE__);        if (send(peer, dp, size + 4, 0) != size + 4) {            syslog(LOG_WARNING, "tftpd: write: %m");            goto abort;        }        read_ahead(file, pf->f_convert);+    syslog(LOG_NOTICE, "windsome %s %d\n",__func__, __LINE__);        for (;;) {            n = recv_time(peer, ackbuf, sizeof(ackbuf), 0, &r_timeout);+            syslog(LOG_NOTICE, "windsome %s %d:n=%d\n",__func__, __LINE__, n);            if (n < 0) {+                syslog(LOG_WARNING, "tftpd: read(ack): %m");                goto abort;            }


为了分析超时原因,想到用wireshark抓包,看看成功与失败时数据包有何不同。

成功时图片如下,注意绿色那部分协议为TFTP的那几个包。tftpd发送一个包就会收到一个回馈包。


失败时图片如下,注意绿色那块之间有些IPv4协议的碎片包,再看看碎片包的内容,2个内容组合起来刚好是成功情况下的一个包。为何会有碎片,为何包会被切?据此我猜测时mtu有问题(网卡一个包的最大字节数)。

为了证实这个问题我对pc作了ifconfig

eth0      Link encap:Ethernet  HWaddr f0:de:f1:dc:9a:c4            inet addr:192.168.111.6  Bcast:255.255.255.255  Mask:255.255.255.0          UP BROADCAST RUNNING MULTICAST  MTU:576  Metric:1
发现MTU为512,一般情况下MTU应该为1500,所以修改MTU为1500进行测试
sudo ifconfig eth0 mtu 1500
然后在hisi3716c上测试,发现能正常下载了。

然而,这种设置mtu的方式实在麻烦,并且在网络重启或dhcp重新获取ip地址后,mtu又会变回576。为了方便,我们期望mtu值保存并且一直生效。在google了之后,找到了修改的方法,需要修改2个地方,其一是/etc/network/interfaces,其二是/etc/dhcp/dhclient.conf和/etc/dhcp3/dhclient.conf。

1:interfaces的修改,在其中加入mtu设置

auto loiface lo inet loopbackauto eth0iface eth0 inet dhcp        mtu 1500#iface eth0 inet static#       mtu 1500#       address 192.168.1.63#       netmask 255.255.255.0#        network 192.168.1.0#       #broadcast 192.168.1.250#       #gateway 192.168.1.100

2:dhclient.conf的修改,在其中去掉mtu的更新

request subnet-mask, broadcast-address, time-offset, routers,        domain-name, domain-name-servers, domain-search, host-name,        netbios-name-servers, netbios-scope, interface-mtu,        rfc3442-classless-static-routes, ntp-servers;
变为
request subnet-mask, broadcast-address, time-offset, routers,        domain-name, domain-name-servers, domain-search, host-name,        netbios-name-servers, netbios-scope,        rfc3442-classless-static-routes, ntp-servers;

保存后重启网络即可。

原创粉丝点击