ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

RK3568嵌入式Linux NFS根文件系统搭建与调试实战

RK3568嵌入式Linux NFS根文件系统搭建与调试实战 1. 为什么要在 RK3568 上折腾 NFS 根文件系统做嵌入式 Linux 开发的同行大概都有过这种体验每次改一行应用代码就要重新编译、打包镜像、烧录 eMMC然后等板子重启一套流程下来少说五分钟。一天改二十次代码两个小时就耗在烧录和等待上了。这种开发节奏效率低得让人抓狂。NFS rootfs 就是来解决这个问题的。它的核心思路很简单板子启动时内核不再从本地存储eMMC、SD 卡加载根文件系统而是通过网络挂载宿主机上某个目录作为自己的根目录。这样一来你在宿主机上编译好的程序直接丢进那个目录板子重启就能用连拷贝都省了。改代码、编译、重启、验证整个循环压缩到几十秒以内。RK3568 是瑞芯微的一款四核 Cortex-A55 处理器主频 2.0GHz带 NPU、支持双千兆网口、PCIe、USB3.0 等一堆外设在工业网关、边缘计算、车载终端这些场景里用得很多。正点原子的 RK3568 开发板是市面上比较常见的一款资料相对齐全适合拿来入门和做项目验证。但说实话官方 SDK 默认的配置是面向量产的NFS 调试环境需要自己从头搭一遍中间涉及 U-Boot 环境变量、内核配置、网络参数、NFS 服务端配置等好几个环节任何一个环节出问题板子就卡在启动阶段屏幕上要么一片黑要么停在某个报错信息上不动。我前后在 RK3568 上搭过三套 NFS 调试环境踩过的坑包括但不限于U-Boot 的bootargs里 IP 地址写错导致内核找不到 NFS 服务器、内核编译时忘了勾选 NFS 客户端支持、NFS 服务端版本和内核挂载参数不匹配、TFTP 传内核镜像时网络不通等等。每次排查都要花不少时间因为启动阶段的报错信息往往很隐晦有时候就是一行VFS: Unable to mount root fs具体原因得靠经验去猜。这篇内容就是把这些经验整理出来从 U-Boot 环境变量配置、TFTP 服务搭建、内核配置、NFS 服务端配置到最终调试按实际操作的顺序一步步讲清楚。适合正在用 RK3568 做开发、想搭 NFS 调试环境的同行参考也适合其他嵌入式平台做类似配置时借鉴思路。整个流程我已经在正点原子 RK3568 开发板上完整验证过按这个步骤走基本可以一次跑通。2. 搭建前的环境准备与网络拓扑确认2.1 硬件连接与网络规划在动手改任何配置之前先把物理连接和网络规划理清楚。NFS rootfs 的本质是板子通过网络从宿主机拉取根文件系统所以板子和宿主机之间必须网络互通。最稳妥的方式是用一根网线把板子的千兆网口和宿主机的网口直连或者两者都接到同一个交换机/路由器上。我推荐直连的方式原因有两个一是直连不依赖外部网络环境在办公室、实验室、家里都能用二是直连可以省去路由器 DHCP 分配的变量IP 地址完全由自己控制排查问题时少一个不确定因素。网络规划建议如下角色IP 地址说明宿主机Ubuntu192.168.1.100NFS 服务端 TFTP 服务端RK3568 开发板192.168.1.200NFS 客户端子网掩码255.255.255.0同一网段网关192.168.1.1直连时可随意填不影响 NFS 挂载这里有个细节需要注意宿主机的 IP 地址必须是静态的不能是 DHCP 动态获取的。因为 U-Boot 的bootargs里写死了 NFS 服务器的 IP如果宿主机 IP 变了板子就挂载不上了。在 Ubuntu 上设置静态 IP 可以通过图形界面的网络设置也可以直接改/etc/netplan/下的配置文件。我习惯用 netplan配置示例如下network: version: 2 ethernets: enp3s0: addresses: - 192.168.1.100/24 dhcp4: no改完之后执行sudo netplan apply生效。注意网卡名称enp3s0要根据自己机器的实际情况改用ip addr命令可以查看。2.2 宿主机必备软件安装宿主机上需要装两个服务TFTP 和 NFS。TFTP 用来给板子传内核镜像和设备树文件NFS 用来提供根文件系统。这两个服务在 Ubuntu 上安装都很简单sudo apt update sudo apt install tftp-hpa tftpd-hpa nfs-kernel-server -y装完之后先别急着配置确认一下版本信息。NFS 服务端的版本会影响板子挂载时使用的协议版本这个后面会详细讲。dpkg -l | grep nfs正常情况下会看到nfs-kernel-server的版本号Ubuntu 20.04 一般是 1.3.4 左右Ubuntu 22.04 会更新一些。版本本身不是大问题关键是配置时要明确指定支持的 NFS 协议版本。2.3 确认板子的 U-Boot 支持网络启动RK3568 的 U-Boot 默认是支持网络功能的但不同厂家的 SDK 配置可能有差异。上电后进入 U-Boot 命令行执行ping命令测试网络 ping 192.168.1.100如果能看到host 192.168.1.100 is alive之类的回复说明 U-Boot 的网络驱动工作正常。如果提示No ethernet found或者ping failed那就要先排查网络驱动的问题。正点原子的 RK3568 板子用的是 Realtek 的千兆 PHYU-Boot 里一般已经适配好了但如果你用的是其他厂家的板子可能需要确认设备树里 PHY 的配置是否正确。有个同行遇到过fmql uboot 千兆网不通的问题最后发现是 PHY 的复位引脚配置不对设备树里改一下就好了。所以如果 ping 不通先检查硬件连接再检查 U-Boot 的设备树配置。3. TFTP 服务端配置与内核镜像传输3.1 TFTP 服务配置的细节TFTP 服务的配置文件在/etc/default/tftpd-hpa默认内容大概是这样的TFTP_USERNAMEtftp TFTP_DIRECTORY/var/lib/tftpboot TFTP_ADDRESS:69 TFTP_OPTIONS--secure我一般会把 TFTP 的根目录改到自己习惯用的路径比如/home/username/tftpboot这样拷贝文件方便。改完之后是这样的TFTP_USERNAMEtftp TFTP_DIRECTORY/home/username/tftpboot TFTP_ADDRESS0.0.0.0:69 TFTP_OPTIONS--secure --create这里有几个点要说明。TFTP_ADDRESS改成0.0.0.0:69表示监听所有网卡的 69 端口默认的:69在某些系统上可能只监听 IPv6导致板子连不上。--create选项允许上传文件虽然我们主要用下载功能但加上也无妨。改完配置后创建目录并设置权限mkdir -p /home/username/tftpboot chmod 777 /home/username/tftpboot sudo systemctl restart tftpd-hpa sudo systemctl status tftpd-hpa状态显示active (running)就说明服务起来了。可以在 TFTP 目录里放一个测试文件然后在宿主机上用tftp命令自己连自己测试一下echo hello /home/username/tftpboot/test.txt tftp 192.168.1.100 tftp get test.txt tftp quit如果能下载下来说明 TFTP 服务配置没问题。3.2 内核镜像与设备树的准备RK3568 的 SDK 编译完成后会在kernel/arch/arm64/boot/目录下生成Image文件在kernel/arch/arm64/boot/dts/rockchip/目录下生成.dtb文件。把这两个文件拷贝到 TFTP 目录cp kernel/arch/arm64/boot/Image /home/username/tftpboot/ cp kernel/arch/arm64/boot/dts/rockchip/rk3568-atk-evb.dtb /home/username/tftpboot/注意 dtb 文件名要根据自己板子的实际型号来正点原子的 RK3568 开发板对应的 dtb 一般是rk3568-atk-evb.dtb或者类似的命名。如果不确定可以在 SDK 的device/rockchip/rk3568/目录下找找配置文件中指定的 dtb 名称。这里有个经验每次重新编译内核后记得把新的 Image 和 dtb 重新拷贝到 TFTP 目录。我有时候改完内核直接重启板子忘了拷贝结果板子跑的还是旧内核排查半天才发现问题。后来我写了个小脚本编译完自动拷贝#!/bin/bash cp kernel/arch/arm64/boot/Image /home/username/tftpboot/ cp kernel/arch/arm64/boot/dts/rockchip/rk3568-atk-evb.dtb /home/username/tftpboot/ echo Copy done.放在 SDK 根目录下编译完执行一下就行省心不少。3.3 U-Boot 中 TFTP 传输的验证在 U-Boot 命令行里先用ping确认网络通然后用tftp命令拉取内核镜像 tftp 0x02080000 Image地址0x02080000是 RK3568 上内核加载的常用地址具体值可以参考 SDK 里的环境变量设置。传输成功后U-Boot 会显示传输的文件大小和耗时。如果传输失败常见原因有TFTP 服务没启动或者防火墙挡住了 69 端口宿主机 IP 和板子 IP 不在同一网段文件名写错或者文件不在 TFTP 目录里防火墙的问题在 Ubuntu 上比较常见默认的 ufw 可能会拦截 TFTP 的流量。可以临时关闭防火墙测试sudo ufw disable如果关闭后能传输那就需要添加规则允许 69 端口而不是一直关着防火墙。4. NFS 服务端配置与根文件系统准备4.1 NFS 导出目录的配置NFS 服务端的配置文件是/etc/exports在里面添加一行/home/username/nfsroot 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)这一行的含义逐项解释一下/home/username/nfsroot要导出的目录也就是板子的根文件系统所在目录192.168.1.0/24允许访问的网段也可以写具体的 IPrw读写权限调试阶段需要写权限方便在板子上直接改文件sync同步写入数据更安全但性能略低。调试阶段建议用 sync避免断电丢数据no_subtree_check关闭子树检查减少不必要的开销提高兼容性no_root_squash允许客户端的 root 用户保持 root 权限这个很重要否则板子上的 root 用户会被映射成匿名用户很多操作会权限不足改完 exports 文件后执行sudo exportfs -ra sudo systemctl restart nfs-kernel-server可以用showmount -e localhost查看导出列表确认配置生效。4.2 根文件系统的制作与放置RK3568 的 SDK 一般会提供 Buildroot 或 Yocto 构建的根文件系统也可能提供 Ubuntu 的根文件系统。不管哪种最终都需要得到一个完整的根文件系统目录里面包含bin、sbin、lib、etc、usr等标准目录。如果 SDK 提供的是.img镜像文件需要先挂载或者解压出来mkdir /mnt/rootfs sudo mount -o loop rootfs.img /mnt/rootfs sudo cp -a /mnt/rootfs/* /home/username/nfsroot/ sudo umount /mnt/rootfs如果 SDK 直接提供了根文件系统的压缩包解压到 NFS 目录即可sudo tar -xvf rootfs.tar.gz -C /home/username/nfsroot/放置完成后检查一下关键目录是否存在ls /home/username/nfsroot/应该能看到bin、dev、etc、home、lib、proc、root、sbin、sys、tmp、usr、var这些目录。如果缺少dev、proc、sys这些目录需要手动创建sudo mkdir -p /home/username/nfsroot/{dev,proc,sys,tmp} sudo chmod 1777 /home/username/nfsroot/tmptmp目录的权限 1777 表示所有用户可读写但只有文件所有者能删除自己的文件这是标准做法。4.3 NFS 版本兼容性问题的处理这是最容易踩坑的地方。不同版本的 NFS 协议在挂载参数上有差异如果内核挂载时指定的版本和服务端支持的不一致就会挂载失败。Linux 内核支持 NFSv2、NFSv3、NFSv4RK3568 的 BSP 内核一般默认支持 NFSv3 和 NFSv4。Ubuntu 的 nfs-kernel-server 默认同时支持 v3 和 v4。但有时候内核配置里只勾选了部分版本导致挂载时报Protocol not supported。在 U-Boot 的bootargs里可以通过nfsvers参数指定 NFS 版本nfsroot192.168.1.100:/home/username/nfsroot,nfsvers3我建议先用nfsvers3因为 v3 的兼容性最好配置也最简单。如果 v3 不行再试 v4。v4 的配置稍微复杂一些涉及到fsid和nfsroot路径的映射问题。另外内核配置里需要确保以下选项被勾选CONFIG_NFS_FSy CONFIG_NFS_V3y CONFIG_NFS_V3_ACLy CONFIG_NFS_V4y CONFIG_ROOT_NFSyCONFIG_ROOT_NFSy这个选项特别关键它允许内核直接挂载 NFS 作为根文件系统。如果这个没勾内核启动时会报VFS: Cannot open root device nfs or unknown-block(0,255)。5. 内核配置中与 NFS 启动相关的关键选项5.1 网络驱动与根文件系统选项RK3568 的内核配置里和 NFS 启动直接相关的选项分布在几个不同的菜单里。用make menuconfig进入配置界面需要确认以下选项网络设备支持Device Drivers --- Network device support --- Ethernet driver support --- * Rockchip GMAC ethernet support这个选项确保内核启动后能驱动板子上的千兆网口。如果这个没勾内核启动后网络不通NFS 挂载自然失败。网络文件系统File systems --- Network File Systems --- * NFS client support * NFS client support for NFS version 3 * NFS client support for NFS version 4 * Root file system on NFS这几项必须全部勾选。Root file system on NFS就是前面提到的CONFIG_ROOT_NFS它是内核能够把 NFS 目录当作根文件系统的前提。IP 自动配置Networking support --- Networking options --- * IP: kernel level autoconfiguration * IP: DHCP support * IP: BOOTP support如果bootargs里用的是ipdhcp那 DHCP 支持必须勾选。如果用的是静态 IP 配置比如ip192.168.1.200:192.168.1.100::255.255.255.0::eth0:off那 BOOTP 支持可以不勾但 IP 自动配置这一项还是要勾上。5.2 内核命令行参数的传递机制U-Boot 通过bootargs环境变量把参数传给内核内核解析这些参数来决定根文件系统从哪里挂载。一个典型的 NFS 启动bootargs是这样的setenv bootargs consolettyS2,1500000n8 root/dev/nfs rw nfsroot192.168.1.100:/home/username/nfsroot,nfsvers3 ip192.168.1.200:192.168.1.100:192.168.1.1:255.255.255.0::eth0:off逐段解释consolettyS2,1500000n8指定串口控制台RK3568 一般用 ttyS2波特率 1500000root/dev/nfs告诉内核根文件系统是 NFSrw根文件系统以读写方式挂载nfsroot192.168.1.100:/home/username/nfsroot,nfsvers3NFS 服务器 IP 和导出路径指定 NFS 版本为 3ip192.168.1.200:192.168.1.100:192.168.1.1:255.255.255.0::eth0:off板子的 IP、服务器 IP、网关、掩码、网卡名、自动配置关闭这个ip参数的格式是固定的客户端IP:服务器IP:网关:掩码:主机名:网卡名:自动配置。中间的主机名可以留空自动配置写off表示使用静态 IP。5.3 设备树中网络相关的配置检查RK3568 的设备树里以太网节点的配置直接影响内核启动后网络能否正常工作。以正点原子的板子为例设备树里一般会有这样的节点gmac1 { phy-mode rgmii; clock_in_out output; snps,reset-gpio gpio3 RK_PB7 GPIO_ACTIVE_LOW; snps,reset-active-low; snps,reset-delays-us 0 20000 100000; assigned-clocks cru SCLK_GMAC1_RX_TX; assigned-clock-parents cru SCLK_GMAC1_RGMII_SPEED; pinctrl-names default; pinctrl-0 gmac1m1_miim gmac1m1_tx_bus2 gmac1m1_rx_bus2 gmac1m1_rgmii_clk gmac1m1_rgmii_bus; phy-handle rgmii_phy1; status okay; };这里有几个关键点phy-mode要匹配实际的硬件连接方式RGMII 或 RMIIsnps,reset-gpio要对应正确的 GPIO 引脚status必须是okay。如果这些配置有误内核启动后网口不工作NFS 挂载就会超时失败。有个同行遇到过rk3568 uboot 千兆网不通的问题最后发现是设备树里 PHY 的复位 GPIO 写错了改过来就好了。所以如果 U-Boot 阶段 ping 不通先查设备树里的网络节点配置。6. U-Boot 环境变量配置与启动流程串联6.1 环境变量的设置与保存在 U-Boot 命令行里需要设置几个关键的环境变量setenv ipaddr 192.168.1.200 setenv serverip 192.168.1.100 setenv gatewayip 192.168.1.1 setenv netmask 255.255.255.0 setenv bootargs consolettyS2,1500000n8 root/dev/nfs rw nfsroot192.168.1.100:/home/username/nfsroot,nfsvers3 ip192.168.1.200:192.168.1.100:192.168.1.1:255.255.255.0::eth0:off setenv bootcmd tftp 0x02080000 Image; tftp 0x0a100000 rk3568-atk-evb.dtb; booti 0x02080000 - 0x0a100000 saveenvbootcmd的含义是先从 TFTP 服务器下载内核镜像到内存地址0x02080000再下载设备树到0x0a100000然后用booti命令启动内核把设备树地址传给它。saveenv把环境变量保存到存储介质里下次上电自动生效。如果不执行saveenv重启后设置就丢了。6.2 启动流程的完整串联设置好环境变量后执行run bootcmd或者直接reset板子就会按照以下流程启动U-Boot 初始化网络通过 TFTP 下载内核镜像和设备树到内存U-Boot 把bootargs传递给内核跳转到内核入口内核启动初始化网络驱动根据ip参数配置网卡 IP内核根据nfsroot参数向 NFS 服务器发起挂载请求挂载成功后内核执行根文件系统里的/sbin/init系统正常启动整个流程中任何一步出错都会导致启动失败。常见的报错和对应原因报错信息可能原因TFTP error: File not found文件名写错或文件不在 TFTP 目录VFS: Unable to mount root fsNFS 服务未启动、IP 不对、导出路径不对NFS: Protocol not supportedNFS 版本不匹配IP-Config: Failed to open eth0内核网络驱动未加载或设备树配置错误Kernel panic - not syncing: VFS根文件系统挂载失败检查以上所有项6.3 调试过程中的实用技巧调试 NFS 启动时串口终端是唯一的信息来源。建议把串口的日志级别调高让内核输出更多信息。可以在bootargs里加loglevel8或者ignore_loglevel这样能看到内核的详细日志。另外如果 NFS 挂载失败内核会进入 panic 状态板子就卡住了。这时候可以按复位键重启回到 U-Boot 命令行修改bootargs再试。不要每次都重新烧录那样太浪费时间。还有一个技巧在宿主机上用tcpdump抓包可以看到板子和 NFS 服务器之间的通信过程。如果板子发了挂载请求但服务器没响应或者响应了但板子没收到抓包一看就清楚了。sudo tcpdump -i enp3s0 -n port 2049 or port 111NFS 使用 2049 端口rpcbind 使用 111 端口。抓包能看到完整的 RPC 调用过程对排查协议层面的问题很有帮助。7. 常见故障的排查链路与修复方案7.1 板子卡在 U-Boot 阶段无法下载内核现象执行run bootcmd后TFTP 传输一直超时或者报错。排查步骤在 U-Boot 里ping 192.168.1.100确认网络通不通如果 ping 不通检查网线连接、宿主机 IP、防火墙如果 ping 通但 TFTP 失败检查 TFTP 服务状态和目录权限确认文件名大小写是否匹配Linux 下文件名区分大小写我遇到过一种情况U-Boot 里 ping 得通但 TFTP 就是传不了。后来发现是宿主机的防火墙只放行了 ICMP没放行 TFTP 的 UDP 69 端口。关掉防火墙或者添加规则就好了。7.2 内核启动后找不到 NFS 根文件系统现象内核启动日志显示VFS: Unable to mount root fs on unknown-block(0,255)。排查步骤确认 NFS 服务端是否正常运行sudo systemctl status nfs-kernel-server确认导出目录是否正确showmount -e localhost确认bootargs里的nfsroot路径和 IP 是否正确确认内核配置里CONFIG_ROOT_NFS是否勾选确认板子和宿主机是否在同一网段这个报错是最常见的原因也最多。我建议按顺序逐项检查不要跳步。有一次我排查了半天最后发现是nfsroot路径里多了一个空格导致内核解析参数时出错。这种低级错误在紧张调试时很容易犯。7.3 挂载成功但启动过程中卡住现象NFS 挂载成功的日志已经打印出来了但系统启动到某一步就卡住不动。这种情况一般是根文件系统里的某个服务或者脚本有问题。可能的原因/etc/fstab里有挂载本地分区的条目但 NFS 环境下这些分区不存在导致挂载超时某个启动服务依赖网络但网络配置还没完成根文件系统里的库文件缺失或者版本不匹配排查方法在bootargs里加init/bin/sh让内核启动后直接进入 shell不执行正常的 init 流程。这样可以手动检查文件系统逐步排查问题。setenv bootargs consolettyS2,1500000n8 root/dev/nfs rw nfsroot192.168.1.100:/home/username/nfsroot,nfsvers3 ip192.168.1.200:192.168.1.100:192.168.1.1:255.255.255.0::eth0:off init/bin/sh进入 shell 后可以手动挂载/proc、/sys然后检查各个目录和文件。7.4 触摸屏方向不对等外设问题有同行问到rk3568 触摸竖屏改为横屏设备树修改的问题。这其实和 NFS 启动没有直接关系但在 NFS 调试环境下改起来很方便因为改完设备树重新编译 dtb通过 TFTP 下载重启就行不用重新烧录整个系统。触摸屏方向一般在设备树的触摸节点里配置比如gt1x { status okay; touchscreen-inverted-x; touchscreen-inverted-y; touchscreen-swapped-x-y; };具体加哪些属性取决于屏幕的安装方向和触摸 IC 的默认坐标系。touchscreen-swapped-x-y表示交换 X 和 Y 轴touchscreen-inverted-x表示 X 轴反向。组合使用可以适配各种旋转角度。改完 dtb 后通过 TFTP 下载重启立刻就能看到效果这就是 NFS 调试环境的便利之处。8. 调试环境下的开发效率提升实践8.1 应用程序的快速迭代NFS 根文件系统最大的好处就是应用程序的迭代速度。在宿主机上交叉编译好的程序直接拷贝到 NFS 导出目录里板子上就能运行不需要重启更不需要烧录。比如你正在调试一个基于 RK3568 的 EtherCAT 主站程序编译生成ethercat_master可执行文件后cp ethercat_master /home/username/nfsroot/usr/bin/然后在板子的串口终端里直接执行/usr/bin/ethercat_master改代码、编译、拷贝、运行整个循环不到一分钟。如果每次都要烧录 eMMC那效率完全没法比。8.2 内核模块的动态加载调试驱动时经常需要反复修改内核模块。NFS 环境下可以在宿主机上编译好.ko文件拷贝到 NFS 目录然后在板子上用insmod加载cp my_driver.ko /home/username/nfsroot/lib/modules/板子上insmod /lib/modules/my_driver.ko如果模块有问题导致内核崩溃重启板子即可不会影响 NFS 服务器上的文件。这种隔离性让调试驱动变得安全很多。8.3 根文件系统的备份与恢复NFS 根文件系统在宿主机上就是一个普通目录备份和恢复都很简单。在调试过程中如果改坏了某个配置文件导致系统起不来可以直接在宿主机上修复不需要通过板子操作。我习惯在开始调试前先打个快照cp -a /home/username/nfsroot /home/username/nfsroot.bak如果改坏了直接恢复rm -rf /home/username/nfsroot cp -a /home/username/nfsroot.bak /home/username/nfsroot这比在板子上用dd命令备份恢复快多了而且不会因为板子起不来而束手无策。8.4 多板子共用一个 NFS 根文件系统如果你手上有多个 RK3568 板子可以让它们共用同一个 NFS 根文件系统。只需要在 NFS 服务端的/etc/exports里允许整个网段访问然后每个板子设置不同的 IP 地址即可。但要注意如果多个板子同时写同一个文件可能会冲突。调试阶段一般不会遇到这个问题但如果要同时跑多个板子做压力测试最好还是给每个板子单独的根文件系统目录。9. 一些容易忽略的细节与个人经验9.1 串口终端的配置RK3568 的调试串口是 ttyS2波特率 1500000。这个波特率不是常见的 115200有些 USB 转串口线可能不支持这么高的波特率。如果串口终端显示乱码先检查波特率设置。我用的是 CH340 芯片的串口线支持 1500000 波特率工作正常。如果手头的线不支持换一根 FT232 芯片的试试。9.2 内核编译时的配置保存每次make menuconfig改完配置后记得保存到.config文件并且备份一份。RK3568 的 SDK 里内核配置文件一般在kernel/arch/arm64/configs/目录下文件名类似rockchip_linux_defconfig。可以把改好的配置保存回去make savedefconfig cp defconfig arch/arm64/configs/rockchip_linux_defconfig这样下次重新编译时配置不会丢。我有一次改完配置忘了保存重新编译后 NFS 支持又没了排查了半天才发现是配置没保存。9.3 NFS 挂载超时时间的调整默认的 NFS 挂载超时时间比较短如果网络稍有延迟可能会挂载失败。可以在bootargs里加nfsroot的timeo参数nfsroot192.168.1.100:/home/username/nfsroot,nfsvers3,timeo600timeo600表示超时时间为 60 秒单位是 0.1 秒。如果网络环境不太好可以适当加大这个值。9.4 关于 NFSv4 的额外配置如果非要用 NFSv4配置会稍微复杂一些。NFSv4 需要一个伪根文件系统在/etc/exports里要这样写/home/username/nfsroot 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash,fsid0)fsid0表示这是 NFSv4 的根。然后bootargs里的nfsroot路径要相应调整nfsroot192.168.1.100:/,nfsvers4注意路径变成了/因为fsid0已经把导出目录映射为 NFSv4 的根了。这个细节很容易搞错我当初就是从 v3 换到 v4 时没改路径导致挂载失败。9.5 调试完成后的收尾工作NFS 调试环境搭好之后开发效率确实高但也有一些需要注意的地方。比如NFS 根文件系统依赖网络如果网络不稳定板子可能会卡住。所以在做性能测试或者长时间运行测试时最好还是烧录到 eMMC 里跑。另外NFS 根文件系统的读写速度受网络带宽限制比本地存储慢不少。如果应用对 IO 性能要求高NFS 环境可能不适合做性能评估只适合做功能调试。我在实际项目中的做法是功能开发和调试阶段用 NFS 根文件系统快速迭代功能稳定后烧录到 eMMC 做性能和稳定性测试。两者结合既保证了开发效率又保证了测试的准确性。还有一点NFS 服务端的导出目录权限要设置好。如果多人共用一台宿主机做 NFS 服务器要避免互相干扰。可以给每个人分配不同的导出目录和 IP 段在/etc/exports里分别配置。最后分享一个我常用的小技巧在宿主机的 NFS 导出目录里放一个sync.sh脚本内容是根据当前编译产物自动更新根文件系统里的对应文件。比如#!/bin/bash cp /path/to/build/app /home/username/nfsroot/usr/bin/ cp /path/to/build/lib/*.so /home/username/nfsroot/usr/lib/ echo Sync done at $(date)每次编译完执行一下省去手动拷贝的麻烦。这个脚本可以根据项目实际情况定制把常用的拷贝操作都放进去日积月累能省不少时间。
返回列表