☰
U-Boot ping不通PC或虚拟机:四层链路与PHY/RGMII排查
2026/10/2 9:17:30 网站建设 项目流程

U-Boot 里敲下ping 192.168.1.10,终端停了几秒,然后甩出一行ping failed; host 192.168.1.10 is not alive。没有中间状态,没有提示,没有分层信息,就一句不通。这个场景几乎每个做 Uboot 网络移植的人都撞过:板子上网口灯亮着,PHY 也认出来了,环境变量看着也对,可就是 ping 不通 PC 机或者那台 VMware 虚拟机。真正麻烦的地方在于,"Uboot ping 不通 PC 机或虚拟机"这一句话背后至少藏着四层原因——物理链路、PHY/MAC 初始化、网络层地址配置、以及 PC 或虚拟机那一侧的可达性。任何一层断了,结果都是同一行报错。

这篇文章面向的是手里正拿着 i.MX6ULL、RK3568、Exynos 4412 这类板子,在 U-Boot 阶段调网口的人。我会把整条链路从"谁 ping 谁"开始,一层一层拆到 RGMII delay、VMware 桥接绑定、Windows 防火墙 ICMP 放行这些具体细节,给出可以直接照着做的命令、判据和排错顺序。不讲虚的,只讲能让你在半小时内定位到断点的方法。

1. 先把方向搞清楚:U-Boot 只主动发问,不被动应答

1.1 从 PC 去 ping 板子,不通是正常现象

很多人第一次调网口,习惯性地在 PC 上开个 cmd,ping 192.168.1.100,看到 Request timed out 就认定板子网口坏了。这个判断从一开始就错了。U-Boot 的网络协议栈是一个极简实现,它只实现了"客户端"这一半:发 ARP 请求、发 ICMP echo request、收 echo reply。它不会响应别人发过来的 ARP 请求,也不会回复别人发来的 ICMP echo request。换句话说,PC 发过去的 ARP 询问在 U-Boot 这里就石沉大海了,PC 连板子的 MAC 都解析不到,自然显示超时或者 Destination host unreachable。

这个设计不是缺陷,是取舍。U-Boot 的目标是把镜像从服务器拉下来,它只需要能主动发起传输,不需要被访问。等你把 Linux 内核启动起来,完整协议栈跑起来之后,PC 再去 ping 板子就通了——所以"PC ping 不通 U-Boot 阶段的板子"和"板子网络没配好"完全是两件事,别把它们混在一起。

1.2 判断通没通的唯一正确姿势

在 U-Boot 提示符下,唯一的判据是板子主动 ping 对端:

setenv ipaddr 192.168.1.100 setenv netmask 255.255.255.0 setenv serverip 192.168.1.10 ping 192.168.1.10

成功时输出形如host 192.168.1.10 is alive,失败就是ping failed; host ... is not alive。这里的serverip通常就是你 PC 或者虚拟机的 IP,也是后面tftp、nfs要连的那台机器,所以拿它当 ping 目标最顺。

提示:ping命令依赖编译时打开了CONFIG_CMD_PING。如果你在 U-Boot 提示符下敲 ping 提示Unknown command,那不是网络问题,是配置问题,先去 defconfig 里把这个选项打开重新编译。

1.3 为什么 Linux 下双向都通,U-Boot 下只有单向

这个差异值得说清楚,因为它决定了你的排查思路。Linux 内核里有完整的邻居子系统(ARP 表、ARP 应答)和 ICMP 处理路径,任何一方主动询问它都会回。U-Boot 里没有这套东西,它只在一次ping调用期间临时收发几个包,函数返回后就结束了。所以你永远只能"板子问、对端答"这一个方向。理解了这一点,你就会自然地先去确认板子发出去的包有没有到达对端,而不是盯着 PC 为什么 ping 不到板子。

2. 地址链自检:ipaddr、netmask、serverip 与 ethaddr

2.1 四个环境变量各自管什么

U-Boot 的网络参数几乎全靠环境变量,搞清楚每个变量的职责,比盲目重刷固件有效得多。

变量作用典型值缺失后果
ipaddr板子自己的 IP192.168.1.100无法构造本地地址,ping 直接失败
netmask板子的子网掩码255.255.255.0按默认值算,可能把对端判成跨网段
serverip服务器(PC/虚拟机)IP192.168.1.10tftp/nfs 无法进行,ping 也常用它做目标
gatewayip网关,仅跨网段时用192.168.1.1同网段时可不设,跨网段时必须设
ethaddr板子 MAC 地址00:11:22:33:44:55部分实现会拒绝发包或发出全 0 MAC

用printenv一次性看全,用setenv逐个改,改完一定要saveenv,否则掉电重启全部打回原形——这是新手最容易反复栽的地方,改对了当时能通,第二天上电又不行,就是因为没保存。

2.2 网段不一致是最隐蔽的低级错误

板子 192.168.1.100/24,PC 是 192.168.0.5/24,这种情况肉眼扫一眼很容易忽略,但它百分之百 ping 不通,因为两边算出来的网络号根本不是一个。更隐蔽的是掩码不一致:板子netmask是 255.255.0.0,PC 是 255.255.255.0,IP 都在 192.168.1.x 里,看起来没问题,但对包的处理逻辑按各自的掩码走,边界情况会出现单向可达。

所以排查第一步永远是:把板子ipaddr、netmask和 PC 的ipconfig(或 Linux 的ip addr)并排抄下来,逐位对比前三段和掩码。这一步不要省。

2.3 ethaddr 缺失:包根本没机会发出去

有些 SoC 的 MAC 地址存在 eFuse 或者 OTP 里,出厂没烧写时读出来是全 0,U-Boot 会打印Warning: failed to set MAC address之类的告警。全 0 的源 MAC 发出去,交换机可能直接丢弃,对端的 ARP 缓存里也会出现莫名其妙的表项。手动补一个合法的本地管理地址就行:

setenv ethaddr 02:11:22:33:44:55 saveenv

注意 MAC 必须全网唯一,同一网段里两台板子用同一个 MAC,会导致 ARP 表反复抖动、时通时不通,这种问题在现场最难查,因为现象是"偶发"。如果你们的 U-Boot 打开了CONFIG_NET_RANDOM_ETHADDR,那么每次上电 MAC 都是随机的,这时反而要注意别和真实网卡冲突。

3. PHY 与链路层:ping 之前先确认网口真的起来了

3.1 用 mii / mdio 命令把 PHY 状态读出来

网络层配置再对,PHY 没起来也是白搭。U-Boot 提供了一组直接读 PHY 寄存器的命令,比猜有用得多:

mii info # 扫描 PHY 地址,显示链路状态和速率 mdio list # 列出挂载在 MDIO 总线上的 PHY mii dump 0 1 # 读 PHY 地址 0 的寄存器 1(BMSR)

BMSR(寄存器 1)里有两位关键信息:bit2 是 Link Status,置 1 表示链路已建立;bit5 是 Auto-Negotiation Complete,置 1 表示自协商完成。如果 Link Status 一直是 0,那后面所有排查都别做,先把物理链路和 PHY 初始化解决掉。如果 Link 是 1、Auto-Neg 也完成,说明至少 MAC 和 PHY 之间的 MDIO 通信是正常的,问题更可能在 RGMII 数据路径或者上层地址。

3.2 自协商与速率双工不匹配

PHY 和交换机之间默认走自协商。如果你在对端强行写死 100M 全双工,而板子这边还在自协商 1000M,协商结果会不一致,表现通常是链路能起来但丢包率极高,mii info看着是 up,ping 却是 100% 失败。遇到这种情况,先看一眼对端交换机端口的配置,或者干脆换一个普通的百兆交换机验证一下。

双工不匹配还有一种典型现象:小包(ping 的 64 字节)能通,大包(tftp 传几百 KB)一传就崩。这种"ping 通但 tftp 挂"的情况,八成是双工或 MTU 相关,不要死磕 ping。

3.3 网线、接口与信号完整性

链路层的最底下还是硬件,几个必须过一遍的点:

  • 网线本身:换一根确定好的线,别用劣质长线。
  • RJ45 指示灯:Link 灯亮不代表数据通,但 Link 灯不亮就一定不通。
  • 晶振与时钟:PHY 一般需要 25MHz 参考时钟,i.MX6ULL 这类用 RMII 的平台需要 50MHz 参考时钟,时钟没起来 PHY 就是块死芯片。
  • 复位 GPIO 与电源:PHY 的 reset 脚如果一直拉着,或者 1.8V/3.3V 供电异常,同上。
  • 变压器(magnetics)和 RJ45 网络变压器的连接是否按参考设计走。

3.4 常见平台差异一览

平台接口类型高频踩坑点
i.MX6ULLRMII50MHz 参考时钟来源没配,引脚复用没开
RK3568RGMIITX/RX delay 没配,千兆下丢包
Exynos 4412外挂 DM9000片选、时序、中断引脚
FMQL 系列千兆RGMIIdelay、PHY 复位时序、时钟相位

这张表不是让你照抄结论,而是提醒你:不同平台的"ping 不通"根因完全不一样,先确认自己板子的接口类型,再去查对应方向。

4. 虚拟机这一侧:VMware 网络模式选错,板子永远够不着

4.1 桥接、NAT、仅主机三种模式的本质区别

用 VMware 跑 Ubuntu 当 tftp 服务器的人特别多,"Uboot ping 不通虚拟机"的案例里,一大半是网络模式选错了。

模式虚拟机 IP 来源板子能否访问典型用途
桥接(Bridged)和物理 LAN 同网段能,只要绑对网卡板子直连开发机时首选
NAT由 VMware 虚拟网段分配不能,除非做端口映射且方向受限虚机上网,不适合板子直连
仅主机(Host-only)主机内部虚拟网段只能主机访问纯主机与虚机通信

关键点:桥接模式下虚机才会拿到和物理局域网同网段的 IP,板子才可能 ping 通它。NAT 模式下虚机躲在一层地址转换后面,板子发出的 ARP 根本到不了虚机,必然不通。很多人虚机是 NAT 装的,能上网,就以为网络没问题,结果 U-Boot 怎么都 ping 不通——第一件事就是把网络模式改成桥接。

4.2 桥接绑定到了错误的物理网卡

改成桥接之后还是不通,接下来查 VMnet0 到底桥到了哪块网卡。开发机如果有线无线都有,VMware 默认可能桥接到无线网卡,而板子插的是有线口。这样虚机的包走无线出去,板子的包走有线进来,两者不在同一个二层广播域里,怎么都不通。在 VMware 的虚拟网络编辑器里把 VMnet0 显式桥接到板子实际连接的那块有线网卡,问题往往当场解决。

4.3 主机防火墙与 ICMP 放行

如果是 PC 直接当服务器(不是虚拟机),Windows Defender 防火墙默认会拦截入站 ICMP。结果就是:PC 能 ping 通板子吗?不能,因为 U-Boot 不应答;板子能 ping 通 PC 吗?也不能,因为防火墙把 echo request 丢了。去"高级安全 Windows Defender 防火墙"里把"文件和打印机共享(回显请求 - ICMPv4-In)"这条规则对当前网络配置文件启用即可。

Linux 主机上则是反过来,iptables或firewalld可能拦 ICMP:

# 临时放行 ICMP,仅用于验证 sudo iptables -I INPUT -p icmp -j ACCEPT

注意:上面这条只是临时验证用的,确认是防火墙问题后,应该按公司规范配置成持久规则,而不是留着一条临时规则。

4.4 PC 多网卡时的路由优先级

开发机同时接着有线、无线、还有一堆虚拟网卡(VMnet1、VMnet8)的时候,serverip指向虚机 IP、但主机路由表把去往那个网段的流量从别的网卡走了,也会不通。用route print(Windows)或ip route(Linux)确认去往板子网段的路由确实是从接板子那块网卡出去的。虚拟网卡一多,metric 顺序经常出意外。

5. 千兆网口最容易栽的地方:RGMII delay 与时钟配置

5.1 RGMII 为什么必须配 delay

RGMII 接口在每个时钟边沿同时传数据和控制信号,时序窗口非常窄。为了保证建立/保持时间,发送端相对 TXC 需要 1~2ns 的延迟,接收端相对 RXC 也需要相应的延迟。这个延迟要么在 MAC 侧(设备树里的tx_delay/rx_delay)配,要么在 PHY 侧通过引脚 strap 或寄存器配,两边必须配合好,否则轻则跑不了千兆、只能跑百兆,重则链路显示 up 但一个包都过不去。

这就是典型的"phy 显示 link up 1000M、ping 却 100% 丢包"的根因。很多人看到mii info显示 1000M 就以为硬件没问题了,其实数据路径的采样点早就错开了。

5.2 RK3568 / FMQL 平台上的典型处理路径

在这类平台上,正确的做法是先在设备树里确认 PHY 节点的phy-mode:

&gmac1 { phy-mode = "rgmii-id"; /* MAC/PY 内置 delay,或按实际改为 rgmii + 显式 delay */ tx_delay = <0x1f>; rx_delay = <0x0f>; status = "okay"; };

rgmii-id表示收发延迟由 PHY 内部提供;如果你的 PHY 不支持内部延迟,就要用rgmii并在 MAC 侧补上tx_delay/rx_delay。具体数值必须查你手上那颗 PHY 的数据手册和参考设计,常见组合有 0x0f、0x1f 这类,照抄别人的值有概率刚好不对。改完设备树要重新编译 DTB 并放到启动介质上,只改 U-Boot 源码不重新打包是没用的。

5.3 i.MX6ULL 的 RMII 时钟与引脚复用

i.MX6ULL 很多开发板用 RMII,坑主要集中在时钟和 IOMUX 上。RMII 需要一路 50MHz 参考时钟,通常由 PHY 提供或由 SoC 输出,具体走哪一路取决于硬件设计。如果时钟没使能,PHY 根本没有工作时钟,mii info里连 PHY 都扫不到。这时候要顺着原理图确认 50MHz 的来源,再到 U-Boot 里确认对应的 clock gate 打开了、相关引脚复用配成了 ENET 功能而不是 GPIO。引脚复用错了,最直观的现象就是网口灯不亮或者只有电源灯亮。

5.4 4412 一类老平台的外挂网卡

Exynos 4412 时代很多板子用的是外挂的 DM9000 之类的并口网卡,不是 RGMII,排查方向完全不同。它的链路建立不依赖 MDIO 自协商,问题更多出在片选信号、总线读写时序、中断引脚,以及驱动里配置的基地址是否正确。这类板子上mii命令可能压根不可用,因为它不是标准 MDIO PHY。判断自己属于哪一类,是排查前的第一件事。

6. 把 ping 不通拆成四个可验证的阶段

6.1 分层排查表

与其反复瞎试,不如把这条链路切分成四个阶段,逐个用明确判据确认:

阶段验证方法通过判据失败常见原因
物理链路看 RJ45 灯、换网线Link 灯亮网线、变压器、供电、复位
PHY/MACmii info、mii dump 0 1Link=1、AutoNeg=1时钟、MDIO 地址、delay
网络层printenv对比 PCipconfig同网段、掩码一致IP/掩码冲突、ethaddr
对端可达PC 抓包、防火墙规则能收到 ARP 且有回应虚机模式、防火墙、路由

从上往下走,一旦某一层不过,就只在这一层解决,不要跳层乱试。这套顺序能帮你把"玄学不通"变成"明确断点"。

6.2 用抓包确认板子的包到底发出去没有

在 PC 或虚拟机上开 Wireshark,过滤arp或者icmp,然后在 U-Boot 里执行一次 ping。三种结果对应三种根因:

  • 抓不到任何 ARP:板子的包根本没上到这条链路。往回查 PHY、delay、网线,属于第 1、2 阶段。
  • 抓到 ARP 请求,但没有 ARP 应答:对端没回,属于第 4 阶段,查防火墙、虚机模式、路由。
  • 抓到 ARP 有应答,ICMP 请求也发出去但没有 reply:对端收到了却没回 ICMP,多半是防火墙只放了 ARP 没放 ICMP。

这三种分叉能极大缩短定位时间,比反复改 IP 有效得多。

6.3 U-Boot 侧能用的辅助命令清单

除了ping,这些命令配合起来用:

printenv # 看全部环境变量 mii info # 看 PHY 链路与速率 mdio list # 看 MDIO 上的 PHY dhcp # 走 DHCP,用来反向验证底层是否通 tftp 0x80800000 zImage # 用 tftp 验证大流量传输 nfs 0x80800000 /path # 用 nfs 验证文件系统挂载

这里有个特别实用的技巧:如果dhcp能拿到地址而静态ping不通,那说明底层链路和 PHY 都是好的,问题一定在地址配置;如果dhcp也失败,那大概率是物理层或 PHY 的问题,别再折腾环境变量了。DHCP 通不通,是一个非常好的分水岭。

7. 几个我在实际项目里反复踩到的细节

7.1 IP 冲突导致的"时通时不通"

板子设的 IP 和网段里某台设备撞了,会出现一种很难查的现象:刚上电 ping 能通,过一会儿又不通,或者两台机器轮流应答。多板测试时尤其容易发生,因为大家习惯性地都用 192.168.1.100。给每块板子分配不同尾号,或者干脆用 DHCP,能省掉大量莫名其妙的排查时间。

7.2 直连和过交换机的差别

板子和 PC 直连时,现代网卡都支持 auto-MDIX,普通直连线就能通,但有些老交换机或老网卡对线序有要求。更常见的问题是直连时对端没有 DHCP,过交换机时又受端口速率限制。同一条命令,换一个连接方式结果不同,说明问题在物理层或对端策略上,不在板子代码里。遇到"某个环境下能通、换个环境不通",先用直连排除交换机因素。

7.3 saveenv 没执行,改了个寂寞

这个坑我踩过不止一次:setenv改完当场 ping 通了,兴奋地去干别的,结果一重启全没了。不同板子的环境变量存在 SPI Flash、eMMC 或 NAND 里,容量和块定义都不一样,如果存储介质有问题,saveenv可能报错但被忽略。改完配置后,稳妥做法是执行saveenv再看一眼有没有报错,然后真的重启一次验证,确认配置能持久化再继续后面的事。

7.4 MAC 地址用手写的,测试时反而更省心

量产板子靠 eFuse 里的 MAC,但在调试阶段,我一般会手动setenv ethaddr一个固定的、带本地管理位的地址(第一字节第二个 bit 置 1,比如 02:xx:xx:xx:xx:xx),存到环境变量里。这样每次上电 MAC 都一致,抓包时容易识别,也不会因为 eFuse 没烧而拿到全 0。等硬件和网络都验证通过,再切回读 eFuse 的正式方案。

U-Boot 的网口调试说到底就是一条单向链路加一堆可验证的判据,把这四个阶段和对应的命令用熟,绝大多数"ping 不通"都能在半小时内定位到具体那一层,而不是靠反复重刷固件碰运气。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询