MT798x 路由器,OpenWrt 的各种固件要怎样选
WN2TRY
2026年06月25日 14:33
收录于文集
共4篇

MediaTek MT798x 路由器的固件种类有点多,初次接触可能一头雾水,本文简介 OpenWrt/ImmortalWrt 各种固件的区别。

路由器的固件一般有两部分,一是 Boot Loader,二是系统。Boot Loader 在 MTK 的设备上又分两部分 BL2 和 FIP (BL31 + U-Boot)。正常启动,Boot ROM 加载 BL2,初始化硬件,BL2 加载 FIP ,然后 u-boot 启动系统。

首先是闪存的分区布局不同。下图是锐捷 X30E Pro 的分区表,列出了原厂布局 stock 和一种 custom 布局。

Custom 固件把原厂固件的后面三个分区合并成一个 ubi 大分区,这样就可以有更多空间供用户使用。custom 的分区表可能不只一种,区别多在于 ubi 的大小。

分区布局在 u-boot 通过环境变量管理。而在系统内核则是通过设备树 DT 指定。

计算一下上图所有分区大小的总和,会发现分区表在 120MB 结束,末尾的 8MB 没有分配。为什么末尾空间不分给系统使用?原因在于 NAND 闪存的坏块管理。

NAND 闪存使用中出现坏块不可避免。MTK 的坏块管理方案叫 NMBM ,它在闪存尾部预留空间用作坏块映射,它把数据映射到尾部的健康块,避免写入坏块。NMBM 相对位于驱动底层,对系统透明。

Stock 和 custom 固件大都会用 MTK 的 u-boot。而 MTK 的 BL2 和 u-boot 一般默认开启 NMBM,在设备启动时扫描闪存,建立坏块映射。而要在系统内继续使用 NMBM,把坏块映射传递给系统,内核也需要开启 NMBM 。

OpenWrt 原生系统内核开启 NMBM,要在设备树 DT 的 spi-nand 节点处添加 mediatek,nmbm 等相关属性。


对于 SPI-NAND 闪存,OpenWrt 默认使用 UBIFS 文件系统。它的 UBI 子系统本身就有坏块管理,而且支持磨损均衡,比 NMBM 更加完善。但由于 NMBM 对 UBI 透明,在内核开启 NMBM 的情况下,UBI 实际无法获取物理坏块信息,磨损均衡也不起作用。再加上 NMBM 和 UBI 都需要预留空间,两者都启用会有空间浪费。所以 OpenWrt 主线倾向于完全关闭 NMBM,直接使用 UBI 的坏块管理。

除了在内核关闭 NMBM 外,还需要编译 BL2 和 FIP (u-boot),同样关闭 NMBM。这种完全禁用 NMBM 的固件,被称为 OpenWrt U-Boot Layout (ubootmod)。

ubootmod 固件除了关闭 NMBM,还有其他特点:

  • ubi 分区可能占满闪存剩余空间

  • u-boot 环境变量被放到了 ubi 卷(ubootenv + ubootenv2)内

  • kernel、dtb、rootfs 被打包为 FIT 格式的镜像,同样放到 ubi 卷(fit)内

  • 可能会有一个 recovery 卷,保存 initramfs

  • 可能改变原厂分区布局

下图是给 X30E Pro 模拟的 custom layout 和 ubootmod layout 的分区结构区别,两者都保留了前面部分的原厂数据

UBI 的保留空间是动态管理,分散在整个分区内,所以 ubootmod 固件可以把所有的剩余空间都分给系统使用。网上不建议开启 NMBM 的 u-boot 使用 ubootmod 固件,原因大概就在于这样分区会破坏 NMBM 在尾部的保留空间。不过并非 MTK 的 u-boot 就不能使用 ubootmod 固件,比较新的 u-boot 已经支持加载 FIT 镜像,修改编译参数就能适配 ubootmod 固件。

对于 NMBM 跟 UBI 共存的固件(stock/custom layout),有一种改进做法是在 DT 里使用 mediatek,bmt-remap-range 属性来限制 NMBM 的扫描范围,尽可能把 ubi 分区的数据排除在外。不过使用这种方法最好不要把 kernel 排除在外。

ubootmod 有一种变体,它更进一步,把 FIP (BL31 + U-Boot) 和其他重要数据(EEPROM、MAC)都放到 ubi 分区内作为 ubi 卷存在,这样除了 BL2 之外的数据都在 UBI 坏块管理保护之下,这种 all-in-ubi 的布局叫做 OpenWrt UBI Layout。不过因为这几个 ubi 卷需要手动创建,稍有点麻烦,所以比较少见。

关闭 NMBM 并不是说 ubi 之外的分区就没有坏块管理了,其实还有 skip-bad 机制保底,发现坏块作出标记并把数据写入下一个健康块。ubootmod 固件把 u-boot 环境变量放到 ubi 卷内,ubi 分区之外的只读数据依赖 skip-bad 。不过 skip-bad 无法预防读取干扰等非写入问题导致的坏块,所以相对完美的办法还是用前述 all-in-ubi layout。


综上所述,NMBM 跟 UBI 坏块管理重复,多占了空间,也不能提供更好的保护,还是禁用为佳。

ubootmod 不一定非要用 OpenWrt 编译的原生 u-boot。网页恢复界面比 TFTP 要好用很多,所以最佳选择还是自己编译 MTK 的 u-boot,关闭 NMBM、调整编译参数适配 ubootmod 固件的特性。另外 BL2 也需要对应调整。

MTK u-boot 开启网页恢复界面,从外部加载 initramfs 会很容易,完全不需要再保留 recovery 卷。

MTK 的 BL2 和 u-boot 可以使用下面两个仓库的源码编译,推荐后者,功能多、更新快、支持更全面:

对于 OpenWrt 固件的打包类型,新版的 u-boot 会自动适应,用户不用关心它是 fit 还是 tar。 具体关于打包格式的区别,会在后续文章里介绍。


ubootmod 固件刷机注意:

  • 建议刷入系统镜像前先创建 ubootenv/ubootenv2 这两个 ubi 卷用来保存 u-boot 环境变量。

  • 这两个卷其实不用手动创建,u-boot 如果检测不到会自动创建,但前提是 ubi 分区还有足够剩余空间。

  • 所以如果这两个卷以前没有,建议在刷入 ubootmod 固件之前,执行 ubi detachmtd erase ubi 这两个命令清空 ubi 分区的数据。命令可以在 u-boot 控制台执行,也可以在 initramfs 里执行。执行之后重启,u-boot 会自动创建 ubootenv 和 ubootenv2 卷。

  • 关闭 NMBM 前 备份一次闪存的数据,因为如果有坏块的话,关闭 NMBM 之后读取的会是错误数据。

#openwrt#​#immortalwrt#​#mt7981#​#mt7986#​#ubootmod#​#mtk-u-boot#​#NMBM#​#UBIFS#​#X30e-pro#​#锐捷黑豹#​#路由器刷机#​