适用系统:Windows 11(22H2 及以上)
目标:搭建好交叉编译环境 + NFS 服务,开发板能通过网络挂载 rootfs
为什么用 WSL2 而不是 VirtualBox?
| 对比项 | VirtualBox | WSL2 |
|---|---|---|
| 启动速度 | 30秒以上 | 2秒内 |
| 资源占用 | 高(独占内存) | 低(动态分配) |
| 与 Windows 文件互通 | 麻烦 | /mnt/c/ 直接访问 |
| NFS 给开发板访问 | 需配置桥接网卡 | 开启镜像网络后自动共享 IP |
ℹ️ 关于 WSL2 的 NFS 服务器:WSL2 内核 ≥ 5.15(运行
uname -r查看,当前主流为 6.6)已原生包含nfsd模块,可直接使用标准的nfs-kernel-server,与正点原子教程完全一致。旧版 WSL2(内核 < 5.15)才需要使用unfs3(用户态 NFS 服务器)。本教程以 nfs-kernel-server 为主。
整体流程
[Windows 11]
│
├─ Step 1: 安装 WSL2 + Ubuntu 22.04
├─ Step 2: 配置镜像网络(开发板能访问 WSL2)
├─ Step 3: 运行一键安装脚本
├─ Step 4: 把 rootfs 放入 NFS 目录
└─ Step 5: 开发板通过网络启动
Step 1:安装 WSL2 和 Ubuntu 22.04
1.1 确认 Windows 版本
按 Win + R 输入 winver,确认版本 ≥ 22H2(Build 22621)。
低于 22H2 请先通过 Windows Update 升级。
1.2 开启 WSL2
以管理员身份打开 PowerShell(右键开始菜单 → “Windows PowerShell (管理员)”):
wsl --install -d Ubuntu-22.04
这条命令会自动:
- 开启「适用于 Linux 的 Windows 子系统」功能
- 开启「虚拟机平台」功能
- 下载并安装 Ubuntu 22.04
等待安装完成,然后重启电脑。
1.3 首次启动 Ubuntu
重启后,Ubuntu 会自动打开黑色终端窗口,提示:
Installing, this may take a few minutes...
Please create a default UNIX user account. The username does not need to match your Windows username.
Enter new UNIX username:
输入你的用户名(比如 dev),然后输入密码(输入时不显示,属正常)。
1.4 验证 WSL2 安装成功
在 PowerShell 里运行:
wsl -l -v
应该看到:
NAME STATE VERSION
* Ubuntu-22.04 Running 2
VERSION 必须是 2,如果是 1,运行 wsl --set-version Ubuntu-22.04 2 升级。
Step 2:配置镜像网络(关键步骤)
这一步是让开发板能访问 WSL2 里的 NFS 服务器的关键。
默认情况下 WSL2 使用 NAT 网络,开发板无法直接访问。
开启「镜像网络」后,WSL2 与 Windows 共享同一个 IP,开发板直接就能连上。
2.1 创建 .wslconfig 文件
在 PowerShell 中运行:
notepad "$env:USERPROFILE.wslconfig"
记事本打开(可能提示文件不存在,点”是”新建),输入以下内容:
[wsl2]
networkingMode=mirrored
保存并关闭记事本。
2.2 重启 WSL2 使配置生效
wsl --shutdown
然后重新打开 Ubuntu(开始菜单搜索 “Ubuntu”)。
2.3 验证网络配置
推荐方式(有线/无线通用),在 Ubuntu 里运行:
hostname -I
输出示例:
192.168.2.142
这个 IP 就是开发板需要 NFS 连接的 IP,记下来。
同时在 Windows 的 CMD 或 PowerShell 里运行 ipconfig 交叉验证:有线用户看”以太网适配器”,无线用户看”无线局域网适配器 WLAN”,IPv4 地址应与上面完全一致。
⚠️ 关于
ip addr show eth0显示 state DOWN教程里有时会建议用
ip addr show eth0来查看 IP,但这条命令只适用于有线网卡已连接的情况。
上网方式 eth0 状态 说明 有线网(插了网线) state UP,有inetIP正常 无线网(WiFi) state DOWN,无 IP正常,eth0 对应物理网口,没插线就是 DOWN 不管有线还是无线,只要
hostname -I能显示出和 Windows 相同的局域网 IP,就说明镜像网络已经生效,可以继续下一步。
Step 3:安装服务(NFS + TFTP)
3.1 安装 nfs-kernel-server 和 tftpd-hpa
sudo apt update
sudo apt install -y nfs-kernel-server tftpd-hpa rpcbind
3.2 安装交叉编译工具链
sudo apt install -y gcc-arm-linux-gnueabihf
3.3 配置 NFS 共享目录
sudo mkdir -p /nfsroot
sudo chmod 777 /nfsroot
# 配置导出(保留本地版本,不要被包管理器覆盖)
echo "/nfsroot *(rw,sync,no_subtree_check,no_root_squash)" | sudo tee /etc/exports
3.4 配置 TFTP 目录
sudo mkdir -p /srv/tftp
sudo chmod 777 /srv/tftp
3.5 启动服务
sudo service nfs-kernel-server start
sudo service tftpd-hpa start
3.6 验证安装结果
# 验证交叉编译器
arm-linux-gnueabihf-gcc --version
# 验证 NFS 服务运行
sudo service nfs-kernel-server status
# 验证 NFS 导出列表
showmount -e localhost
# 应输出:/nfsroot *
# 验证 TFTP 服务运行
sudo service tftpd-hpa status
Step 4:准备 rootfs 和内核文件
4.1 rootfs 放入 NFS 目录
# 假设你有 rootfs.tar.gz
sudo tar -xzf rootfs.tar.gz -C /nfsroot/
# 检查
ls /nfsroot/
# 应该看到:bin dev etc lib proc sbin sys tmp usr var 等目录
4.2 内核和 DTB 放入 TFTP 目录
# 编译完成后
cp arch/arm/boot/zImage /srv/tftp/
cp arch/arm/boot/dts/imx6ull-xxx.dtb /srv/tftp/
# 验证
ls /srv/tftp/
# zImage imx6ull-xxx.dtb
Step 5:开发板网络配置
5.1 硬件连接
[Windows 电脑]
│
网线/路由器
│
[iMX6ULL 开发板]
开发板和电脑必须在同一个局域网(连接同一个路由器,或直连网线+设置静态 IP)。
5.2 在 U-Boot 里设置环境变量
开发板上电,在串口终端按任意键进入 U-Boot 命令行:
# 设置服务器 IP(WSL2/Windows 的 IP)
setenv serverip 192.168.1.105
# 设置开发板自己的 IP(在同一网段,随便一个未被占用的)
setenv ipaddr 192.168.1.200
# 设置网关
setenv gatewayip 192.168.1.1
# 设置 NFS 根目录路径
setenv nfsroot /nfsroot
# 设置内核启动参数(NFS 启动)
setenv bootargs "console=ttymxc0,115200 root=/dev/nfs nfsroot=${serverip}:${nfsroot},v3,tcp rw ip=${ipaddr}"
# 设置启动命令(通过 TFTP 加载内核和 DTB)
setenv bootcmd "tftp 0x80800000 zImage; tftp 0x83000000 imx6ull-xxx.dtb; bootz 0x80800000 - 0x83000000"
# 保存环境变量到 flash
saveenv
# 启动
boot
⚠️
imx6ull-xxx.dtb替换为你实际的 DTB 文件名。
5.3 验证 TFTP 连通性(在 U-Boot 里)
先测试网络是否通:
ping 192.168.1.105
看到 host 192.168.1.105 is alive 说明网络正常。
再测试 TFTP:
tftp 0x80800000 zImage
看到传输进度条说明 TFTP 正常。
Step 6:验证 NFS 挂载
开发板 Linux 启动后,在串口终端验证 NFS 是否挂载成功:
# 在开发板上运行
mount | grep nfs
# 应输出:192.168.1.105:/nfsroot on / type nfs (rw,...)
df -h
# 应看到 NFS 根文件系统
也可以在 Ubuntu WSL2 里实时测试文件同步:
# WSL2 里创建测试文件
echo "hello from WSL2" > /nfsroot/test.txt
# 开发板上查看
cat /test.txt
# 输出:hello from WSL2
日常使用备忘
每次打开 WSL2 后确认服务状态
# 查看服务状态(配置了自启后应该自动运行)
sudo service nfs-kernel-server status
sudo service tftpd-hpa status
# 如果没运行,手动启动
sudo service nfs-kernel-server start
sudo service tftpd-hpa start
查看本机 IP(每次 DHCP 可能变化)
hostname -I
💡 建议把电脑 IP 设置为静态,这样 U-Boot 里的
serverip就永远不用改。
Windows:网络设置 → 以太网 → IP 设置 → 手动 → 填写固定 IP。
添加新的 NFS 导出目录
# 编辑 /etc/exports
sudo vim /etc/exports
# 添加:/新目录 *(rw,sync,no_subtree_check,no_root_squash)
# 重新加载
sudo exportfs -ra
sudo service unfs3 restart
交叉编译常用命令
# 编译 Linux 内核
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
make imx6ull_defconfig
make -j$(nproc) zImage dtbs
# 编译 U-Boot
export CROSS_COMPILE=arm-linux-gnueabihf-
make mx6ull_xxx_defconfig
make -j$(nproc)
# 编译单个驱动模块
arm-linux-gnueabihf-gcc -o mydrv.ko ...
常见问题排查
❌ NFS 挂载失败:Connection refused
# 检查 unfs3 是否运行
sudo service unfs3 status
# 检查端口是否监听
sudo netstat -tlnp | grep 2049
# 重启服务
sudo service unfs3 restart
❌ TFTP 超时
# 检查开发板和电脑是否能 ping 通
ping 192.168.1.200 # 在 WSL2 里 ping 开发板
# 检查 TFTP 文件是否存在
ls /srv/tftp/
# 检查 TFTP 服务
sudo service tftpd-hpa status
❌ WSL2 里 IP 和 Windows 不一样
说明镜像网络没有生效,检查:
# Windows PowerShell 里
wsl --version
# 确认 WSL 版本 >= 2.0.0
如果版本低,更新 WSL:
wsl --update
wsl --shutdown
然后重新打开 Ubuntu,再次 ip addr show eth0 验证。
❌ 脚本中途失败
脚本设置了 set -e,失败时会停止并显示出错的行。
常见原因:网络问题导致 apt 下载失败。
解决:检查网络,然后直接重新运行 ~/setup.sh(已安装的包会跳过)。
❌ WSL2 重启后 NFS 没有自动启动
检查 /etc/wsl.conf:
cat /etc/wsl.conf
应包含:
[boot]
command = "service unfs3 start; service tftpd-hpa start"
如果没有,手动添加:
sudo tee /etc/wsl.conf <<'EOF'
[boot]
command = “service nfs-kernel-server start; service tftpd-hpa start” EOF
然后 wsl --shutdown 重启 WSL2 使配置生效。
⚠️ 注意启动顺序:nfs-kernel-server 会自动拉起 rpcbind,无需单独写 rpcbind。
❌ U-Boot ping WSL2/Windows 失败:host is not alive
现象:开发板能 ping 通路由器(192.168.2.1),但 ping 不通 WSL2/Windows 的 IP(如 192.168.2.142)。
根本原因:Windows 防火墙默认屏蔽来自外部设备的 ICMP 入站请求。
网络拓扑:开发板通过网线连路由器,Windows/WSL2 通过 WiFi 连同一路由器,路由器负责桥接两者。WSL2 使用镜像网络模式,与 Windows 共享同一 IP,链路本身没有问题,防火墙才是障碍。
验证方法:先临时关闭防火墙确认:
# 管理员 PowerShell
netsh advfirewall set allprofiles state off
通了则说明是防火墙问题,测完恢复:
netsh advfirewall set allprofiles state on
正式修复:对局域网网段统一放行(nfs-kernel-server 使用多个动态 RPC 端口,逐个开放很麻烦,直接用子网规则一次解决):
# 允许 ICMPv4 入站(ping)
New-NetFirewallRule -DisplayName "Allow ICMPv4" -Protocol ICMPv4 -IcmpType 8 -Direction Inbound -Action Allow
# 允许局域网所有入站(覆盖 NFS/TFTP 所有端口,只对内网开放)
New-NetFirewallRule -DisplayName "Allow LAN 192.168.2.0/24" `
-Direction Inbound -RemoteAddress 192.168.2.0/24 -Action Allow
执行后无需重启,规则立即生效。
❌ 开发板有两个 eth 接口,不知道用哪个
判断方法:把两个都激活,查看 carrier 值(1=有网线,0=没插线):
ip link set eth0 up
ip link set eth1 up
cat /sys/class/net/eth0/carrier
cat /sys/class/net/eth1/carrier
ip link set ethX up执行后内核会打印link is not ready,这是正常现象——PHY 正在自动协商(需 1~3 秒)。协商完成后内核会打印Link is Up - 100Mbps/Full,之后再读 carrier 才准确。
❌ NFS 挂载超时:Connection timed out
现象:showmount -e localhost 正常,但开发板 mount 卡住或超时。
根本原因:Windows 防火墙拦截了 NFS 的 RPC 端口。nfs-kernel-server 除 2049 外还使用 portmapper(111)和动态 mountd 端口,单独开 2049 不够。
修复:使用局域网子网规则,见上方「U-Boot ping 失败」的正式修复方案。
❌ 开发板手动配置 IP 后断网,重连后 IP 丢失
手动用 ifconfig 配的 IP 不持久,网线重插或内核重置网卡后会消失。重新配置即可:
ifconfig eth0 192.168.2.200 netmask 255.255.255.0 up
route add default gw 192.168.2.1
如需持久化,修改 rootfs 里的网络初始化脚本(如
/etc/network/interfaces或/etc/init.d/相关脚本)。
延伸阅读
搭好开发环境后,建议继续理解启动链路,再进入内核移植。




