在OK6410开发板上,用最新版本busybox-1.35重新制作了rootfs。按照readelf命令结果,将交叉工具链中直接、间接所引用到的动态链接库,通通复制进来。本以为作为基础功能的ping会很顺利,实际了也折腾一天。
golden@ubuntu:~/workspace/busybox$ arm-none-linux-gnueabi-readelf -d rootfs/bin/busybox
Dynamic section at offset 0x10900c contains 26 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libm.so.6]
0x00000001 (NEEDED) Shared library: [libresolv.so.2]
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x0000000c (INIT) 0xc604
0x0000000d (FINI) 0xe9c24
0x00000019 (INIT_ARRAY) 0x119000
0x0000001b (INIT_ARRAYSZ) 4 (bytes)
...
?正常情况下, 移植好网络驱动,并使能linux的tcp/ip等网络协议的前提下, udhcpc工具将按默认脚本?/usr/share/udhcpc/default.script (也可手动指定脚本:-s xxx.script)设置好路由、DNS和接口IP,一步到位。目前遇到的问题,是ping 8.8.8.8能通,nslookup www.baidu.com也没有问题,但ping www.baidu.com却报错?。
# udhcpc -i wlan0 -s /etc/udhcpc.script
udhcpc: started, v1.35.0
udhcpc: broadcasting discover
udhcpc: broadcasting select for 192.168.1.29, server 192.168.1.1
udhcpc: lease of 192.168.1.29 obtained from 192.168.1.1, lease time 259200
deleting routers
route: SIOCDELRT: No such process
adding dns 192.168.1.1
# ping www.baidu.com -c 4
ping: bad address 'www.baidu.com'
# ping 8.8.8.8 -c 4
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=115 time=39.883 ms
64 bytes from 8.8.8.8: seq=1 ttl=115 time=85.281 ms
...
# nslookup www.baidu.com
Server: 192.168.1.1
Address: 192.168.1.1:53
Non-authoritative answer:
www.baidu.com canonical name = www.a.shifen.com
Name: www.a.shifen.com
Address: 112.80.248.75
Name: www.a.shifen.com
Address: 112.80.248.76
一开始,还以为是nslookup和ping代码有差异,毕竟换了新busybox代码,但包括用诸如wget的其他应用做测试也是失败的,也就排除掉busybox ping代码的可能。网上有不少人分享了类似问题的总结,比如?https://blog.csdn.net/weixin_33979745/article/details/90280743?这个文章列了诸如/dev/resolv.conf脚本配置问题、nscd 域名解析cache的缓存访问问题,可惜无法解决我遇到的问题。
当然,作为网络问题,抓包分析是一个不错的思路。用"tcpdump -i wlan0 -w test.pcap"分别抓取nslookup 和ping过程的包日志。nslookup的包分析结果,的确能看下DNS协议的请求包和响应包,证明内核协议是通的;但ping的日志包压根没有,文件实际大小为0,说明问题还没到协议层。
后来想到一个笨办法, 就是拿之前飞凌光盘给的rootfs,做交叉对比实验, 逐步排查脚本、bin、lib库的差异点。最终确定问题发生在libnss_dns.so这个库的缺失上。往前看本文的开头,busybox依赖链接库的查询结果,并无此库,而次级的间接依赖库也是如此,但现实给我上了一课。
NSS,全称(Naming Service Switch) ,详见:Chapter 2 The Name Service Switch (Overview)
The name service switch is a file named?nsswitch.conf(4). It controls how a client machine or application obtains network information. It is used by client applications that call any of the?getXbyY()?interfaces such as the following. gethostbyname() getpwuid() getpwnam() getipnodebyname()
......
Switch File Information Sources
Information Sources? | Description? |
---|
files | A file stored in the client's?/etc?directory. For example,?/etc/passwd | nisplus | An NIS+ table. For example, the?hosts?table. | nis | An NIS map. For example, the?hosts?map. | compat | Compat can be used for password and group information to support old-style + or - syntax in?/etc/passwd,?/etc/shadow, and?/etc/group?files. | dns | Can be used to specify that host information be obtained from DNS.? | ldap | Can be used to specify entries be obtained from the LDAP directory.? |
文章描述来看,还真跟DNS有关系,根据文章表述,一些函数比如libC库的gethostbyname()会调用nss功能,虽然我未设置nsswitch.conf,甚至这些库之间的依赖关系中也没有看到对libnss库的引用,但既然是调用关系,那实际应该是会被一起加载的吧。
从实际验证来看,这个libnss_dns.so的缺失是造成ping域名失败的原因。?
|