实验二十七 NFS 挂载根文件系统——改根不烧卡对应课件《第6章 构建Linux根文件系统-V2》6.2 节下Slide 49-57系列说明本系列基于华清远见 FS-MP1ASTM32MP157A开发板对应课件《第6章 构建Linux根文件系统》。实验二十五、二十六做的根文件系统还躺在 Ubuntu 里——本篇让板子用上它Ubuntu 出一个 NFS 共享目录板子的bootargs改成从网络挂根。这是第 6 章的上板大闭环点火后 init 跑我们写的 rcS、提示符显示我们 profile 定义的样式——根文件系统从此是自己的而且 NFS 根改起来不用烧卡Ubuntu 里改完板上重启就生效后面所有实验都吃这个红利。前置实验二十六根文件系统目录树已齐。一、NFS 是什么为什么根文件系统要挂它NFSNetwork File System 把服务器上的目录通过网络共享出来客户端像挂本地盘一样挂它。用在根文件系统上好处一句话根在服务器上、板子只管挂——改个脚本、换个程序、加个库Ubuntu 里cp完板子重启即生效完全不碰烧写。实验十三曾用 U-Boot 的nfs命令试过一次四行网关警告 T T T的教训还记得吗本篇是它的正戏内核的 NFS 客户端挂根U-Boot 只负责把 bootargs 递过去。拓扑沿用实验十三定档的那套板子.8↔ ASIX USB 网卡Windows.99↔ VMnet0 桥接 ↔ Ubuntuens38静态.100TFTP 服务器实验十三与本篇的 NFS 服务器是同一台 Ubuntu。二、实验环境实际项目实际值服务器Ubuntu 虚拟机ens38192.168.0.100实验十三配的静态 IP新增 NFS 服务客户端板子ipaddr 192.168.0.8实验九设的环境 串口根文件系统实验二十五/二十六的rfs-busybox/目录内核实验十九~二十二编的 5.4.31本篇要重编一次步骤 1开工自检10 秒ls rfs-busybox整棵树齐实验二十六步骤 7 的 find 清单板子能拦停进STM32MP、print serverip192.168.0.100。三、课件 ↔ 步骤对应表课件 Slide内容对应步骤49~53服务器端装 NFS、建共享目录、配 exports、使能 v2、重启、本机挂载验证步骤 254~56客户端 bootargsroot/dev/nfs nfsroot.txt 格式拆解步骤 457禁止 git hash 进版本号.scmversion步骤 147承实验二十六uevent helper 内核配置步骤 1——点火验收进自己的根文件系统步骤 5本篇动作 → 后面谁用 → 现在含糊的后果本篇动作后面哪里还会用现在含糊的后果/home/cnu/nfsboot/rfs共享根第 7 章起所有实验的根文件系统都挂它实验二十九 buildroot 的产物也放这儿每章都要重烧卡开发效率归零bootargs 的root/dev/nfs nfsroot... ip...第 6 章之后一切上板实验的启动入口格式错一个冒号内核找不到根 panic.scmversion第 7 章 insmod 模块内核与模块版本串必须一致版本不一致模块加载报Invalid module format查半天uevent helper 勾选rcS 第 10 行不再报错mdev 热插拔真正生效报错常驻还以为根做坏了改根不烧卡的调试模式全系列剩余实验的工作方式——四、实验步骤步骤 1内核先重编一次——uevent helper .scmversionSlide 47 57点火之前内核要动两处一次重编带上① 勾上 uevent helper实验二十六步骤 6 预告的报错修法cd内核源码/linux-5.4.31makemenuconfig# Device Drivers ---# Generic Driver Options ---# [*] Support for uevent helper# 退出时选 SavegrepUEVENT_HELPER .config# 应有 CONFIG_UEVENT_HELPERy② 建.scmversion按课件要求禁止 git 哈希进版本号echo.scmversion课件 Slide 57 的原话与红字第 5 章的编译配置让内核版本号带了 git hash每次 git 提交后版本号会变内核版本号与模块版本号不一致时模块无法运行——第 7 章要 insmod 自己编的.ko两者必须同串。执行echo .scmversion并重编后版本号回归纯净的5.4.31带哈希的 uImage 文件请保留保留保留课件原文连写三个用于检查作业——把arch/arm/boot/uImage先拷一份存档再重编。与实验十九步骤 3.3 的关系把账记平实验十九说课件没要求、建议留着哈希当铁证——那是第 5 章场景现在课件第 6 章明确要求建.scmversion为模块版本一致性第 7 章马上受益建。两处的道理各自成立第 5 章排障靠哈希第 7 章加载模块靠一致。③ 重编并送服务器一条命令LOADADDR 老规矩cparch/arm/boot/uImage /tmp/uImage-with-hash.bak# 保留带哈希版作业检查用make-j4uImage dtbsLOADADDR0xC2000040cparch/arm/boot/uImage /home/cnu/tftpboot/my_uImagechmod644/home/cnu/tftpboot/my_uImage重编后Image Name:变回干净的Linux-5.4.31——从此带不带哈希不再是出厂/自编的判据改看uname -a的编译者与时间我们的是(cnucnu-virtual-machine) 当天日期出厂的是(oe-useroe-host)Apr 8 07:08:47 UTC 2020。步骤 2服务器端配置Slide 49~53装 NFS 服务与客户端工具sudoaptupdatesudoaptinstallnfs-kernel-server nfs-common建共享目录把根文件系统搬进去mkdir-p/home/cnu/nfsbootcp-a你的路径/rfs-busybox /home/cnu/nfsboot/rfs# -a 连符号连接与权限一起带ls/home/cnu/nfsboot/rfs# bin dev etc lib linuxrc mnt proc root sbin sys tmp usr var配置 exports共享清单sudonano/etc/exports# 末尾加一行/home/cnu/nfsboot *(rw,sync,no_root_squash,no_subtree_check)nano 键位改完CtrlO回车保存、CtrlX退出——完整键位卡见实验二十步骤 1本系列通用。图实测顶替课件 Slide 50——nano 4.8 里改好的/etc/exports原有内容全是注释掉的示例末行新增/home/cnu/nfsboot *(rw,sync,no_root_squash,no_subtree_check)绿框。五个参数逐个懂课件 Slide 51参数含义/home/cnu/nfsboot共享目录步骤里建的那个*允许任意客户端 IP 访问也可写192.168.0.*收紧rw读/写权限sync数据同步写内存和磁盘——挂根文件系统用 syncasync 有丢数据风险no_root_squash远程 root 在此目录保有 root 权限——默认的 root_squash 会把远程 root 压成普通用户根文件系统就改不动了课件原话极不安全通常只用于挂载根文件系统no_subtree_check不检查父目录权限省事使能 NFS v2——开发板内核的 NFS 客户端默认按 v2 协商课件注明Ubuntu 的服务端默认可能不开 v2。这个文件是 root 的要用sudo打开sudonano/etc/default/nfs-kernel-serverCtrlEnd直接跳到文件末尾或用方向键滚到底另起一行加上RPCNFSDOPTS--nfs-version 2,3,4 --debug --syslog改完CtrlO回车保存、CtrlX退出——完整键位卡见实验二十步骤 1本系列通用。不带sudo打开的话 nano 是只读的保存时会报[ Error writing /etc/default/nfs-kernel-server: Permission denied ]。图实测顶替课件 Slide 52——/etc/default/nfs-kernel-server末行新增RPCNFSDOPTS--nfs-version 2,3,4 --debug --syslog绿框上面的RPCNFSDCOUNT8、RPCMOUNTDOPTS--manage-gids等行是 Ubuntu 自带默认不用动。重启服务并本机验证sudo/etc/init.d/nfs-kernel-server restartsudomountlocalhost:/home/cnu/nfsboot/rfs /mnt-tnfsls/mnt# bin dev etc lib linuxrc mnt proc root sbin sys tmp usr varsudoumount/mnt# 看完卸载别占着图实测顶替课件 Slide 53——nfs-kernel-server.service重启成功 sudo mount localhost:/home/cnu/nfsboot/rfs /mnt -t nfs后ls /mnt打出 13 样绿框linuxrc与mnt 看完sudo umount /mnt卸载——服务器本地自测通过NFS 服务工作正常。本机这一挂是 NFS 版的127.0.0.1 自测实验十三 TFTP 的同款思路服务器端问题在本机就暴露别把服务器配置错误带到板子上排查。步骤 3板子网络复核实验十三的遗产上电拦停进STM32MPSTM32MP print ipaddr netmask serverip ethaddr预期ipaddr192.168.0.8、netmask255.255.255.0、serverip192.168.0.100。哪条不对就setenv补上 saveenv实验九/十三的流程。顺手ping 192.168.0.100应is alive。图实测——print ipaddr netmask serverip ethaddr四件套ipaddr192.168.0.8、netmask255.255.255.0、serverip192.168.0.100、ethaddr与实验九设置一致ping 192.168.0.100→host 192.168.0.100 is alive绿框——网络复核全过。步骤 4bootargs 换成 NFS 根Slide 54~56课件的整串与拆解——IP 要换成我们拓扑的课件板的 client-ip 是.2我们板是.8服务器同为.100STM32MP setenv bootargs consolettySTM0,115200 root/dev/nfs nfsroot192.168.0.100:/home/cnu/nfsboot/rfs,prototcp rw ip192.168.0.8:192.168.0.100:192.168.0.1:255.255.255.0::eth0:off STM32MP saveenv这串长参数的官方出处是内核文档Documentation/filesystems/nfs/nfsroot.txt格式root/dev/nfs nfsroot[server-ip:]root-dir[,nfs-options] ipclient-ip:server-ip:gw-ip:netmask:hostname:device:autoconf[:dns0:dns1]字段我们的值说明root/dev/nfs——告诉内核根在网络文件系统上实验十六的unknown-block(0,0)panic 就是因为当时 root 空着nfsrootserver-ip:root-dir192.168.0.100:/home/cnu/nfsboot/rfs服务器与共享目录prototcp指定传输协议ipclient-ip192.168.0.8板子自己的 IP——内核起来后 U-Boot 的环境变量管不着了IP 必须从这里传ipserver-ip192.168.0.100NFS 服务器ipgw-ip192.168.0.1网关——我们实验室没有路由器同网段通信其实用不到它实验十三的教训跨网段才真的需要网关照课件格式填着即可ipnetmask255.255.255.0子网掩码iphostname空主机名不设ipdeviceeth0用哪块网卡——就一个网口ipautoconfoff不用 DHCP 自动配置IP 我们手工给死了ipdns0/1不写DNS不使用bootargs是环境变量跟内核文件无关——后面每次run mybootnettftp 两个文件 bootm都会带着它点火。步骤 5点火——走进自己的根文件系统STM32MP tftp c2000000 my_uImage STM32MP tftp c4000000 stm32mp157a-fsmp1a.dtb STM32MP bootm c2000000 - c4000000视频实测点火全程压缩版 5.2 MB 入库随文档走原版 11.5 MB 本地留档不入库——终点即第 6 章终极验收Please press Enter to activate this console.回车后[rootfsmp1a: /]#提示符出现。预期日志的看点自上而下Image Name: Linux-5.4.31——干净版本串.scmversion 生效编译者要看/proc/versionuname -a里没有这个信息见步骤 5 末尾的实测说明驱动初始化段网卡stmmac 5800a000.ethernet MAE0621A 枚举——NFS 挂根先过网络这一关eMMC 照常在列IP-Config: Complete:一行——内核按ip设好了网络deviceeth0, addr192.168.0.8, ... server192.168.0.100VFS: Mounted root (nfs filesystem) readonly on device 0:12.一类——根挂上了NFS 根默认先只读挂rw 由 bootargs 的 rw 请求重挂/生效以实测日志为准Run /sbin/init as init process——我们 busybox 的 init 上场rcS 悄悄跑完mount -a挂 tmpfs /tmp、mdev 七步——若仍见cant create /proc/sys/kernel/hotplug: nonexistent directory回步骤 1 查CONFIG_UEVENT_HELPERy落实没有、内核是否重编并重新 tftpPlease press Enter to activate this console.→回车→ 提示符[rootfsmp1a: /]#——profile 的 PS1 生效主机名是我们自己定的。进去后逐项验收ls / # bin dev etc lib linuxrc mnt proc root sbin sys tmp usr var 13 样 ls /bin | head # 一排 busybox 命令 mount # 头行 192.168.0.100:/home/cnu/nfsboot/rfs on / type nfs (rw,…,vers2…) # devtmpfs /dev、tmpfs /tmp、tmpfs /dev、devpts、proc、sysfs 各行 ls /dev | head # console、gpiochip0~2 等一排设备文件mmcblk2* 排序靠后head 截不到别慌 cat /proc/cpuinfo | grep -c processor # 2双核 uname -a # Linux 192.168.0.8 5.4.31 #4 SMP PREEMPT 当天日期时间 armv7l GNU/Linux cat /proc/version # Linux version 5.4.31 (cnucnu-virtual-machine)…——编译者证据在这里图实测——六项验收一屏全收ls /13 样齐ls /bin | head全是 busybox 命令红框mount头行192.168.0.100:/home/cnu/nfsboot/rfs on / type nfs (rw,…,vers2…)——NFS 根挂上、vers2说明步骤 2 的 v2 使能真谈成了devtmpfs/tmpfs/devpts/proc/sysfs 各行都在ls /dev一排设备文件grep -c processor打2双核绿注uname -aLinux 192.168.0.8 5.4.31 #4 SMP PREEMPT Sun Sep 27 23:11:29 CST 2026 armv7l GNU/Linux——纯净5.4.31无哈希无-dirty构建时间戳就是当晚.scmversion 生效的铁证。开头两行reg11: disabling/reg18: disabling是内核收尾时关掉没在用的调节器无害。两个与预测不同的实测事实说清楚uname -a的主机名是192.168.0.8不是fsmp1a——ip七字段里 hostname 留空时内核拿 client-ip 当主机名[rootfsmp1a: /]#里的fsmp1a来自/etc/profile的export HOSTNAMEfsmp1aPS1 用的是它。两处各管各的不矛盾。编译者不在uname -a里——uname -a只有版本号和构建时间戳(cnucnu-virtual-machine)要cat /proc/version才看得到。第 6 章终极验收达成U-Boot、内核、设备树、根文件系统——四件全部是自己的。玩完reboot回 U-BootNFS 根随便重启不怕写坏。五、注意事项no_root_squash不能漏——漏了它远程 root 被压权rcS 里mount/mkdir /dev/pts会报Permission denied实验二十九微调篇会再遇到一次类似的权限戏成因不同。exports 改完必须restartNFS 服务不重启不认新配置改完先本机mount localhost验证再上板。ip七字段用冒号分隔数量不能错——少一个冒号整串解析错乱症状是内核报IP-Config: Unable to set parameters或干脆静默拿不到 IP 后卡在Waiting forNFS。client-ip 是板子的.8别照抄课件的.2server-ip 是 Ubuntu 的.100——这两个 IP 从实验十三沿用写反了 NFS 找不到服务器。bootargs整串加单引号含空格的老规矩saveenv 后print bootargs逐字核对一遍再点火。板子与服务器之间别隔路由器——同一网段直连我们的桥接拓扑天然满足跨网段要动网关别自己加戏。重编内核后两个文件都要重新 tftpuImage 变了、dtb 没变但 DRAM 易失——bootm 前的老规矩md.l验魔数。六、验证点一览验证点命令通过的样子在哪一步敲uevent helper 已勾grep UEVENT_HELPER 内核/.configCONFIG_UEVENT_HELPERy步骤 1.scmversion 在位ls -l 内核/.scmversion文件存在重编后make ... uImage不再带哈希步骤 1带哈希版已存档ls -l /tmp/uImage-with-hash.bak存在作业检查用步骤 1NFS 服务在跑sudo /etc/init.d/nfs-kernel-server status、exportfs -vrunningexports 那行在列步骤 2本机挂载通sudo mount localhost:/home/cnu/nfsboot/rfs /mnt -t nfs ls /mnt13 个条目齐全看完 umount步骤 2rfs 内容齐ls /home/cnu/nfsboot/rfsbin dev etc lib linuxrc mnt proc root sbin sys tmp usr var步骤 2板子网络通ping 192.168.0.100U-Boot 里is alive步骤 3bootargs 正确print bootargs与步骤 4 逐字一致client-ip.8步骤 4根挂上看点火日志VFS: Mounted root (nfs filesystem)一行步骤 5rcS 跑完无报错看点火日志无cant create /proc/sys/kernel/hotplug步骤 5进自己的根提示符 ls /、mount、ls /dev、uname -a[rootfsmp1a: /]#四条命令的输出符合步骤 5 清单步骤 5不达标时的排查现象先查什么卡Waiting for/ NFS 超时一串T或nfs: server ... not responding服务器exportfs -v有没有那行板子ping .100通不通nfsroot路径拼写v2 使能加了没、服务重启没VFS: Unable to mount root fs on unknown-block(2,34)一类root/dev/nfs写了没漏了它内核还在找块设备ip冒号数量挂上了但 rcS 全线Permission deniedexports 的no_root_squashrfs目录是 root 拥有吗cp -a保留属主普通用户拷的会变属主——sudo chown -R root:root /home/cnu/nfsboot/rfs归位rcS 报cant create /proc/sys/kernel/hotplug步骤 1 的CONFIG_UEVENT_HELPERy与重编、重新 tftp实验二十六步骤 6进了 shell 但提示符是/ #不是[rootfsmp1a: /]#profile 没被执行——askfirst 起的是-/bin/sh登录 shell 会读 profile核对 etc/profile 文件名与内容Run /sbin/init后直接 panicno initrfs 里sbin/init指向 busybox 的连接与bin/busybox在不在——cp -a有没有漏板子拿到 IP 但挂载报Permission denied服务器侧日志exports 里目录路径写错/home/cnu/nfsboot权限七、实验完成标志内核重编完成CONFIG_UEVENT_HELPERy实测在.config、.scmversion就位、uname -a显示纯净5.4.31#4构建、当晚时间戳带哈希的 uImage 已存档/tmp/uImage-with-hash.bak步骤 1 实测NFS 服务器配置完成exports 五参数在列、v2 使能、服务重启后本机挂载验证通过步骤 2 实测图 01~03rfs-busybox已搬进/home/cnu/nfsboot/rfs13 个条目齐全步骤 2 实测——图 03 本机挂载ls /mnt可见板子网络复核print四件套 pingis alive步骤 3 实测图 04bootargs已切换为 NFS 根整串并 saveenvclient-ip为板子的.8步骤 4 实测——点火进入 NFS 根即整串生效的反证点火进入自己的根文件系统Please press Enter to activate this console.回车后[rootfsmp1a: /]#提示符出现点火视频入档mount头行192.168.0.100:/home/cnu/nfsboot/rfs on / type nfs (rw,…,vers2…)、ls /13 样、ls /dev设备文件、双核2、uname -a纯净5.4.31——验收一屏全过步骤 5 实测图 05——第 6 章终极验收八、下一步buildroot 构建根文件系统busybox 方案到此全通。但它有先天的不足只有命令、没有用户体系移植第三方软件要一个个手动搬库。下一篇实验二十八上 buildroot——一条 menuconfig 配到底、自动处理依赖、连用户名密码都能配出来做出更接近产品的根文件系统两套方案此后并存NFS 上两个目录bootargs 改一行即可切换。
阅读完成 · 觉得有帮助?