环境信息
| 角色 | IP 地址 |
|---|---|
| NFS 服务器 (Linux VM) | 192.168.0.133 |
| Zynq 板卡 | 192.168.0.100 |
| PC | 192.168.0.106 |
| rootfs | rootfs.tar.gz |
源文件只需要板卡的
rootfs.tar.gz
U-Boot 关键变量 (来自printenv)
设置IP地址
setenv ipaddr 192.168.0.100 # Zynq 板卡 IP setenv serverip 192.168.0.133 # NFS 服务器 IPkernel_image=uImage devicetree_image=devicetree.dtb kernel_load_addr=0x2080000 devicetree_load_addr=0x2000000 image_path=/ ipaddr=192.168.0.100 serverip=192.168.0.133 rootfs_partition=/dev/mmcblk0p2 bitstream_image=fpga.bit loadbit_addr=0x1000000 bootargs=console=ttyPS1,115200 earlyprintk rootfstype=ext4 rootwait clk_ignore_unused uio_pdrv_genirq.of_id=generic-uio一、准备工作 (PC 端)
1. 从 rootfs.tar.gz 生成 rootfs.img(eMMC 直接烧写用)
# 方法一:使用 mkfs.ext4 -d(推荐) mkdir rootfs_tmp sudo tar -xzf rootfs.tar.gz -C rootfs_tmp sudo chown -R root:root rootfs_tmp dd if=/dev/zero of=rootfs.img bs=1M count=2000 # count 根据实际 rootfs 大小调整,略大于解压后占用空间即可 sudo mkfs.ext4 -F -d rootfs_tmp rootfs.img sudo rm -rf rootfs_tmp # 方法二:loop 挂载法 dd if=/dev/zero of=rootfs.img bs=1M count=2000 sudo mkfs.ext4 -F rootfs.img sudo mkdir -p /mnt/rootfs sudo mount -o loop rootfs.img /mnt/rootfs sudo tar -xzf rootfs.tar.gz -C /mnt/rootfs sudo chown -R root:root /mnt/rootfs sudo umount /mnt/rootfs生成后的
rootfs.img可通过dd if=rootfs.img of=/dev/mmcblk0p2 bs=1M直接写入 eMMC。
二、NFS 服务端搭建 (192.168.0.133)
1. 安装 NFS 服务
sudo apt update sudo apt install nfs-kernel-server -y2. 准备 rootfs(NFS 导出用)
# 创建 NFS 导出目录 sudo mkdir -p /home/admin/workspace/nfs_rootfs # 上传并解压 rootfs.tar.gz 到 NFS 目录 cd /home/admin/workspace/nfs_rootfs sudo tar -xzf rootfs.tar.gz sudo chown -R root:root . rm -f rootfs.tar.gz3. 配置 NFS 导出
# 编辑 /etc/exports,添加: sudo tee -a /etc/exports <<'EOF' /home/admin/workspace/nfs_rootfs 192.168.0.0/24(rw,sync,no_root_squash,no_subtree_check,insecure) EOF # 应用导出 sudo exportfs -ra # 验证 sudo exportfs -v showmount -e 192.168.0.1334. 防火墙
# 如果 ufw 开启,放行 NFS 相关端口 sudo ufw allow from 192.168.0.0/24 to any port nfs sudo ufw allow from 192.168.0.0/24 to any port 111 # 或直接关闭 sudo ufw disable5. 自测
sudo mount -t nfs -o nfsvers=3 192.168.0.133:/home/admin/workspace/nfs_rootfs /mnt ls /mnt/ sudo umount /mnt三、板卡 U-Boot NFS 启动
板卡上电,在倒计时内按任意键打断 autoboot,进入 U-Boot 命令行:
# 1. 加载 FPGA bitstream(必须,否则外设不工作) fatload mmc 0:1 ${loadbit_addr} ${image_path}/${bitstream_image} fpga loadb 0 ${loadbit_addr} ${filesize} echo FPGA load OK # 2. 从 eMMC FAT 分区加载内核 fatload mmc 0:1 ${kernel_load_addr} ${image_path}/${kernel_image} # 3. 从 eMMC FAT 分区加载设备树 fatload mmc 0:1 ${devicetree_load_addr} ${image_path}/${devicetree_image} # 4. 设置 bootargs 为 NFS root setenv bootargs 'console=ttyPS1,115200 root=/dev/nfs rw nfsroot=192.168.0.133:/home/admin/workspace/nfs_rootfs,nfsvers=3 ip=192.168.0.100:192.168.0.133:192.168.0.1:255.255.255.0::eth0:off' # 5. 启动内核 bootm ${kernel_load_addr} - ${devicetree_load_addr}ip 参数格式:
ip=<板卡IP>:<服务器IP>:<网关>:<掩码>::<网卡>:off
四、修复 eMMC rootfs 分区
NFS 启动进入系统后执行:
# 1. 格式化 mmcblk0p2 umount /dev/mmcblk0p2 2>/dev/null mkfs.ext4 -F /dev/mmcblk0p2 # 2. 挂载 eMMC rootfs mount /dev/mmcblk0p2 /mnt # 3. 从当前 NFS 根文件系统复制全部内容 tar cf - \ --exclude=/proc \ --exclude=/sys \ --exclude=/dev \ --exclude=/run \ --exclude=/tmp \ --exclude=/mnt \ --exclude=/lost+found \ / | tar xf - -C /mnt # 4. 创建必要的空目录 mkdir -p /mnt/proc /mnt/sys /mnt/dev /mnt/run /mnt/tmp /mnt/mnt chmod 1777 /mnt/tmp # 5. 卸载并重启 sync umount /mnt reboot重启后板卡将以 eMMC ext4 rootfs 正常启动,无需再依赖 NFS。
五、故障排查
板卡无法 ping 通 NFS 服务器
# 在 U-Boot 中测试 ping 192.168.0.133NFS mount 失败 (access denied)
- 检查
/etc/exports中 IP 网段是否正确 (192.168.0.0/24) - 检查 NFS 服务是否运行:
sudo systemctl status nfs-kernel-server - 检查是否有防火墙:
sudo ufw status
内核不支持 NFS root
如果启动时报 "VFS: Unable to mount root fs",说明内核未编译 NFS 客户端支持,需要重新编译内核开启CONFIG_ROOT_NFS和CONFIG_NFS_FS。
mountd 端口随机变化
NFS mountd 默认使用随机端口,如果中间有防火墙可能需要固定端口:
# 编辑 /etc/default/nfs-kernel-server sudo sed -i 's/^RPCMOUNTDOPTS=.*/RPCMOUNTDOPTS="--port 40000"/' /etc/default/nfs-kernel-server sudo systemctl restart nfs-kernel-server