
1. 写在前面这块板子到底折腾的是什么几年前我第一次拿到一块工控单板板载 eMMC 只有 8GB跑的还是个精简版 Linux当时第一反应是“这不就是台小电脑嘛”。结果真正去配存储、刷系统、做恢复出厂的时候才发现工控单板和普通 PC 完全是两套玩法。普通 PC 你装个系统、分个区、引导坏了拿 U 盘修就行工控单板一旦 rootfs 写坏了轻则返厂重烧重则整个产线停摆。这篇文章我想把工控单板上最常见的三件事串起来讲透存储配置、系统升级、以及基于 OverlayFS 的恢复出厂机制。这三件事表面上是三个独立操作实际在工控场景里是一条完整的运维链路——你先把存储规划好才能让升级变得安全而升级方案一旦选定恢复出厂就成了最关键的兜底手段。文章里的命令和路径我都按常见 RK/Rockchip、全志等平台的 Linux 系统来写理论部分也是通用的你手里的板子只要跑的是标准 Linux 内核基本都能直接对照着实践。需要先说明一下这不是一篇“从零教你看懂 Linux”的基础教程而是面向已经能把系统跑起来、想进一步搞懂“这板子坏了怎么救、空间满了怎么加、系统怎么安全升级”的工程师和爱好者。如果你是刚接触嵌入式 Linux读起来可能有几个术语需要额外查一下但我尽量把原理讲得生活化把命令的每个参数也解释清楚。这篇文章是系列的第一篇重点放在存储布局和 OverlayFS 的原理与实操升级部分会先给一个总览具体到 A/B 分区和整镜像刷写的细节后面单独展开。2. 存储配置先把这块板子的“家底”摸清楚2.1 工控单板上有哪些存储介质工控单板上的存储和 PC 不太一样常见的就三类eMMC、SD/TF 卡、Nor/NAND Flash。大部分商业级工控板出厂时主系统是烧在 eMMC 里的容量从 4GB 到 64GB 不等比 PC 的硬盘小得多但胜在稳定、抗震动、断电不掉数据。SD 卡则通常被用作扩展存储、日志存储或者特殊场景下的启动介质。Nor Flash 容量最小但启动速度极快一般只放 bootloader 或者关键参数。我实际遇到最多的情况是这样的板子 eMMC 上烧了一个只读的 rootfs再叠一层 OverlayFS 用于运行时写入SD 卡则被格式化成 ext4 或 vfat用来存日志、配置文件或者作为数据交换区。这个结构本身就是一种存储配置策略核心目的是“系统层不被写坏数据层可以随便折腾”后面讲 OverlayFS 恢复出厂时你会看到这套设计是怎么闭环的。2.2 上手第一步查看存储拓扑拿到板子先别急着改东西第一件事是看清存储拓扑。我常用的三条命令缺一不可lsblk df -hT cat /proc/cmdlinelsblk能看到块设备树状结构比如mmcblk0是 eMMC、mmcblk1是 SD 卡、nvme0n1是 NVMe 盘。df -hT能看清每个挂载点的文件系统类型和占用率。而cat /proc/cmdline这条很容易被忽略但它恰恰是最关键的——内核启动参数里如果出现了rootUUIDxxx或root/dev/mmcblk0p7你就能立刻判断系统真正从哪个分区启动以及有没有挂载 OverlayFS 的相关参数。我之前调试一块板子lsblk 看一切正常df 也显示有 overlay 挂在根目录但就是没法恢复出厂后来一查 cmdline 才发现内核压根没带 overlay 参数系统是把 rootfs 当成普通读写分区挂载的。所以记住不看 cmdline 就动分区等于闭着眼改电路。2.3 分区方案怎么规划才合理规划分区不是越大越好而是“每一块都用途明确”。我在实际项目中比较推荐的分区套路是分区文件系统典型大小挂载点用途bootloader裸分区4-8MB无U-Boot 等引导程序单独放避免干扰bootvfat/ext4128-256MB/boot内核、设备树、initrdrootfsext4/erofs1-4GB/系统根文件系统尽量只读dataext4剩余全部/data业务数据、日志、可写内容backupext4256-512MB可挂可卸系统备份或恢复出厂用的镜像这个方案的优点非常明显bootloader 和内核、rootfs 物理隔离互不干扰rootfs 可以做只读挂载配合 OverlayFS 实现“假可写”也就为恢复出厂打好了底子data 独立分区即使系统坏了数据还在重刷系统也不会影响业务数据。如果你用的是全志或者 Rockchip 的板子SDK 里通常有现成的分区表模板但默认模板里 data 分区经常被划得特别小拿到手之后第一步就是按实际需求重新调整。我个人不推荐一股脑把所有空间都塞给 rootfs因为工控场景里“备份系统”和“保存数据”这两个需求永远比“系统又多装了几个软件包”更刚性。2.4 修改分区后如何正确处理文件系统分区方案定下来之后实际操作上很多新手会在这里翻车。用fdisk或parted修改分区表只是第一步接下来还要让内核重新读取分区表partprobe /dev/mmcblk0然后对新分区做格式化mkfs.ext4 /dev/mmcblk0p4这两条命令看似简单但有个很隐蔽的坑如果你修改的分区正在被系统挂载使用partprobe会报Device or resource busy。这时候最稳妥的办法是进入 recovery 模式或者从 SD 卡启动系统再操作 eMMC 分区表。你千万不要想着“我直接 umount 掉再重新挂载就完事”因为 rootfs 通常无法被卸载强行操作极易把正在运行的系统搞崩。还有一个小习惯我非常推荐格式化 ext4 的时候加上-L指定卷标比如mkfs.ext4 -L data /dev/mmcblk0p4。之后写/etc/fstab时用LABELdata而不是/dev/mmcblk0p4来挂载这样即使设备节点因为插入了 SD 卡而变化挂载关系依然稳定。2.5 fstab 的写法与常见错误/etc/fstab是存储配置的收尾环节。我的典型写法如下LABELboot /boot vfat defaults,ro 0 0 LABELrootfs / ext4 defaults,ro,noatime 0 1 LABELdata /data ext4 defaults,noatime 0 2 tmpfs /tmp tmpfs defaults,size128M 0 0这里有几个值得展开讲的细节。rootfs 挂载成ro是工控系统安全性的基础配合 OverlayFS 后既能满足运行时写入需求又能让系统重启后自动回到“出厂状态”这一点后面的章节会详细讲。noatime能减少大量无意义的写操作尤其对 eMMC 这种有擦写寿命的存储来说积少成多能有效延长寿命。tmpfs挂到/tmp或/var/log的某个子目录可以让系统把高频日志写在内存里而不是疯狂闪存盘。踩坑最多的就是0 1和0 2这两个数字的语义。第一个数字是是否需要 dump 备份第二个是fsck检查顺序——根文件系统必须是 1其他统一 2如果都在同一块磁盘上fsck顺序没必要区分太细但千万不要让根目录的检查顺序变成 0否则系统启动时不会自动修复文件系统错误细微的坏块会越积越多。3. 系统升级先看全局再动手实践3.1 升级工控系统为什么要慎之又慎普通 Linux 用户升级系统就是跑一下apt upgrade或者yum update但工控系统完全不是这个操作逻辑。工控板上的系统往往是一个深度裁剪过的镜像内核和根文件系统的版本绑定很严密SDK 里编出来的根文件系统和内核如果版本不匹配轻则某些外设模块加载失败重则系统起不来。加上很多工控板出厂时跑的还是只读 rootfs常规的包管理器制度根本没法直接操作。所以工控系统升级本质上是“整机版本升级”而非“增量补丁升级”。升级之前你必须回答三个问题现在的版本是什么升级包从哪里来升级失败怎么回滚3.2 升级的三种常规路线从操作路径上分我见过的主流升级方式有三种第一种是包管理器升级路线适用于开发板形态的产品或原型验证阶段。系统跑的是可读写 rootfs直接apt、opkg或yum在线安装。这种方式开发调试很省事但量产设备上很少采用因为网络环境、包源稳定性和依赖关系都很不可控。第二种是整镜像刷写路线就是把整套系统做成一个完整的镜像文件通常是.img或厂商自定义格式通过烧录工具、dd命令或厂商专用刷机脚本写入 eMMC。这个方式最直接恢复出厂也是同一套流程换一个镜像而已。缺点是你得停机刷写而且一旦中途断电板子就可能变砖。第三种是 A/B 双分区升级路线这是工业级产品最推荐的模式。板子上同时存在两个 rootfs 分区系统总是从标记为 active 的那一个启动。升级时把新系统写入另一个分区写入完成后把启动标志切换过去。这种方式的好处是“升级失败可以秒回滚”代价是存储空间翻倍对 eMMC 容量小于 8GB 的板子来说比较紧张。这三种方式各有适用的场景没有绝对的好坏。我自己的习惯是研发阶段用第一种小批量试产用第二种正式稳定交付的项目用第三种。3.3 升级前必不可少的备份动作不管选哪种升级路线备份这一步都不能省。很多人觉得“系统不是我做的我没法备份”其实工控系统备份没那么玄乎关键分区抓下来就行。先查看分区编号再把关键分区备份成镜像cat /proc/cmdline dd if/dev/mmcblk0p7 of/data/backup/rootfs_before_upgrade.img bs4M statusprogress如果板子在运行dd 线上备份正在使用的 rootfs 会有文件系统不一致的风险更稳的做法是让系统先进入 recovery 模式或者从 SD 卡启动一个最小系统再对 eMMC 做备份。我自己的习惯是备三样bootloader 分区、boot 分区、rootfs 分区。这三个东西加起来一般不到 2GB存到 U 盘或者 SD 卡里升级真出了问题十分钟就能回来。这里要特别强调一个经验备份的时候要在镜像文件名里写清楚版本号和时间比如rootfs_v1.2.3_20250101.img。我曾经遇到过同事把两个版本的镜像放同一个目录文件名只差一个字符结果恢复的时候刷错了版本在现场折腾了大半天才把系统找回来。3.4 升级失败的现场救援思路即使准备做得很充分升级也还是有翻车的可能。真到这一步的时候第一反应应该是保持冷静然后按优先级处理先确认硬件有没有彻底损坏再看 bootloader 能不能进入恢复模式最后才考虑重新刷写整个镜像。大部分工控板 U-Boot 都内置了一个按键进入的恢复模式按住特定按键上电系统会进入 USB 烧录或 SD 卡启动模式。这种情况下你只需要一个烧录工具和一份原始镜像就能把板子救回来。真正麻烦的是 eMMC 的 bootloader 区域也写坏了这时候就只能用串口、JTAG 或者拆芯片重新烧这个级别的维修一般只能找厂商或专业人员处理。所以我才一直强调升级动作要保守、方案要带备份和回滚任何“刷完再看能不能开机”的做法在产线上都是拿设备寿命开玩笑。4. OverlayFS 恢复出厂原理与实操一次讲明白4.1 OverlayFS 是怎么“变出”一个可写文件系统的OverlayFS 是 Linux 内核自带的联合文件系统它把一个或多个只读目录和一个可写目录“叠加”成一个看起来完全可写的目录。你可以把它想象成一张贴在墙上的便利贴墙上的内容永远不变便利贴上写的东西随意涂改把便利贴撕掉之后墙还是原来的墙。具体到工控系统上挂载关系通常是这样的lowerdir只读的 rootfs 分区比如/dev/mmcblk0p7upperdir一个可写的存储区域通常是 data 分区里的一个目录比如/data/overlay/upperworkdirOverlayFS 内部用于元数据管理的目录比如/data/overlay/work系统启动时把三部分联合挂载到/应用层看到的是一份“可写”的完整系统。所有对系统的修改新增文件、修改配置、安装软件都写进 upperdir而 lowerdir 里的原始系统文件始终保持原样。恢复出厂的原理也就在这把 upperdir 清空重启之后系统就回到了和刚烧录时一模一样的状态。这比重新刷写镜像快得多也不需要停机断网非常适合产线和远程运维场景。4.2 先用 mount 看清当前状态开始操作之前先用mount | grep overlay看看当前系统是不是真的跑在 OverlayFS 上。典型的输出大概长这样overlay on / type overlay (rw,relatime,lowerdir/mnt/rootfs-ro,upperdir/data/overlay/upper,workdir/data/overlay/work)看到这行说明系统已经按预期用上了 OverlayFS。如果输出的挂载点不是/或者完全没有 overlay 输出那说明你的系统没启用 OverlayFS恢复出厂也就无从谈起——你面临的是另一个问题可能需要对 rootfs 做只读化改造这属于进阶内容这里先按下不表。还有一个细节很多人在df -h里看到根目录显示overlay而不是/dev/mmcblk0pX就开始担心系统是不是坏了。这不是异常OverlayFS 挂载的根目录在df里的显示就是 overlay。真正要关注的是/data/overlay/upper所在分区的剩余空间因为所有的运行时写入都在消耗它。4.3 恢复出厂的三种实现方式恢复出厂的实现方式没有唯一标准我根据自己的项目经验整理成表格你可以按场景选用实现方式操作复杂度恢复速度适用场景清空 upperdir 后重启低中现场运维、远程恢复用脚本封装备份镜像到独立分区再恢复中高量产设备、定时自动恢复利用 u-boot 环境变量触发恢复高高设备频繁被误改配置的场景最简单直接的方式是清空 upperdirrm -rf /data/overlay/upper/* rm -rf /data/overlay/work/* sync reboot但注意如果系统当前正在运行直接rm -rfupperdir 里的文件会存在正在占用的情况效果不一定干净。所以更稳妥的做法是先切换到单用户模式或进入一个临时的 initramfs 环境再执行清理。如果你对系统掌控力比较强也可以写一个 systemd 服务让系统在重启前自动完成清理动作。我实际项目里用的是一套“双重保险”方案一份恢复出厂脚本放在 data 分区一份放在 boot 分区。正常情况下用脚本恢复万一 data 分区都出问题了就从 boot 分区加载恢复脚本用只读镜像里的备份数据重建整个 upperdir。4.4 实操演示完整跑一遍恢复出厂下面是一个可直接参考的恢复出厂脚本我没有用生产环境的完整代码但保留核心逻辑关键是让你看懂顺序和判断逻辑#!/bin/bash # factory_reset.sh OVERLAY_DIR/data/overlay FACTORY_ROOTFS_IMG/data/backup/rootfs_factory.img log() { echo [$(date %Y-%m-%d %H:%M:%S)] $ } # 1. 检查当前挂载 mount | grep overlay on / || { log overlay not found, exit exit 1 } # 2. 配置需要保留的数据比如业务证书、校准参数等 PRESERVE_LIST/data/overlay/etc/ssl /data/overlay/etc/calibration # 3. 把需要保留的数据临时移到安全位置 for item in $PRESERVE_LIST; do if [ -d $item ]; then cp -a $item /data/preserve_tmp/ 2/dev/null || true fi done # 4. 重建 upper 与 work 目录 rm -rf $OVERLAY_DIR/upper rm -rf $OVERLAY_DIR/work mkdir -p $OVERLAY_DIR/upper mkdir -p $OVERLAY_DIR/work sync # 5. 从备份镜像恢复 rootfs可选 if [ -f $FACTORY_ROOTFS_IMG ]; then dd if$FACTORY_ROOTFS_IMG of/dev/mmcblk0p7 bs4M statusprogress sync fi # 6. 把保留数据放回去 for item in $PRESERVE_LIST; do cp -a /data/preserve_tmp/$(basename $item) $item 2/dev/null || true done log factory reset done, reboot now reboot这个脚本的执行顺序是精心排过的先检查系统确实是 OverlayFS避免误操作普通系统再把需要保留的关键配置抽出来然后彻底清空 upper 和 work如果有更底层的出厂镜像也顺带刷回去最后把保留数据放回重启生效。有读者可能问upper 都清空了保留的数据放回还有意义吗有。工控设备往往有设备证书、Calibration 参数、序列号等属于“产品个体”的数据真正的恢复出厂不能把这类数据一起抹掉。所以恢复出厂脚本的核心不是“全删”而是“该删的删、不该删的留”。4.5 恢复出厂后如何验证系统“真的干净了”恢复出厂后不要急着下结论一定要验证。我的验证清单有三条# 1. 确认 overlay 挂载正常 mount | grep overlay # 2. 确认关键配置确实回到了出厂版本 cat /etc/os-release cat /etc/version # 某些厂商的自定义版本文件 # 3. 确认业务关键服务自动起来了 systemctl status your-app如果系统里有多个配置版本历史也可以在恢复前用快照方式留个存档比如tar czf /data/backup/etc_before_reset_$(date %Y%m%d_%H%M%S).tar.gz /data/overlay/upper/etc这样即使恢复出厂后又发现问题你也能回头查之前改过什么配置而不是两眼一抹黑。5. 常见问题与排查技巧实录5.1 OverlayFS 挂载失败排查系统启动到一半就卡住或者 shell 里发现根目录变成了/dev/mmcblk0p7而不是 overlay这种情况往往不是 OverlayFS 配置写错了而是挂载顺序出了问题。内核启动时 rootfs 先以 ro 方式挂载到临时目录然后 init 脚本再把 overlay 联合挂载到/。如果 init 脚本里执行组合挂载时upperdir对应的分区还没有挂载好OverlayFS 就会失败。这类问题的排查思路是从dmesg入手dmesg | grep -i overlay看有没有明确的错误信息比如file system on /dev/mmcblk0p4 is not supported或者No such file or directory。前者表示 data 分区的文件系统格式有问题后者表示 upper 目录没创建成功。你也可以检查/etc/fstab里 data 分区的挂载顺序确保它在 overlay 挂载之前就已经 ready。5.2 dd 刷机后系统起不来拿到一块新板子很多人喜欢直接dd把镜像写到整块 eMMC然后发现系统起不来。这种情况十有八九是镜像本身没问题但 eMMC 的 boot 区域需要单独处理。很多工控芯片Rockchip、Amlogic 等都有专门的 bootloader 烧录流程不能用通用的dd覆盖整块盘必须用厂商烧录工具先烧 bootloader再用dd写 rootfs。如果你只能拿到一个完整的.img镜像文件先不要急着dd用fdisk -l 镜像文件看看里面的分区偏移再用dd按偏移写入对应分区别整盘覆盖。5.3 升级后软件包与内核版本不匹配这是我最常被问到的问题之一。现象是你通过包管理器升级了一个库或者驱动模块重启后某个外设不工作了查内核日志大概率是 module 版本不匹配。原因在于工控板的内核通常不是发行版内核而是厂商 SDK 深度定制过的模块和内核的编译依赖很强单纯升级用户态软件不会出问题一旦动了内核模块前后版本必须严格对应。所以我的建议是如果产品已经进入稳定交付阶段不要用包管理器大版本升级内核模块所有涉及内核的变更走厂商 SDK 重新编译走整机镜像升级路线这样虽然动作重一点但可控性最强。5.4 常见问题速查表为了方便现场排查我把遇到过的典型问题整理成一个速查表现象大概率原因处理建议系统启动后根目录不是 overlayinit 脚本挂载顺序错误检查 fstab 与 init 脚本修改 fstab 后无法开机UUID/卷标不对或 fsck 顺序错进入救援模式修正 fstabdf 显示 overlay 空间变小upperdir 所在分区被写满清理 /data或加大 data 分区dd 刷机后启动卡在 bootloaderbootloader 区域被覆盖用厂商工具重新烧写 bootloader升级后某外设失效内核模块版本不匹配回到 SDK 重新编译内核与驱动6. 最后说一点我的实际体会做了这么久工控 Linux最深的感触是这些板子看着像 Linux实际上和通用 Linux 系统是两个世界。通用 Linux 崇尚灵活依赖包管理器随时可以升级工控 Linux 崇尚稳定哪怕损失一点便利性也要确保设备在恶劣环境下长期可靠运行。存储配置、升级、恢复出厂这三件事说到底都是在“稳定”和“可维护”之间找平衡。我个人在配置一台新工控板时一定会在第一时间做三件事把 rootfs 挂成只读并启用 OverlayFS给 data 分区留足余量写一个经过现场验证的恢复出厂脚本并和镜像一起备份到多个存储位置。这三件事做完后面不管怎么折腾设备心里都有底。另外建议你把 reset 脚本、镜像文件、烧录工具这三样东西放到一个固定目录并写一页 README 记录操作顺序因为你永远不知道下一次需要它的时候是不是正在产线现场、满手是灰、网络还连不上。关于 OverlayFS 的更多细节比如多层 lowerdir、灵活使用 workdir 的权限设计以及 A/B 分区升级的完整操作流程我在系列后续文章里再展开聊。这篇先到这里希望对正在跟工控板较劲的朋友有帮助。