
玩Jetson设备的朋友应该都有过这种经历前一刻还在跑目标检测模型或者正在调试AGX Orin上的推理任务突然系统无响应强制断电重启后设备直接卡住屏幕上闪过一行EXT4-fs error或者Bad magic number in super-block然后就再也没有然后了。这篇文章要讲的就是我在Jetson Nano、Xavier NX这些设备上多次踩坑之后总结出来的一套从superblock损坏到最终恢复的完整实战流程。内容以EXT4文件系统为主线覆盖了故障成因、备份superblock的定位、e2fsck修复命令的详细用法以及修复过程中各种典型问题的应对方案。不管你是跑YOLOv5还是在Orin上部署Llama这类边缘推理任务这套流程都适用。1. Jetson设备文件系统的“命门”EXT4与superblock1.1 先从Jetson的存储布局说起Jetson系列产品的存储方案其实是比较杂的。Jetson Nano开发者套件用的是microSD卡官方镜像写进SD卡就能启动Jetson Xavier NX模组本身带16GB eMMC但很多开发者还是习惯从SD卡或NVMe启动到了AGX Orin这一代标配就是NVMe SSD了。但不管用哪种介质只要你是用NVIDIA官方镜像不管是SDK Manager烧的还是用balenaEtcher直接写SD卡最终的rootfs分区几乎无一例外都是EXT4文件系统。这个设计其实很有讲究。嵌入式设备上常见的选择无非是EXT4、F2FS、Btrfs这几个NVIDIA选EXT4图的是成熟稳定、兼容性好、工具链完善。EXT4从2008年进入主线内核至今经过了十几年的打磨像e2fsck、dumpe2fs、debugfs这些修复工具链非常成熟出了问题至少能救。反观F2FS虽然对闪存做了优化但修复工具相对少出问题更折腾。Btrfs虽然自带校验和快照但在老内核比如Jetson Nano早期的Ubuntu 18.04上支持度并不好而且NVIDIA官方也没提供Btrfs的默认镜像配置所以EXT4就是那个“不会出错的选择”。分区布局方面一张官方镜像SD卡大致是这样最前面是bootloader相关的小分区然后是内核和设备树分区最后是一个很大的EXT4分区承载rootfs。在Jetson设备上这个rootfs分区在系统里通常显示为/dev/mmcblk0p1把SD卡插到PC上则是/dev/sdX1这种形式。搞清楚这一点很重要因为后面所有修复操作都要精确对到这个分区上搞错了盘符可能把别的硬盘给格式化掉。1.2 superblock文件系统的“总账本”EXT4文件系统把整个分区划分成很多个块组block group每个块组管理一块连续的存储区域。而superblock也就是超级块是整个文件系统最顶层的元数据你可以把它理解成一本厚书的目录索引。里面记录了文件系统的块大小、总块数、空闲块数、inode总数、每块组包含多少块、文件系统挂载次数、最后一次挂载时间、UUID、特性标志等等。为什么superblock损坏是灾难性的因为内核挂载文件系统时第一步就是读取superblock来确认“这个分区是不是EXT4”“块大小多大”“从哪里开始找inode表”。如果superblock里的magic number不对内核会直接拒绝挂载报出Bad magic number in super-block。这就好比你去图书馆查书结果目录索引被人撕了管理员根本不知道该从哪个书架开始找。inode损坏可能还只是某个文件打不开、某个目录读不了但superblock一旦损坏整个分区就跟废了差不多。好在EXT4设计时考虑到了这点它在文件系统创建时就把superblock做了多份冗余备份存放在特定的块组里。默认情况下这些备份位于第1、3、5、7、9、25、27、49……等块组的起始位置具体分布受sparse_super特性影响。我们可以用工具查出来精确位置后面第3章会详细演示。1.3 为什么会坏掉电、异常关机与硬件老化我在实际维修中遇到的superblock损坏原因排前三的分别是非正常断电、SD卡老化损坏、镜像烧录中断。非正常断电是最常见的。很多Jetson设备被拿去做边缘计算节点放在现场无人值守供电一抖就重启。问题在于Linux系统对文件写入是有缓存的数据先写到内存的page cache里再由内核的pdflush线程在合适的时机落盘。你直接拔电意味着缓存里大量的元数据更新inode修改、块位图更新、目录项变更根本没写回磁盘superblock和实际数据之间就出现了不一致。极端情况下如果正好在更新superblock本身时断电那superblock就半残了。SD卡的老化也是大头。Jetson Nano那个SD卡槽本来就容易出问题再加上很多开发者用的是高速但非工业级的TF卡写入量大、温度高时间长了就会出现坏块。文件系统在坏块上写数据读回来校验不对内核就会报I/O error。前面提到的热词里有个“通过文件系统来屏蔽坏道的方法”这确实是老玩家会考虑的事情但对于superblock这种核心元数据坏道导致的损伤往往更致命——好在e2fsck在修复时也能识别这些坏块并做重映射尽量把损失控制住。至于镜像烧录中断多发生在用balenaEtcher烧写到一半拔卡、或者SD卡质量差导致写入不稳的情况。这类损坏往往一上电就报错甚至烧完就直接进不了系统。2. 修复前的“冷静期”情况评估与工具准备2.1 设备处于什么状态先别急着动手我见过不少朋友一看到EXT4-fs error就开始瞎敲命令结果越搞越糟。所以修复前第一步是冷静下来判断设备到底处于哪种状态。大致分三种情况第一种是完全无法启动开机后卡在NVIDIA logo或者串口日志里能看到内核在挂载rootfs时报错第二种是系统能起来但是文件系统被内核强制挂载成只读read-only所有写操作都失败这种多半是文件系统内部出现了不一致内核出于保护机制自动降级第三种是系统能正常读写但偶尔出现文件损坏、目录丢失、权限错乱之类的问题这种属于“亚健康”状态还没到崩盘的地步但已经在提醒你该检查了。这里有一条铁律在修复完成之前绝对不要对这个分区做任何写入操作。尤其不能尝试直接挂载后往里面复制文件这相当于在一个地基已经裂了的房子上继续施工只会让问题更严重。如果系统还能启动只是只读挂载那就赶紧把重要数据先复制出来然后再进入修复流程。2.2 为什么必须在Linux PC上操作修复EXT4文件系统的标准工具是e2fsck它要求被检查的文件系统必须处于未挂载状态。你想想Jetson设备自己已经起不来了怎么可能在它上面卸载rootfs所以常规操作是把SD卡从Jetson上取下来通过读卡器插到一台Linux PC上进行修复。对于使用eMMC或NVMe的Jetson设备比如Xavier NX模组、AGX Orin就稍微麻烦一点。eMMC没法直接拔下来需要通过USB线把Jetson连接到PC进入恢复模式按住Recovery键再上电然后用jetson-recovery工具或者dd命令直接读写板载存储。NVMe SSD则可以通过M.2转USB的硬盘盒读取。不管哪种方式思路都一样让文件系统处于离线状态然后在另一台机器上对它做检查和修复。Linux PC的环境要求很简单一个跑Ubuntu的台式机或虚拟机即可。如果你的PC就是Windows也没关系装个Ubuntu虚拟机把USB读卡器透传给虚拟机一样能操作。但要注意虚拟机里USB设备识别可能会有延迟多试几次确认lsblk能看到SD卡再动手。2.3 动手之前先想清楚数据要不要救我自己的习惯是在跑任何修复命令之前先把整张SD卡做一个镜像备份。这不是胆小是真的吃过亏。有一次我在一台Jetson Nano上直接跑e2fsck自动修复工具把一堆看起来“错误”的目录项直接删了后来发现其中有我之前调试好的模型配置丢了再也找不回来。做备份的命令很简单sudo dd if/dev/sdb of~/jetson-sd-backup.img bs4M statusprogress这里sdb是你SD卡对应的设备节点注意是整卡设备而不是分区节点。bs4M设置一次读写的块大小提高吞吐速度。SD卡容量越大这个操作耗时越长32GB的卡大概十几分钟256GB的卡可能要等一个多小时。但这十几分钟换来的是一份“后悔药”万一修复命令把数据搞坏你还可以从镜像里捞回文件。如果空间不够做全卡镜像退而求其次至少用testdisk或者dd单独备份rootfs分区的关键目录比如/home、/etc、/opt。但我的建议还是全卡镜像因为这个代价和丢失数据的代价相比实在太划算了。3. 核心修复过程从备份superblock回滚到文件系统一致性恢复3.1 定位备份superblock的位置前面说过EXT4创建时会存放多份superblock备份。第一个任务就是找到这些备份到底在哪个块。有两种方法第一种是用dumpe2fs查看sudo dumpe2fs /dev/sdb1 | grep -i superblock输出里会有一行Superblock backups stored on blocks:后面列出的数字就是备份superblock所在的块号。第二种方法更加通用用mke2fs -n命令。注意-n参数的意思是“只显示参数不真正创建文件系统”所以即使这个分区已经是EXT4了也能安全地打印出信息sudo mke2fs -n /dev/sdb1 mke2fs 1.46.5 (30-Dec-2021) /dev/sdb1 contains a ext4 file system last mounted on ... Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, ...以最常见的4K块大小为例第一个备份superblock通常在块32768的位置。如果你的文件系统是1K块大小那第一个备份位置是8193。这个数字就跟备用钥匙一样接下来修复时要用到。3.2 用e2fsck指定备份superblock定位到备份位置后就可以开始修复了。首先确保分区没有被挂载sudo umount /dev/sdb1然后执行sudo e2fsck -b 32768 -y /dev/sdb1这里解释一下参数的含义。-b superblock告诉e2fsck用指定的块号作为superblock源而不是默认的块0位置。当主superblock损坏时如果直接运行e2fsck它会报Bad magic number in super-block然后拒绝继续一旦指定了备份位置e2fsck就能读取到合法的文件系统参数从而开始后面的检查修复流程。-y参数表示对过程中所有问题自动回答“yes”避免修复到一半卡在一个交互式确认上。如果担心误操作可以先用-n参数跑一次“彩排”只打印会做什么不真正修改。如果第一个备份位置报错或者检查结果异常就换下一个备份块试试sudo e2fsck -b 98304 -y /dev/sdb1从实测经验看32768这个备份块在很多Jetson官方镜像上都能直接恢复。跑完第一遍修复后我强烈建议再执行一次不带-b参数的完整检查sudo e2fsck -f -y /dev/sdb1这时主superblock已经被重新写回e2fsck会从第0块开始重新读一遍文件系统元数据把残留的inode、块位图问题彻底清干净。3.3 e2fsck输出解析inode、目录项与“孤儿文件”修复过程中会看到一连串Pass信息这些信息不是无意义的刷屏而是e2fsck在按阶段遍历文件系统Pass 1: Checking inodes, blocks, and sizes——检查所有inode是否合法对应的数据块是否有冲突文件大小是否和位图一致。这个阶段最常见的错误是某个inode引用了已经被标记为空闲的块或者两个inode指向同一个块。Pass 2: Checking directory structure——遍历目录项检查目录里的文件名对应的inode是否存在、有没有循环引用。常见的修复结果是删掉一些失效的目录项。Pass 3: Checking directory connectivity——检查目录树是否连通确保所有目录都能从根目录到达。那些已经与主目录树断开的目录会被移动到lostfound。Pass 4: Checking reference counts——检查每个inode的链接计数是否正确。比如一个文件在目录里出现了两次引用计数却只有1这里会修正。Pass 5: Checking group summary information——最后校验块组信息也就是重新统计每个块组的空闲块、空闲inode数修复位图和superblock中的不一致。如果某些文件在被修复前已经损坏到无法恢复e2fsck会把它们放到lostfound目录里。这个名字听起来像垃圾场但其实是“失物招领处”——文件内容还在原来的数据块里只是目录项丢失了。修复完成后可以去/mnt/jetson-root/lostfound翻一翻说不定能找到你想抢救的东西。顺带说一句e2fsck还会检查和修复文件权限位。有些朋友遇到过“文件明明是自己的却提示没有权限”的情况这在异常断电后很常见——inode里的权限字段因为元数据不一致被改乱了。修复时e2fsck会根据目录项和默认umask做一定程度的纠正这也是热词里“文件权限修复”在文件系统层面的实际含义。3.4 修复之后的第一次启动修复完成后不要直接把SD卡插回Jetson就上电。先在PC上挂载一下看看文件系统能不能正常读取sudo mkdir -p /mnt/jetson-root sudo mount /dev/sdb1 /mnt/jetson-root ls /mnt/jetson-root正常情况下应该能看到bin、etc、home、usr、var这些熟悉的目录。如果ls能正常列出基本说明文件系统结构已经恢复了。df -h /mnt/jetson-root可以查看分区挂载信息和剩余空间确认superblock里的容量数据也正确。确认无大碍后先卸载sudo umount /mnt/jetson-root再把SD卡插回Jetson设备上电启动。这里要提醒一点如果修复过程中有大量文件被改动第一次启动可能会比平时慢一些因为系统要做一次完整的磁盘检查或者重建部分缓存这属于正常现象。启动完成后在终端里执行dmesg | grep ext4 df -h sudo touch /test-write sudo rm /test-writedmesg看内核有没有继续报EXT4错误df确认rootfs挂载正常touch一个临时文件再删除则是快速验证读写是否正常。如果这三项都通过恭喜你系统算是救回来了。4. 修复实战中踩过的坑与排查技巧4.1 e2fsck常见错误提示与应对速查修复过程中会碰到各种报错我把实际遇到的几个典型错误整理成了表格方便你对照排查错误提示含义应对方案Bad magic number in super-block主superblock损坏无法解析使用-b参数指定备份superblockAttempt to read block from filesystem resulted in short read读取数据块时发生I/O错误通常是硬件坏道先检查硬件用e2fsck -c扫描坏块严重时更换存储介质Superblock last mount time is in the future系统时钟异常导致的时间戳不一致用hwclock --hctosys校准时间再重新运行e2fsckInodes that were part of a corrupted orphan linked list found存在孤儿inode通常是中断操作残留让e2fsck自动处理文件会移到lostfoundThe filesystem size (according to the superblock) is X blockssuperblock记录的容量与实际分区大小不一致确认分区表没变再考虑用备份superblock重建其中Attempt to read block... short read这条要特别留意。这类错误往往不是元数据逻辑问题而是存储介质的物理问题——SD卡某个区域已经坏掉了读都读不出来。遇到这种情况光跑e2fsck是治标不治本的后面必须要做坏道检测和硬件评估。4.2 文件系统坏了还是硬件坏了判断“软件问题”还是“硬件问题”是修复中最容易翻车的一个点。我的判断套路是三步走。第一步看报错里有没有硬件层面的关键词。用dmesg查一下内核日志如果出现I/O error、Buffer I/O error、mmc0: error -110这类信息大概率是硬件读写失败而不是纯文件系统逻辑错误。第二步修复完成后观察是否“反复坏”。如果这次修好跑几天又崩了而且每次崩的报错都差不多那基本可以断定是存储介质本身的问题。文件系统逻辑错误修一次就能稳很久硬件问题则是修了还会复发。Jetson Nano的SD卡槽接触不良、AGX Orin的NVMe SSD过热掉盘都是典型的“反复坏”场景。第三步做一次主动扫描。用e2fsck -c可以在检查过程中扫描坏块把发现的坏块加入坏块表文件系统后续就不会再去使用这些区域。这个方法对应了热词里“通过文件系统来屏蔽坏道的方法”对小面积坏道确实有效。但如果扫描出来坏块数量很多或者同一个位置反复出现就别硬撑了换一张全新的工业级SD卡或者换固态盘成本远比数据丢失的代价低。4.3 当修复无法挽救时官方镜像重刷与数据保留如果备份superblock也读不出来或者e2fsck跑到一定阶段报错说Cant repair那就说明文件系统损伤已经超出了工具能处理的范围。这时候最理性的选择是放弃修复直接重刷官方镜像。重刷的流程不复杂Jetson Nano等SD卡启动的设备用balenaEtcher把官方镜像重新写入SD卡即可带eMMC的Xavier NX模组则需要进入恢复模式用SDK Manager或者jetson-recovery工具重烧。重刷之后系统就是全新的代价是板载存储上的所有数据都会清空。但重刷不代表数据完全没救。如果你之前做了整卡镜像备份就是第2章说的dd可以用testdisk从镜像里恢复分区和数据文件。如果没有备份也可以把旧SD卡接到Linux PC上用photorec之类的工具按文件签名扫描未分配空间尝试捞回一些图片、文本文件。这些工具的效率取决于碎片程度运气好的话能救回大部分文件但不要抱太大期望。所以核心建议还是那句话重要的数据和模型一定要有多份备份。4.4 预防体系从被动修复到主动防御踩过几次坑之后现在我对待Jetson设备的态度已经变成了“预防优于修复”。几个习惯分享一下。第一尽量避免硬断电。给设备接一个带开关的插座需要关机时先执行sudo shutdown -h now等指示灯彻底熄灭再断电。这个习惯能规避掉绝大多数superblock损坏的风险尤其是那些跑在环境不稳定现场的设备。第二周期性执行sync。sync命令的作用是把内存中缓存的数据强制写回磁盘。虽然不能替代正常关机但在一些需要临时拔卡、移动设备的场景下先sync一下会安全很多。服务类的任务里也可以在关键代码的写文件逻辑后调用sync()系统调用把重要的配置文件及时落盘。第三定期做全卡镜像。不用太频繁每次比较大的系统配置调整、模型调试完成之后做一次就行。比如在Jetson上部署完YOLOv5的整套环境后把整张SD卡做一个镜像存到PC或NAS上。一旦后续文件系统出问题直接用dd把镜像写回一张新SD卡几分钟就能恢复一个可用的系统。第四如果条件允许给设备配一个不间断电源UPS或者稳压电源。Jetson Orin这类高功耗设备的供电波动更容易引发存储写入异常稳定的输入电压本身就能减少很多麻烦。最后再分享一个实用小技巧根据我个人的修复经验e2fsck -b 32768 -y很多时候能一把就解决问题但修复完成不代表万事大吉。我习惯在修复并成功启动系统之后马上再执行一次sudo e2fsck -f -y /dev/mmcblk0p1或者对整盘做一次badblocks扫描确认没有隐藏的坏道。这样做虽然多花几分钟时间但能帮助判断这次损坏是偶发的还是硬件已经亮起了红灯。如果扫描结果不理想趁着系统刚恢复还能导出数据赶紧做备份、换存储介质绝对比等到第二次崩溃再手忙脚乱要舒服得多。