T113 NAND Flash UBIFS根文件系统扩容实战:从分区表到打包脚本的完整调优
1. 从硬件升级到软件适配一次完整的根目录扩容之旅最近在折腾一块基于全志T113的开发板原厂板载的SPI NAND Flash是1Gbit的容量有点捉襟见肘。项目需要存储更多日志和用户数据于是我就把Flash芯片换成了同系列但容量翻倍的2Gbit型号也就是MT29F2G01ABAGDWB。硬件升级听起来简单但要让系统真正“认识”并使用这多出来的128MB空间可就不是插拔芯片那么简单了。这背后涉及到从底层分区表到上层文件系统构建的一整套调整特别是对于使用UBIFS这种直接管理裸NAND闪存的文件系统来说任何一个参数对不上新增的空间就只是个“摆设”。这篇文章我就把自己从踩坑到成功的完整调优过程记录下来目标就是让你也能轻松搞定T113平台NAND Flash的根目录扩容。这次实战的核心逻辑很清晰第一步告诉系统“地盘变大了”这需要修改分区表重新划分存储空间第二步告诉文件系统“新地盘怎么用”这需要调整UBI镜像的打包参数确保生成的根文件系统镜像能填满新划分的区域。听起来只有两步但每一步里都有不少细节和容易掉进去的坑。我会把每一步的原理、操作和验证方法都掰开揉碎了讲即使你之前没怎么接触过UBIFS跟着做下来也能理解个七七八八。2. 理解扩容的底层逻辑为什么不能只改分区表在开始动手之前我们得先搞清楚这次扩容到底要改什么以及为什么。很多朋友第一次做类似操作时会有一个天真的想法我换了更大容量的Flash然后在分区表里把根文件系统分区调大不就行了吗如果你用的是eMMC或者带有FTL闪存转换层的存储设备这个想法可能行得通。但对于我们这里用的SPI NAND Flash情况就完全不同了。NAND Flash是一种“裸”闪存它没有内置的智能管理单元。操作系统或文件系统需要直接面对它的物理特性比如数据必须以“页”为单位读写必须以“块”为单位擦除而且还有坏块需要避开。UBIFSUnsorted Block Image File System就是为这种裸NAND设计的文件系统但它不是直接工作在Flash上而是工作在UBIUnsorted Block Images卷之上。UBI相当于一个中间层它负责磨损均衡、坏块管理和逻辑到物理地址的映射。这就引出了两个关键修改点分区表 (sys_partition.fex)这个文件定义了Flash物理空间上的划分。它告诉烧录工具“从第X个扇区到第Y个扇区这块地皮划给根文件系统用。” 修改这里相当于在“土地证”上扩大了根文件系统的合法用地面积。打包脚本 (mkcmd.sh或相关脚本)在系统编译构建时我们需要预先制作一个根文件系统的UBI镜像通常是rootfs.ubifs。制作这个镜像时必须明确指定这个镜像文件系统“预期”能占用多少空间这个预期值是通过逻辑擦除块LEB的数量来定义的。如果你只在分区表里扩大了“地皮”但制作镜像时却告诉它“你只需要原来那么大的房子”那么最终烧录进去的文件系统其可用空间仍然只有原来那么大多余的地皮就荒废了。所以扩容是“声明地盘”和“建造房屋”必须同步匹配的过程。只改前者系统不认只改后者无处安放。接下来我们就进入实战环节。2.1 硬件变更确认与开发环境准备动手改代码之前先确保你的硬件和软件基础是牢靠的。我使用的硬件是“小智”品牌的T113开发板软件是全志原厂的Tina5.0 SDK基于Buildroot具体版本是v1.2。你的开发环境可能有所不同但核心路径和概念是相通的。首先确认你的新Flash芯片已经被系统正确识别。在Linux系统启动后可以通过dmesg | grep -i nand或者cat /proc/mtd命令来查看MTD内存技术设备信息。你应该能看到代表整个NAND Flash的MTD设备以及其总容量是否正确例如2Gbit应该是256MB。这一步是基础如果这里识别的大小就不对那后面的所有修改都可能白费。接着找到你的SDK工程目录。后续的所有修改都在这个目录下进行。关键的文件路径有两个你需要记下来分区表文件路径你的SDK根目录/device/config/chips/t113/configs/你的板子型号/buildroot/sys_partition.fex打包脚本路径通常在你的SDK根目录/build/目录下可能叫mkcmd.sh或类似的脚本它的作用是调用mkfs.ubifs和ubinize等工具来生成最终的UBI镜像。建议在修改前先备份这两个原始文件。这样万一操作失误可以快速回滚。3. 第一步修改分区表重新规划Flash地盘分区表文件sys_partition.fex是一个文本格式的配置文件结构清晰。它定义了Flash上各个分区如boot、rootfs、UDISK等的起始位置、大小和属性。我们的目标是把原本属于UDISK用户数据存储区的一部分空间挪给ubi0_5分区通常就是我们的根文件系统分区。打开这个文件你会看到类似下面的内容格式和分区名可能因板而异[partition] name boot size 2048 ... [partition] name ubi0_5 size 147436 ... [partition] name UDISK size 237568 ...这里有几个关键点需要理解name分区的名称。size分区的大小单位是扇区Sector而一个扇区固定为512字节。这是最容易算错的地方分区的顺序很重要它们通常是连续排列的一个分区的结束就是下一个分区的开始。所以调整一个分区的大小往往会影响到后续分区的起始地址。不过好在全志的打包工具通常会根据size自动计算偏移我们一般只需要关心要修改的分区大小即可。在我的案例中原计划是将UDISK的116MB空间划给ubi0_5。那么计算过程如下116MB需要换算成扇区数116 * 1024 (KB) * 1024 (Byte) / 512 (Byte/Sector) 237568个扇区。查看原ubi0_5分区的size值假设是147436。新的ubi0_5分区大小 原大小 新增大小 147436 237568 385004。相应地UDISK分区的size值需要减去这237568个扇区。修改后的分区表示例[partition] name ubi0_5 size 385004 ... [partition] name UDISK size 0 ; 或者是一个减小后的值如果UDISK不完全取消的话 ...注意这里有个坑。如果你把UDISK的size改成了0意味着你完全取消了用户存储分区所有空间都给了根文件系统。这在实际产品中是否合适需要根据你的应用场景来决定。有时候我们可能只想划一部分过来那么UDISK的size就应该是一个大于0的值。同时要确保Flash的总容量足够容纳所有分区大小之和不能超限。3.2 分区表修改的潜在影响与检查修改分区表后并不意味着就万事大吉了。这里有几个必须检查的点分区对齐为了提高NAND的读写效率分区的起始地址和大小最好与擦除块Erase Block边界对齐。虽然全志的工具链可能会做一定处理但自己心里要有数。你可以用ubinfo -a查看当前系统的擦除块大小PEB size然后确保你计算出的扇区数换算成字节后是PEB大小的整数倍。启动相关分区boot分区通常存放uboot和内核千万不要去动它的size除非你非常清楚你在做什么。修改它的边界可能导致系统无法启动。备份与验证改完分区表在编译之前建议用文本对比工具如diff仔细核对修改处确保没有多删或少字符特别是分号注释和等号两侧的空格有时格式错误会导致解析失败。完成分区表修改我们只是完成了“土地规划”的图纸更新。接下来我们要根据新图纸来“盖房子”。4. 第二步修改打包脚本让UBIFS镜像填满新空间这是整个扩容过程中最核心、也最容易遗漏的一步。正如开头所说分区表定义了物理空间而打包脚本决定了文件系统镜像的逻辑空间。我们找到SDK中的打包脚本它可能是build/mkcmd.sh也可能是其他位置调用mkfs.ubifs和ubinize命令的脚本。我们需要搜索其中为ubi0_5或rootfs制作UBIFS镜像的命令行。关键是要找到mkfs.ubifs这个命令它用于创建一个UBIFS镜像文件。这个命令有一个至关重要的参数-c或--max-leb-cnt。这个参数指定了该UBIFS镜像所能使用的最大逻辑擦除块LEB数量。这个值直接限制了镜像文件系统的最大容量。举个例子假设之前你的-c参数是375而你的LEB大小是258048字节这个值可以通过在目标板上运行ubinfo -a获得后面会讲。那么之前根文件系统镜像的最大容量就是 375 LEB * 258048 Bytes/LEB ≈ 92.4 MB即使你在分区表里给ubi0_5分配了253MB如果这里的-c还是375那么最终烧进去的文件系统最大也只能用到92.4MB剩下的160MB空间永远无法被访问到。这就是为什么只改分区表没用的原因。那么新的-c参数应该怎么计算呢获取目标LEB大小最准确的方法是在一个能正常启动的系统上可以是旧镜像运行ubinfo -a命令。在输出信息中寻找Logical eraseblock size这一项记下这个值。例如我这里是258048字节。注意这个值不是NAND的物理擦除块大小而是UBI层提供的逻辑擦除块大小它通常比物理块小一点因为要存放一些元数据。计算所需LEB数量用你为ubi0_5分区新分配的总字节数除以LEB大小。新分区扇区数385004 来自分区表修改总字节数 385004 * 512 197,122,048 字节所需LEB数 197,122,048 / 258048 ≈ 763.89确定-c参数值-c参数必须是一个整数。我们不能取整为763因为那样会有部分空间用不上。通常的做法是向上取整并留有一点余量以应对UBI自身的元数据开销和坏块预留。我会取一个稍大一点的整十或整百数比如770或780。留有余量是安全的mkfs.ubifs只是设定一个上限实际镜像大小取决于你放入的根文件系统内容。所以我将-c参数从原来的375改为770。找到打包脚本中类似下面的代码段并进行修改# 修改前可能是这样的 mkfs.ubifs -x lzo -m 2048 -e 258048 -c 375 -d ${ROOTFS_DIR} -o rootfs.ubifs # 修改后 mkfs.ubifs -x lzo -m 2048 -e 258048 -c 770 -d ${ROOTFS_DIR} -o rootfs.ubifs参数解释-x lzo: 指定使用LZO压缩。-m 2048: 最小I/O单元大小通常为NAND的页大小Page Size例如2KB。-e 258048: 逻辑擦除块大小必须与ubinfo -a查到的值一致。-c 770: 这就是我们刚计算并调整的最大LEB数量。-d ${ROOTFS_DIR}: 输入目录即构建好的根文件系统内容。-o rootfs.ubifs: 输出的UBIFS镜像文件。4.2 深入理解打包参数与避坑指南修改-c参数看似简单但背后有几个深坑需要注意第一坑-e参数不匹配。这个值必须严格与运行系统中UBI设备报告的LEB大小一致。如果你不确定一个稳妥的方法是先编译一个旧配置的固件烧录进去在系统启动后通过ubinfo -a查询。切勿直接使用NAND芯片手册上的物理擦除块大小比如128KiB它们通常不是同一个值。第二坑忘记修改ubinize.cfg配置文件。mkfs.ubifs生成的是纯UBIFS镜像还需要通过ubinize工具将其封装成UBI镜像这个过程中会用到ubinize.cfg配置文件。在这个文件里同样需要为对应的卷volume指定大小。这个大小应该与你分区表计算出的分区大小匹配或略小因为要扣除UBI元数据占用的PEB。例如[ubi0_5] modeubi imagerootfs.ubifs vol_id5 vol_size197MiB # 这里应等于或接近 385004*512 字节 vol_typedynamic vol_namerootfs vol_flagsautoresize注意vol_flagsautoresize这个选项非常有用。如果设置了它卷会自动占满分区中所有可用的空间。这样即使你这里vol_size设得稍微小一点但必须大于等于mkfs.ubifs镜像的实际容量系统启动后卷也会自动调整到分区最大容量。这为我们提供了一定的容错空间。第三坑编译清理不彻底。修改了分区表和打包脚本后必须进行完整的重新编译。建议使用./build.sh clean清理一下然后再执行./build.sh。因为打包过程可能依赖于中间文件不彻底清理可能导致旧的参数被复用。5. 编译、烧录与验证检验成果的三部曲所有的修改都完成后就到了检验成果的时候。这个过程需要耐心因为编译一次完整的Buildroot系统可能需要较长时间。完整编译在SDK根目录下执行./build.sh。确保编译过程没有报错。编译成功后最终的固件镜像通常是一个.img文件会出现在out/目录下。烧录固件使用全志专用的烧录工具如PhoenixSuit或Allwinner的烧录软件将新编译的.img文件烧录到开发板的NAND Flash中。烧录前请确认备份了重要数据因为这会擦除整个Flash。上电验证这是最激动人心的环节。系统启动后我们需要通过一系列命令来验证扩容是否真正成功。查看MTD分区信息cat /proc/mtd。这里可以看到各个MTD分区的名称、大小和偏移量。找到你的根文件系统分区可能是ubi0_5对应的MTD设备如mtd5检查其size字段是否已经变成了我们预期的值约197MB。查看UBI卷信息ubinfo -a。这个命令会详细列出UBI设备上的所有卷。找到名为rootfs或对应的卷查看其Size。这里显示的是卷的逻辑大小它应该非常接近我们计算出的分区大小例如197MB。如果这里的大小还是原来的90多MB那说明打包脚本的-c参数修改可能未生效或者ubinize.cfg配置有误。查看文件系统挂载和使用情况df -h。这个命令大家最熟悉。查看根目录/的挂载点其Size和Available应该显著增大了。这是最直观的证明。实际写入测试光看不够还得试试能不能用。可以尝试在根目录下创建一个超大文件dd if/dev/zero of/test.big bs1M count150。尝试写入150MB的数据。如果空间足够这个命令会成功执行如果扩容不成功可能在写入几十MB后就会报“设备无剩余空间”的错误。在我自己的验证过程中df -h显示根目录从原来的90多MB变成了190多MB成功写入了150MB的大文件这证明扩容完全成功。至于原文中提到的UDISK分区还剩一点空间的问题这很可能是因为分区表计算时分区大小之和没有完全占满整个Flash的物理容量或者为了对齐擦除块边界而故意留出的一点冗余空间只要不影响主要目标可以不必深究。6. 常见问题排查与进阶思考即使按照步骤操作你也可能会遇到一些问题。这里我总结几个常见的排查方向系统无法启动首先检查串口日志看卡在哪个阶段。如果uboot能启动但内核挂载rootfs失败很可能是分区表修改导致rootfs的起始位置偏移计算错误或者新的UBI镜像格式不被内核识别。重点核对分区表修改后是否影响了其他关键分区如boot的偏移。根目录大小未变这是最典型的问题。请按以下顺序检查确认df -h看到的确实是UBIFS文件系统类型显示为ubifs。核对ubinfo -a输出的卷大小是否正确。如果卷大小不对回溯检查打包脚本中mkfs.ubifs的-c参数是否正确以及ubinize.cfg中对应卷的vol_size或vol_flags设置。确认是否执行了完整的./build.sh clean和./build.sh。文件系统只读或出错如果扩容后文件系统变成只读或者在写入时出错可能是UBIFS的内部参数如-m最小I/O大小与NAND物理参数不匹配或者Flash本身存在坏块问题。可以尝试用ubinfo -a和芯片手册对比参数或者使用flash_erase工具对分区进行擦除后再重新烧录需谨慎会丢失数据。进阶思考这次扩容我们采用的是“静态”调整分区表的方式。在产品化部署中如果希望根文件系统能动态适应不同容量的Flash比如同时支持1Gbit和2Gbit的版本可以考虑更灵活的方法。例如可以让uboot在启动时检测Flash的ID和容量然后动态修改传递给内核的MTD分区信息或者利用UBIFS的autoresize特性在ubinize.cfg中不指定固定vol_size让文件系统在第一次挂载时自动占满整个MTD分区。这些方法实现起来更复杂但灵活性和通用性更强。折腾硬件底层和文件系统就像是在给设备做“内科手术”每一步都需要谨慎和清晰的理解。这次T113的NAND Flash扩容从硬件更换到分区表调整再到UBI打包参数的适配走完整个流程不仅解决了存储空间的问题更让我对UBIFS在裸NAND上的工作方式有了更深的认识。遇到问题别怕多查日志、多验证、一步步回溯总能找到原因。希望这份详细的记录能帮你绕过我踩过的那些坑顺利拿下扩容任务。

相关新闻

FFmpeg缓冲区优化指南:AVIOContext的buffer_size设置到底多少才合理?

FFmpeg缓冲区优化指南:AVIOContext的buffer_size设置到底多少才合理?

FFmpeg缓冲区优化指南:AVIOContext的buffer_size设置到底多少才合理? 最近在调试一个直播拉流项目时,遇到了一个让人头疼的问题:播放器在弱网环境下频繁卡顿,但网络带宽监测显示带宽是足够的。排查了半天,最…

2026/5/17 12:33:23 阅读更多 →
SpringBoot项目实战:JUnit5单元测试从入门到精通(附完整代码示例)

SpringBoot项目实战:JUnit5单元测试从入门到精通(附完整代码示例)

SpringBoot项目实战:JUnit5单元测试从入门到精通(附完整代码示例) 如果你已经用SpringBoot开发过几个项目,可能会发现一个现象:项目初期,业务逻辑清晰,代码跑得飞快;但随着功能迭代&…

2026/7/3 3:21:46 阅读更多 →
OpenClaw 到底是什么?

OpenClaw 到底是什么?

说在前面 🦞 最近刷技术圈的同学应该都被一只"龙虾"刷屏了——OpenClaw,GitHub star 数一路狂飙突破 24 万,超越 React 成为 GitHub 历史上最高星的开源项目 发个消息让它帮你整理文件?行。让它帮你跑个定时脚本监控服务…

2026/5/17 12:33:22 阅读更多 →

最新新闻

符合出口标准的胡萝卜种子如何挑选抗逆品种?2026 种植采购实操指南

符合出口标准的胡萝卜种子如何挑选抗逆品种?2026 种植采购实操指南

很多从事胡萝卜规模化种植,特别是瞄准出口市场的技术负责人和种植户,经常面临一个核心困境:如何在海量的种子品种中,精准筛选出兼具抗逆性、商品性和高产潜力的品种,并构建一套可复制的稳产方案?市面上的营…

2026/7/5 3:04:55 阅读更多 →
大气散射模型 OpenCV 4.8 去雾实战:单张图像 0.5 秒内透射率图估计

大气散射模型 OpenCV 4.8 去雾实战:单张图像 0.5 秒内透射率图估计

基于暗通道先验的实时去雾算法:OpenCV 4.8 工程实现详解清晨的浓雾常常让摄影作品失去应有的色彩与细节,而计算机视觉领域的去雾算法正是解决这一问题的利器。本文将带您深入浅出地实现一个基于暗通道先验的高效去雾系统,仅用不到0.5秒即可完…

2026/7/5 3:04:55 阅读更多 →
靠谱的区域教育一体化管理平台哪个排名高

靠谱的区域教育一体化管理平台哪个排名高

在当今信息化时代,教育行业的数字化转型已经成为必然趋势。区域教育一体化管理平台作为提升教育管理水平、优化教育资源配置的重要工具,受到了越来越多教育机构的关注。然而,在众多的教育管理平台中,如何选择一个既可靠又高效的平…

2026/7/5 3:04:55 阅读更多 →
多重共线性实战指南:识别、归因与工程化解法

多重共线性实战指南:识别、归因与工程化解法

1. 项目概述:为什么多重共线性不是“错误”,而是数据在说话你刚跑完一个线性回归模型,R高达0.92,F检验p值小于0.001,一切看起来都很漂亮——直到你扫了一眼系数表:某个自变量的系数是3.7,标准误…

2026/7/5 3:02:54 阅读更多 →
云原生技术28-K8s排障实战:20个常见问题的快速定位与解决,从CrashLoopBackOff到Running的完整指南

云原生技术28-K8s排障实战:20个常见问题的快速定位与解决,从CrashLoopBackOff到Running的完整指南

1、AI程序员系列文章 2、AI面试系列文章 3、AI编程系列文章 目录 排障思维:从"盲人摸象"到"精准定位" 2.1 自上而下 vs 自下而上 2.2 假设验证法 2.3 二分法定位 Pod问题:四大金刚的"病历本" 3.1 CrashLoopBackOff&…

2026/7/5 3:00:53 阅读更多 →
Codex 实战:AI 编程助手接入真实项目,用真实案例讲清边界

Codex 实战:AI 编程助手接入真实项目,用真实案例讲清边界

聊《Codex 实战:AI 编程助手接入真实项目,用真实案例讲清边界》之前,先说一句实在的:别急着背概念,先看它在真实项目里到底解决什么问题。摘要这篇面向想用 AI 提升研发效率的开发者和技术负责人,但不会把“…

2026/7/5 3:00:53 阅读更多 →

日新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻