Jetson Nano U-Boot 有线网卡与 VMware 直连网络调试笔记
记录目的:复现并整理 Jetson Nano 在 U-Boot 阶段通过板载有线网卡
eth_rtl8169与 Ubuntu 虚拟机通信的完整过程。最终结果:U-Boot 中
ping 192.168.50.1成功,说明 PCIe 网卡、RTL8169 驱动、VMware 桥接和虚拟机网络配置全部打通。

1. 实验目标
本次实验的目标是在 Jetson Nano U-Boot 阶段 使用板载有线网卡连接电脑中的 Ubuntu 虚拟机,实现:
bash
ping 192.168.50.1
成功输出类似:
bash
Using eth_rtl8169 device
host 192.168.50.1 is alive
这说明:
text
1. Jetson Nano 的 PCIe 总线能够正常枚举
2. 板载 Realtek 网卡能够被 U-Boot 识别
3. U-Boot 能够调用 eth_rtl8169 驱动
4. VMware 桥接网络配置正确
5. Ubuntu 虚拟机能够收到 Jetson 发出的 ARP / ICMP 包
2. 整体网络连接关系
最终正确连接方式如下:
text
Jetson Nano 板载 RJ45 网口
↓ 网线
USB 转 RJ45 网卡:Realtek USB FE Family Controller
↓ USB
Windows 电脑
↓ VMware VMnet1 桥接
Ubuntu 虚拟机 ens38
IP 分配如下:
text
Jetson U-Boot:
ipaddr = 192.168.50.2
serverip = 192.168.50.1
netmask = 255.255.255.0
ethaddr = 02:00:00:12:34:56
Ubuntu 虚拟机:
ens38 = 192.168.50.1/24
Windows:
以太网 5 = Realtek USB FE Family Controller
不手动设置 192.168.50.1
注意:192.168.50.1 是给 Ubuntu 虚拟机的 ens38 使用,不要同时设置到 Windows 的"以太网 5"上,否则可能产生 IP 冲突。
3. 关键问题回顾
最开始 U-Boot 中执行:
bash
pci enum
pci
可以看到:
bash
BusDevFun VendorId DeviceId Device Class Sub-Class
_____________________________________________________________
00.02.00 0x10de 0x0faf Bridge device 0x04
01.00.00 0x10ec 0x8168 Network controller 0x00
说明:
text
0x10ec = Realtek 厂商 ID
0x8168 = Realtek RTL8168/RTL8169 系列网卡设备
之后执行:
bash
ping 192.168.50.1
出现:
bash
Using eth_rtl8169 device
ARP Retry count exceeded; starting again
ping failed; host 192.168.50.1 is not alive
这说明:
text
1. PCIe 总线枚举成功
2. RTL8169 驱动已经被调用
3. 问题不是 U-Boot 没识别网卡
4. 真正失败点是 ARP 阶段没有收到 192.168.50.1 的回应
也就是说,问题重点转移到:
text
Jetson 网口 → USB 有线网卡 → Windows → VMware 桥接 → Ubuntu ens38
这条链路是否打通。
4. Windows 端配置
4.1 插入 USB 转 RJ45 网卡
【注意:USB网卡不要复用其他功能】
电脑原本只有 Wi-Fi,没有物理有线网口,因此 VMware 只能桥接到 Wi-Fi,导致虚拟机抓到的是 Wi-Fi 网络里的包,例如:
bash
Request who-has 192.168.2.133 tell 192.168.2.1
这不是 Jetson 的包。
插入 USB 转 RJ45 网卡后,Windows 中出现:
text
以太网 5
Realtek USB FE Family Controller
未识别的网络
这是正确现象。
"未识别的网络"并不代表错误,因为这条线直连 Jetson,不连接路由器,没有 DHCP 和 Internet。
4.2 Windows 的"以太网 5"不要设置静态 IP
Windows 端保持启用即可,不要把它设置成:
text
192.168.50.1
因为这个 IP 要交给 Ubuntu 虚拟机的 ens38。
如果 Windows 和 Ubuntu 同时使用 192.168.50.1,会造成冲突。
5. VMware 虚拟网络编辑器配置
打开:
text
VMware
→ 编辑
→ 虚拟网络编辑器
→ 更改设置
配置如下:
text
VMnet1:
类型:桥接模式
外部连接:Realtek USB FE Family Controller
VMnet8:
类型:NAT 模式
用于 Ubuntu 虚拟机上网
VMnet0:
可保持桥接到 Wi-Fi,不参与本次 Jetson 直连测试
本次关键是:
text
VMnet1 必须桥接到 Realtek USB FE Family Controller
不要桥接到:
text
Intel Wireless-AC 9560
Wi-Fi Direct
Bluetooth
VMnet8
VMnet1 的 Host-only 默认模式
6. VMware 虚拟机设置
虚拟机设置中保留两个网卡:
text
网络适配器 1:
NAT
用于虚拟机访问互联网
网络适配器 2:
自定义:VMnet1
用于连接 Jetson 板子
网络适配器 2 需要勾选:
text
已连接
启动时连接
最终关系:
text
网络适配器 1 → NAT → ens33 → 虚拟机上网
网络适配器 2 → VMnet1 → ens38 → Jetson 直连
7. Ubuntu 虚拟机配置
进入 Ubuntu 后查看网卡:
bash
ip a
本次用于连接 Jetson 的网卡是:
text
ens38
配置 ens38:
bash
sudo ip addr flush dev ens38
sudo ip addr add 192.168.50.1/24 dev ens38
sudo ip link set ens38 up
检查:
bash
ip a show ens38
应看到:
bash
inet 192.168.50.1/24 scope global ens38
如果担心 ens38 影响默认路由,可以执行:
bash
sudo ip route del default dev ens38 2>/dev/null
8. Ubuntu 抓包验证
在 Ubuntu 中执行:
bash
sudo tcpdump -ni ens38 -e 'arp or icmp'
最开始如果抓到:
bash
Request who-has 169.254.169.254 tell 169.254.x.x
这是 Windows / 网卡自动私有地址相关的 ARP,可以暂时忽略。
真正需要看到的是 Jetson 发出的 ARP:
bash
Request who-has 192.168.50.1 tell 192.168.50.2
如果抓不到 192.168.50.2,说明 Jetson 的包还没进入 Ubuntu,需要继续查 VMware 桥接、网线、USB 网卡和虚拟机网络适配器绑定。
9. Jetson U-Boot 配置
进入 U-Boot 命令行后设置网络参数:
bash
setenv ipaddr 192.168.50.2
setenv serverip 192.168.50.1
setenv gatewayip 192.168.50.1
setenv netmask 255.255.255.0
setenv ethaddr 02:00:00:12:34:56
saveenv
检查环境变量:
bash
printenv ipaddr
printenv serverip
printenv gatewayip
printenv netmask
printenv ethaddr
应看到:
bash
ipaddr=192.168.50.2
serverip=192.168.50.1
gatewayip=192.168.50.1
netmask=255.255.255.0
ethaddr=02:00:00:12:34:56
注意:之前曾误输入:
bash
setenv e:2:34:56
这是错误的,正确写法是:
bash
setenv ethaddr 02:00:00:12:34:56
10. U-Boot PCI 枚举测试
执行:
bash
pci enum
pci
正常输出应包含:
bash
01.00.00 0x10ec 0x8168 Network controller 0x00
含义:
text
PCIe 总线已经枚举到 Realtek 网卡
U-Boot 侧 PCIe 总线和 RTL8168/RTL8169 网卡硬件识别正常
11. U-Boot ping 测试
执行:
bash
ping 192.168.50.1
成功时会看到:
bash
Using eth_rtl8169 device
host 192.168.50.1 is alive
这说明:
text
1. U-Boot 成功调用 eth_rtl8169 驱动
2. Jetson 能够通过板载有线网卡发送 ARP / ICMP
3. Ubuntu 虚拟机 ens38 能够回应
4. 整条链路已经打通
12. 成功后的 tcpdump 现象
成功时,Ubuntu 抓包窗口可以看到类似:
bash
02:00:00:12:34:56 > ff:ff:ff:ff:ff:ff, ethertype ARP, Request who-has 192.168.50.1 tell 192.168.50.2
00:0c:29:xx:xx:xx > 02:00:00:12:34:56, ethertype ARP, Reply 192.168.50.1 is-at 00:0c:29:xx:xx:xx
ICMP echo request
ICMP echo reply
判断依据:
text
看到 192.168.50.2 → 192.168.50.1 的 ARP / ICMP,说明 Jetson 包进入虚拟机。
看到 Reply,说明 Ubuntu 成功回应 Jetson。
13. 常见错误与排查
13.1 抓到 192.168.2.x 的包
现象:
bash
Request who-has 192.168.2.133 tell 192.168.2.1
原因:
text
VMware 桥接到了 Wi-Fi,而不是 USB 有线网卡。
解决:
text
虚拟网络编辑器中将 VMnet1 桥接到 Realtek USB FE Family Controller。
13.2 tcpdump 一直没有任何输出
原因可能是:
text
1. 虚拟机网络适配器 2 没有连接
2. 网络适配器 2 没有选择 VMnet1
3. VMnet1 没有桥接到 USB 有线网卡
4. 网线没插好
5. Jetson 网口灯或 USB 网卡灯不亮
排查:
bash
ip a show ens38
sudo tcpdump -ni ens38 -e 'arp or icmp'
同时检查 VMware:
text
网络适配器 2 = 自定义 VMnet1
VMnet1 = 桥接到 Realtek USB FE Family Controller
13.3 U-Boot 提示 ipaddr not set
现象:
bash
*** ERROR: `ipaddr' not set
解决:
bash
setenv ipaddr 192.168.50.2
saveenv
13.4 U-Boot 提示 ARP Retry count exceeded
现象:
bash
ARP Retry count exceeded; starting again
ping failed; host 192.168.50.1 is not alive
含义:
text
Jetson 已经尝试询问 192.168.50.1 的 MAC 地址,但没有收到 ARP Reply。
重点检查:
text
1. Ubuntu ens38 是否是 192.168.50.1/24
2. tcpdump 是否能抓到 192.168.50.2 的 ARP
3. VMware 是否桥接到正确的 USB 有线网卡
4. ethaddr 是否设置正确
5. 网线和网口灯是否正常
14. 最终配置汇总
Windows
text
以太网 5:
Realtek USB FE Family Controller
启用
不配置 192.168.50.1
显示"未识别的网络"是正常的
VMware 虚拟网络编辑器
text
VMnet1:
桥接模式
外部连接:Realtek USB FE Family Controller
VMnet8:
NAT 模式
用于虚拟机上网
VMware 虚拟机设置
text
网络适配器:
NAT
网络适配器 2:
自定义 VMnet1
已连接
启动时连接
Ubuntu
bash
sudo ip addr flush dev ens38
sudo ip addr add 192.168.50.1/24 dev ens38
sudo ip link set ens38 up
sudo tcpdump -ni ens38 -e 'arp or icmp'
Jetson U-Boot
bash
setenv ipaddr 192.168.50.2
setenv serverip 192.168.50.1
setenv gatewayip 192.168.50.1
setenv netmask 255.255.255.0
setenv ethaddr 02:00:00:12:34:56
saveenv
pci enum
pci
ping 192.168.50.1
15. 本次实验结论
本次实验最终确认:
text
Jetson Nano 板载 Realtek 8168/8169 网卡能够在 U-Boot 阶段正常工作。
U-Boot 可以通过 PCIe 枚举到网卡,并使用 eth_rtl8169 驱动完成网络通信。
VMware 中需要将第二块虚拟网卡桥接到 USB 有线网卡,而不是 Wi-Fi 或 VMnet8。
Ubuntu 虚拟机的 ens38 设置为 192.168.50.1/24,Jetson U-Boot 设置为 192.168.50.2/24 后,可以 ping 通。
这套流程也为后续继续复现:
text
1. U-Boot TFTP 下载
2. USB 网卡驱动移植
3. 网络启动调试
4. U-Boot 网络驱动源码分析
打下了基础。
text
Jetson 板子 192.168.50.2
↓
板载 RTL8169 有线网卡
↓
USB 转网口
↓
VMware VMnet1 桥接
↓
Ubuntu 虚拟机 ens38 192.168.50.1
这条链路已经打通了。
所以 tftpboot 下载功能理论上可以实现 。接下来只需要在 Ubuntu 虚拟机里搭建 TFTP 服务器,然后 U-Boot 端用 tftpboot 下载文件即可。
一、Ubuntu 虚拟机端配置 TFTP 服务
1. 安装 TFTP 服务
在 Ubuntu 虚拟机里执行:
bash
sudo apt update
sudo apt install tftpd-hpa tftp-hpa
2. 创建 TFTP 目录
bash
sudo mkdir -p /srv/tftp
sudo chmod 777 /srv/tftp
放一个测试文件进去:
bash
echo "hello from ubuntu tftp server" > /srv/tftp/test.txt
查看确认:
bash
ls -l /srv/tftp
应该能看到:
text
test.txt
3. 修改 TFTP 配置
编辑配置文件:
bash
sudo nano /etc/default/tftpd-hpa
建议内容改成这样:
bash
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure --create"
保存退出。
4. 重启 TFTP 服务
bash
sudo systemctl restart tftpd-hpa
sudo systemctl status tftpd-hpa
如果看到 active (running),说明服务启动成功。
5. 防火墙处理
如果 Ubuntu 开了防火墙,临时允许 TFTP:
bash
sudo ufw allow 69/udp
或者调试阶段直接关闭防火墙:
bash
sudo ufw disable
二、Ubuntu 本机先测试 TFTP 是否可用
在 Ubuntu 虚拟机里执行:
bash
cd /tmp
tftp 192.168.50.1 -c get test.txt
如果成功,/tmp 下会下载到:
bash
test.txt
检查:
bash
cat /tmp/test.txt
能看到:
text
hello from ubuntu tftp server
说明 TFTP 服务本身没问题。
三、U-Boot 端配置网络参数
在 Jetson U-Boot 里执行:
bash
setenv ipaddr 192.168.50.2
setenv serverip 192.168.50.1
setenv gatewayip 192.168.50.1
setenv netmask 255.255.255.0
setenv ethaddr 02:00:00:12:34:56
saveenv
确认:
bash
printenv ipaddr
printenv serverip
printenv netmask
printenv ethaddr
四、U-Boot 先 ping 测试
bash
pci enum
pci
ping 192.168.50.1
如果能看到:
text
Using eth_rtl8169 device
host 192.168.50.1 is alive
说明可以进行 TFTP 下载测试。
五、U-Boot 使用 tftpboot 下载文件
先查看有没有默认加载地址:
bash
printenv loadaddr
如果有,例如:
text
loadaddr=0x80000000
就直接用:
bash
tftpboot ${loadaddr} test.txt
如果没有 loadaddr,可以临时指定一个地址:
bash
tftpboot 0x80000000 test.txt
成功时会看到类似:
text
Using eth_rtl8169 device
TFTP from server 192.168.50.1; our IP address is 192.168.50.2
Filename 'test.txt'
Load address: 0x80000000
Loading: #
done
Bytes transferred = ...
这就说明 U-Boot 阶段 TFTP 下载成功。
六、后续下载真正文件
比如你要下载 u-boot.bin,先放到 Ubuntu 的 TFTP 目录:
bash
cp u-boot.bin /srv/tftp/
然后 U-Boot 里:
bash
tftpboot ${loadaddr} u-boot.bin
或者:
bash
tftpboot 0x80000000 u-boot.bin
七、如果 tftpboot 失败,按这个排查
1. ping 不通
说明网络链路还没通,先不要测 TFTP。
重点检查:
text
VMnet1 是否桥接 Realtek USB FE
Ubuntu ens38 是否是 192.168.50.1
Jetson ipaddr 是否是 192.168.50.2
2. ping 通,但 tftpboot 超时
常见原因:
text
TFTP 服务没启动
防火墙拦截 UDP 69
serverip 设置错
文件目录不是 /srv/tftp
检查:
bash
sudo systemctl status tftpd-hpa
sudo ufw status
ls -l /srv/tftp
3. 提示文件不存在
比如:
text
File not found
说明 U-Boot 要下载的文件名和 /srv/tftp 里的文件名不一致。
检查:
bash
ls -l /srv/tftp
U-Boot 里文件名要完全一致,包括大小写。
最终结论
你现在板子已经和电脑里的 Ubuntu 虚拟机成功连通了。
只要在 Ubuntu 上启动 tftpd-hpa,并把文件放到 /srv/tftp,U-Boot 里就可以通过:
bash
tftpboot ${loadaddr} test.txt
或:
bash
tftpboot 0x80000000 test.txt
实现从电脑下载文件到板子内存。
自动执行 TFTP 下载流程
你截图里的流程可以拆成这样:
bash
Hit any key to stop autoboot: 0
倒计时结束后,U-Boot 自动执行 bootcmd。
然后自动做了这些事:
bash
pci enum
pci
tftpboot 0x84000000 u-boot.bin
所以你看到:
bash
Scanning PCI devices on bus 0
Using eth_rtl8169 device
TFTP from server 192.168.9.119; our IP address is 192.168.9.9
Filename 'u-boot.bin'
Load address: 0x84000000
Bytes transferred = 659264
说明它自动从电脑 TFTP 服务器下载了 u-boot.bin 到板子内存地址:
bash
0x84000000
最后这一句:
bash
# goraw 0x84000000
看起来是老师执行 的,意思是从 0x84000000 这个内存地址开始运行刚下载的 u-boot.bin。
设置了这些环境变量
以你现在的网络环境为例,你可以这样配置:
bash
setenv ipaddr 192.168.50.2
setenv serverip 192.168.50.1
setenv gatewayip 192.168.50.1
setenv netmask 255.255.255.0
setenv ethaddr 02:00:00:12:34:56
setenv loadaddr 0x84000000
setenv bootfile u-boot.bin
然后设置自动下载命令:
bash
setenv bootcmd 'pci enum; pci; tftpboot ${loadaddr} ${bootfile}'
saveenv
这样以后板子上电后,如果你不按键打断,倒计时结束后它会自动执行:
bash
pci enum
pci
tftpboot 0x84000000 u-boot.bin
也就是自动从电脑下载 u-boot.bin 到内存。
如果想自动下载后直接运行
可以把 goraw 也加进去:
bash
setenv bootcmd 'pci enum; pci; tftpboot ${loadaddr} ${bootfile}; goraw ${loadaddr}'
saveenv
这样上电后会自动执行:
text
1. 初始化 PCIe
2. 扫描 PCI 设备
3. 使用 eth_rtl8169 网卡
4. 从 TFTP 服务器下载 u-boot.bin
5. 下载到 0x84000000
6. 直接运行这个 u-boot.bin
但是我建议你先不要自动 goraw
你现在最好先用安全一点的方式:
bash
setenv bootcmd 'pci enum; pci; tftpboot ${loadaddr} ${bootfile}'
saveenv
然后上电自动下载成功后,再手动执行:
bash
goraw ${loadaddr}
原因是:如果 u-boot.bin 文件有问题,自动 goraw 后可能直接卡死。先只自动下载,确认文件能正常下载,再手动运行更稳。
重点理解
tftpboot 只是下载到 RAM:
text
电脑 /srv/tftp/u-boot.bin
↓
tftpboot
↓
Jetson 内存 0x84000000
goraw 0x84000000 才是运行它:
text
从 0x84000000 开始执行刚下载的 u-boot.bin
所以做的事情不是"刷入板子",而是:
text
上电后自动通过网卡从电脑下载新的 u-boot.bin 到内存,
然后再用 goraw 临时运行这个新版本。
断电重启后,如果没有再次 TFTP 下载,它不会永久变成这个版本。