找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2873

积分

0

好友

407

主题
发表于 昨天 04:55 | 查看: 0| 回复: 0

相对于第一版,本指南在以下几个方面进行了重要更新:

  1. 添加“支持的路由器型号”的查询链接:方便您快速确认自己的设备是否适配。
  2. 增加 Web failsafe 下“环境变量编辑”的功能介绍:让您能更灵活地调整启动参数。
  3. *uboot 2025版默认支持刷 `.itb` 固件**:因此本版去掉了关于打补丁支持FIT格式固件的说明。
  4. 明确“多闪存布局选择”与“环境变量设定布局”的优先级:第一版未说明,当两种模式并存时,通过 mtdparts 环境变量设定的布局优先级更高,手动选择的布局将失效,本版已增加此说明。
  5. 项目已适配 h3c_magic-nx30-pro:uboot 2025版已增加对该机型的官方支持,故本版去掉了手动添加 h3c_magic-nx30-pro_defconfig 文件的步骤。
  6. 更新关于 NMBM 的风险说明:更清晰地阐述了刷入启用与未启用 NMBM 固件可能带来的影响。

什么样的 uboot 才算“刷机友好”?它通常具备以下特性:

  1. 易于进入刷机模式:例如,在路由器启动时长按 reset 键,就能通过浏览器访问刷机界面。
  2. 刷机界面功能丰富
    • 支持备份与恢复:可以备份整个闪存或指定分区。完整备份用于灾难恢复;备份 MAC、无线校准等关键分区,则能在刷机后快速还原设备信息。
    • 支持刷写引导程序与固件:这是最核心的刷机操作。
    • 支持加载并运行 initramfs 系统:当刷机界面无法完成某些操作时,可以进入在内存中运行的 initramfs 系统来执行更复杂的任务。
    • 支持动态调整闪存布局:大部分使用闪存的路由系统都要求 uboot 与固件内的分区布局一致。通常,刷特定布局的固件就需要配套的 uboot。而一旦刷写 uboot 失败,往往只能通过拆机接 TTL 或使用编程器来修复,难度大增。如果 uboot 自身就提供修改布局的功能,就能在不重刷 uboot 的前提下适配不同固件,显著降低变砖风险。

下面要介绍的这个开源 uboot 项目,就完美满足了上述所有需求。该项目已为大量基于 MTK 联发科 mt798x 芯片的路由器进行了机型适配(适配机型列表可在此查询:https://cmi.hanwckf.top/p/mt798x-uboot-usage/ 或查看项目 uboot 目录下的 configs 文件夹,例如:https://github.com/hanwckf/bl-mt798x/tree/master/uboot-mtk-20250711/configs)。

若想了解哪些 mt798x 路由器支持刷入 OpenWrt 系统,可以参考 OpenWrt 官方源码树:

支持刷 OpenWrt 的 mt798x 路由器:
https://git.openwrt.org/?p=openwrt/openwrt.git;a=tree;f=target/linux/mediatek/dts;hb=HEAD

此 uboot 项目基于 https://github.com/hanwckf/bl-mt798x 进行二次开发,在其 Web 恢复模式(Web failsafe)下提供了更为强大的功能集。

项目地址:

bl-mt798x-dhcpd:
https://github.com/Yuzhii0718/bl-mt798x-dhcpd

接下来,我们将详细介绍如何编译 bl-mt798x-dhcpd、刷写 uboot 以及使用这个 uboot 为路由器刷入系统。

一、编译(以 h3c_magic-nx30-pro 为例)

首先了解一下关键的编译参数:

  • SOC:CPU 型号,例如 mt7981mt7986
  • BOARD:路由器型号,例如 h3c_magic-nx30-pro
  • VERSION:uboot 的版本号,如 202220232025
  • MULTI_LAYOUT:是否启用多种闪存分区布局支持,默认 MULTI_LAYOUT=0(不启用)。
  • FIXED_MTDPARTS:是否忽略 mtdparts 环境变量并固定闪存分区布局,默认 FIXED_MTDPARTS=1(固定)。

一个重要规则:当 FIXED_MTDPARTS=0 时,即使设置了 MULTI_LAYOUT=1,Web failsafe 中的多闪存布局选择功能也将无效。uboot 会优先使用环境变量中的 mtdparts 定义。

若想在 Web failsafe 中通过下拉菜单选择不同的闪存布局,编译时必须使用 FIXED_MTDPARTS=1MULTI_LAYOUT=1。同时,需要修改设备树(.dts)和配置文件。

我们需要修改以下两个文件:

  1. ./bl-mt798x-dhcpd/uboot-mtk-20250711/arch/arm/dts/mt7981-h3c_magic-nx30-pro.dts:在其中定义多个 layout(布局)。
  2. ./bl-mt798x-dhcpd/uboot-mtk-20250711/configs/mt7981_h3c_magic-nx30-pro_multi_layout_defconfig:确保启用多布局配置。

mt7981-h3c_magic-nx30-pro.dts 文件内容示例(关键部分)

// SPDX-License-Identifier: GPL-2.0-or-later OR MIT

/dts-v1/;
#include "mt7981.dtsi"
#include <dt-bindings/gpio/gpio.h>

/ {
    #address-cells = <1>;
    #size-cells = <1>;
    model = "mt7981-h3c_magic-nx30-pro";
    compatible = "mediatek,mt7981", "mediatek,mt7981-rfb";

    chosen {
        stdout-path = &uart0;
        tick-timer = &timer0;
    };

    config {
        bootcmd = "mtkboardboot";
        blink_led = "green:status";
        system_led = "red:status";
    };

    mtd-layout {
        layout@0 {
            label = "default";
            // mtd layout for stock ubi firmware, support immortalwrt/openwrt 64M ubi firmware
            mtdids = "nmbm0=nmbm0";
            mtdparts = "nmbm0:1024k(bl2),512k(u-boot-env),2048k(Factory),2048k(fip),65536k(ubi),6144k(pdt_data),6144k(pdt_data_1),1024k(exp),38400k(plugin)";
        };

        layout@1 {
            label = "expand(112m)";
            // mtd layout for 112m ubi firmware
            mtdids = "nmbm0=nmbm0";
            mtdparts = "nmbm0:1024k(bl2),512k(u-boot-env),2048k(Factory),2048k(fip),114688k(ubi)";
        };

        layout@2 {
            label = "qwrt(110m)";
            // mtd layout for lean qwrt
            mtdids = "nmbm0=nmbm0";
            mtdparts = "nmbm0:1024k(bl2),512k(u-boot-env),2048k(Factory),2048k(fip),1024k(rsv0),110M(ubi)";
        };
    };
    // ... 其余代码(GPIO, LED, 内存, 网络, SPI等配置)保持不变
};

mt7981_h3c_magic-nx30-pro_multi_layout_defconfig 文件内容示例(关键行)

CONFIG_ARM=y
CONFIG_ARCH_MEDIATEK=y
CONFIG_TARGET_MT7981=y
CONFIG_MEDIATEK_BOOTMENU=y
CONFIG_MTK_WEB_FAILSAFE=y
CONFIG_MEDIATEK_MULTI_MTD_LAYOUT=y  # 确保这行存在且为 y
CONFIG_CMD_MTDPARTS=y
# CONFIG_MTDIDS_DEFAULT="nmbm0=nmbm0"  # 被注释掉,使用 DTS 中的定义
# CONFIG_MTDPARTS_DEFAULT="nmbm0:1024k(bl2)..." # 被注释掉,使用 DTS 中的定义
// ... 其余配置

完成文件修改后,即可开始编译。

编译支持在 Web failsafe 下拉菜单选择闪存布局的 uboot
执行此命令后,将生成 mt7981_h3c_magic-nx30-pro_2025-fip-dhcpd-Yuzhii-fixed-parts-multi-layout.bin 文件。

SOC=mt7981 BOARD=h3c_magic-nx30-pro VERSION=2025 MULTI_LAYOUT=1 FIXED_MTDPARTS=1 ./build.sh

编译支持通过 mtdparts 环境变量修改闪存布局的 uboot
执行此命令后,将生成 mt7981_h3c_magic-nx30-pro_2025-fip-dhcpd-Yuzhii.bin 文件(注意:实际文件名中的版本号可能为2025,此处以生成的为准)。

SOC=mt7981 BOARD=h3c_magic-nx30-pro VERSION=2025 MULTI_LAYOUT=0 FIXED_MTDPARTS=0 ./build.sh

二、刷写 uboot(以 h3c_magic-nx30-pro 为例)

刷写 uboot 主要有两种途径:

  1. 通过原机 uboot 刷写:如果原厂或现有的 uboot 提供了刷写引导程序的功能,直接在其中刷入新的 .bin 文件即可。
  2. 通过 SSH 在系统中刷写:如果原 uboot 无此功能,则需要先登录到路由器的操作系统(如 OpenWrt)中进行刷写。

通过系统刷写的步骤如下

1)启用分区写权限
这需要安装并加载一个特殊的内核模块来解除 MTD 分区的写保护。

opkg update
opkg install kmod-mtd-rw
opkg files kmod-mtd-rw
cd /lib/modules/6.6.119 # 请根据实际内核版本号修改目录名
insmod mtd-rw.ko i_want_a_brick=1

加载成功后,终端会显示一系列 mtd-rw: mtdX: setting writeable_flag 的信息。

2)写入新的 uboot 到 FIP 分区
使用 mtd write 命令将编译好的 bin 文件写入引导分区。首先,你需要知道引导分区(通常是 FIP)的名称,可以通过 cat /proc/mtd 查看。

  • 如果你编译的是 支持下拉菜单选择布局 的 uboot,执行:
    mtd write mt7981_h3c_magic-nx30-pro_2025-fip-dhcpd-Yuzhii-fixed-parts-multi-layout.bin FIP
  • 如果你编译的是 支持环境变量修改布局 的 uboot,执行:
    mtd write mt7981_h3c_magic-nx30-pro_2025-fip-dhcpd-Yuzhii.bin FIP

重要提示FIP 是引导程序所在分区的名称,请务必根据 cat /proc/mtd 的输出结果确认你设备上的准确名称。

三、使用新 uboot 为路由器刷入系统

刷机前,请务必备份好闪存中的重要数据(如 Factory 分区)!

1. 确保 uboot 与固件的闪存布局一致
这是成功刷机的关键。你需要确保 uboot 中定义的 ubi 分区大小与你要刷的固件里的 ubi 分区大小完全一致。理想情况下,整个分区表都应一致。

  • 查看固件布局:可以查阅固件源码中的设备树(.dts)文件,或询问固件发布者。例如,ImmortalWrt 24.10 中 h3c_magic-nx30-pro 的 dts 文件位置通常可以在其 GitHub 仓库找到。
  • 调整 uboot 布局:如果布局不一致,你有以下几种调整方式:
    • 使用下拉菜单选择(针对第一种 uboot):在 Web failsafe 界面中,直接在“选择 mtd 布局”下拉框中选取与固件匹配的布局(例如 default, expand(112m))。
    • 修改环境变量(针对第二种 uboot):在 Web failsafe 的“环境”功能页面,找到并修改 mtdparts 变量,将其值设置为与固件匹配的分区表字符串。
    • 在 Initramfs 系统中修改:启动到 Initramfs 系统后,通过 SSH 登录,使用 fw_setenv 命令修改 mtdparts 环境变量。例如,恢复 h3c_magic-nx30-pro 的出厂布局:
      fw_setenv mtdparts 'nmbm0:1024k(bl2),512k(u-boot-env),2048k(Factory),2048k(fip),65536k(ubi),6144k(pdt_data),6144k(pdt_data_1),1024k(exp),38400k(plugin)'

2. 执行刷机
当 uboot 中的 ubi 分区大小与固件要求一致后,就可以开始刷机了。路由器通电时长按 reset 键,进入 Web failsafe 界面(默认地址 http://192.168.1.1),选择固件文件并上传即可。

3. 处理刷机后空间异常问题
如果刷入系统后,发现可用空间(即 ubi 分区内的 rootfs_data 卷)远小于 【ubi分区大小 - kernel卷大小 - rootfs卷大小】 计算出的值,可以先尝试擦除 ubi 分区再重新刷固件。

  • 在 Web failsafe 的“终端”中执行mtd erase ubi
  • 在 Initramfs 系统中通过 SSH 执行mtd erase ubi

执行完毕后,再次刷入 sysupgrade 固件即可。

4. 关于 NMBM(坏块管理)的重要说明
本项目编译的 uboot 默认启用了 NMBM。强烈建议刷入同样启用了 NMBM 的系统固件,以保持上下两层坏块管理数据的一致性。

  • 风险:如果刷入了未启用 NMBM 的固件,当闪存出现新的坏块时,可能会因数据记录不一致导致系统异常。此时,你可能无法再刷回未启用 NMBM 的固件,只能刷启用 NMBM 的固件来修复。当然,如果闪存一直没有任何坏块,混刷在理论上是可行的。
  • 如何判断固件启用了 NMBM:查看固件的 dts 文件,如果包含 mediatek,nmbm; 这一配置项,即表示启用。例如 ImmortalWrt 24.10 的相关 dts 中就有此配置。
  • 核心建议:闪存上的原始数据(如无线校准参数 eeprom)一旦丢失可能无法恢复。因此,刷机前请充分理解操作风险,并做好备份。对于编译和刷机这类可能影响系统底层稳定的操作,细致的前期准备和调试意识至关重要。

希望这份详细的指南能帮助你顺利完成 MT798x 路由器的 uboot 更换与系统刷写。如果在实践过程中遇到问题,欢迎到技术社区如 云栈社区 与其他开发者交流探讨。




上一篇:手把手配置Clawdbot通过Discord访问:详细步骤与避坑指南
下一篇:Anthropic工程师揭秘:如何用CLAUDE.md构建AI开发的长期记忆系统
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-2-3 00:17 , Processed in 1.521102 second(s), 46 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表