HLK-7621-ALL-KIT-V2.4 OpenWrt 编译、TFTP 救援与固件恢复记录
资源地址
- 官方资料(HLK-7621-ALL-KIT-V2.4 开发板):https://www.hlktech.com/Goods-51.html#datum
- 百度网盘分享(HLK):https://pan.baidu.com/s/1jLOFNGjvsZZwDDnIy7wbnA?pwd=83pg 提取码:
83pg
本文记录基于旧版 OpenWrt Barrier Breaker(Linux 3.10.14)为 MT7621 编译固件,并在根文件系统损坏后通过 U-Boot、TFTP 和 initramfs 恢复系统的完整过程。
一、编译环境与常用命令
OpenWrt 构建系统通常禁止使用 root 用户编译。如果出现以下错误:
1 | Build dependency: Please do not compile as root. |
应切换到普通用户,并确保源码属于该用户:
1 | sudo chown -R "$USER:$USER" ~/mtkopenwrt |
首次完整编译可执行:
1 | make -j$(nproc) V=s |
其中:
nproc返回虚拟机可用的逻辑 CPU 数量。-j$(nproc)按逻辑 CPU 数量并行编译,例如nproc输出4,就等价于-j4。V=s显示较完整的构建信息。V=99显示详细命令,适合排查错误,但不会改变编译结果。
发生编译错误时,建议使用单线程,避免并行日志交错:
1 | make -j1 V=99 |
已经完成的目标文件会被 make 复用,因此用 Ctrl+C 中断后再次执行 make,通常会继续构建,而不是全部重来。不要执行 make clean 或 make dirclean,除非确实需要清理构建结果。
保存并实时观察构建日志:
1 | make -j$(nproc) V=s 2>&1 | tee build.log |
OpenWrt 没有可靠的百分比进度。构建通常依次经过 tools、toolchain、target、package、安装和镜像生成阶段。
二、理解生成的镜像
本次构建生成了以下主要文件:
1 | openwrt-ramips-mt7621-uImage.bin |
它们的用途不同:
| 文件 | 内容 | 主要用途 |
|---|---|---|
uImage.bin |
普通 Linux 内核 | 从 Flash 启动,并挂载 Flash 中的 rootfs |
root.squashfs |
只读根文件系统 | 与内核配合使用 |
squashfs-sysupgrade.bin |
内核 + SquashFS | 永久写入 firmware 分区 |
uImage-initramfs.bin |
内核 + RAM 根文件系统 | TFTP 临时启动和救援 |
vmlinux.elf |
未压缩或带符号内核 | 调试,不是直接烧录固件 |
使用 binwalk 检查永久固件:
1 | binwalk bin/ramips/openwrt-ramips-mt7621-mt7621-squashfs-sysupgrade.bin |
正确的合成固件应同时包含:
1 | uImage header |
本次生成的文件信息为:
1 | 文件大小:7864324 bytes |
这些数值只适用于本次构建。每次重新编译后都应重新核对文件大小和校验值。
三、为什么救援启动需要 initramfs
普通启动流程为:
1 | U-Boot -> Linux 内核 -> 挂载 Flash 中的 SquashFS -> 启动 OpenWrt |
TFTP 救援流程为:
1 | U-Boot -> 将 recovery.bin 下载到 RAM -> 启动内核和 initramfs |
initramfs 是内置在内核镜像中的临时根文件系统。它使系统不依赖 Flash 中的 rootfs,也能进入命令行进行分区检查和固件恢复。initramfs 在 RAM 中运行,重启后其中下载的文件和修改都会消失。
在 make menuconfig 中启用:
1 | Target Images |
对应配置通常为:
1 | CONFIG_TARGET_ROOTFS_INITRAMFS=y |
然后重新构建内核:
1 | make target/linux/clean |
四、旧版 LZMA 工具不兼容
启用 initramfs 后,旧内核可能在生成 initramfs_data.cpio.lzma 时失败:
1 | Error: Incorrect command |
这是旧版 Linux 构建脚本与主机上的 LZMA 命令参数不兼容。可将内置 initramfs 的压缩方式改为 gzip。
注意,kernel_menuconfig 中下面的选项只表示内核是否支持解压外部 ramdisk:
1 | Support initial ramdisks compressed using gzip |
它不一定控制内置 initramfs 的生成格式。应搜索真正的配置项:
1 | INITRAMFS_COMPRESSION_GZIP |
目标配置应为:
1 | CONFIG_INITRAMFS_COMPRESSION_GZIP=y |
如果菜单中不可见,可定位由哪个目标配置文件启用了 LZMA:
1 | grep -RnsE 'CONFIG_INITRAMFS_COMPRESSION_(LZMA|GZIP)' target/linux |
修改持久配置后重新清理并编译。成功时应生成 initramfs_data.cpio.gz,而不是 .cpio.lzma。
五、VirtualBox 与主机之间传输固件
可使用 VirtualBox 共享文件夹,但不要把共享目录直接挂载到源码的 bin 目录,否则原有构建产物会被挂载点暂时遮挡。
推荐让 VirtualBox 自动挂载,或使用独立目录:
1 | /media/sf_openwrt_virtualbox_output |
如果出现权限问题:
1 | sudo usermod -aG vboxsf "$USER" |
也可以通过桥接网络和 SSH 从 Windows 拉取文件:
1 | scp hlk@虚拟机IP:/home/hlk/mtkopenwrt/bin/ramips/固件文件 D:\openwrt_output\ |
六、识别根文件系统启动失败
错误日志示例:
1 | jffs2: Magic bitmask 0x1985 not found |
这表示内核已经启动,但没有在预期的 MTD 分区中找到有效根文件系统。常见原因包括:
- 只写入了内核,没有写入 SquashFS。
- 写入地址或长度错误。
- 固件与 Flash 分区布局不匹配。
- firmware 后部残留旧 JFFS2 数据。
- 启动参数中的 root 分区或文件系统类型错误。
本次 initramfs 启动后的分区表为:
1 | mtd0 0x02000000 ALL |
由此可知 Flash 容量为 32 MiB,firmware 从 0x50000 开始。不要操作 ALL、Bootloader、Config 或 Factory,尤其不能擦除保存 MAC 和无线校准数据的 Factory 分区。
检查 Flash 内容:
1 | hexdump -C -n 64 /dev/mtd4 |
常见魔数:
1 | 27 05 19 56 uImage |
本次检查发现 mtd4 只有一个长度为 0x21822 的 Breed MT7621 uImage,紧随其后的 mtd5 全部为 0xFF,证明 Flash 中只有内核镜像,没有 SquashFS。
七、通过 TFTP 启动恢复系统
U-Boot 输出如下时,表示它正在等待电脑提供 recovery.bin:
1 | TFTP from server 192.168.1.2; our IP address is 192.168.1.1 |
将 Windows 有线网卡设置为:
1 | IP:192.168.1.2 |
将以下文件复制到 TFTP 根目录并重命名:
1 | openwrt-ramips-mt7621-uImage-initramfs.bin -> recovery.bin |
正常下载时,Loading: * 会变成连续的 #,随后 U-Boot 从 RAM 启动。进入如下提示符即表示 initramfs 启动成功:
1 | root@OpenWrt:/# |
注意:U-Boot 日志里的 Model 来自当前 U-Boot 使用的设备树或移植配置,不一定代表实际硬件型号。不能仅凭类似 Model: ASUS RT-AC1200GU 的文字选择固件。
八、在 initramfs 中上传永久固件
本次系统默认 LAN 地址为 192.168.16.254。为了访问位于 192.168.1.2 的 TFTP 服务器,可临时设置:
1 | ifconfig br-lan 192.168.1.1 netmask 255.255.255.0 up |
不要给作为网桥成员的 eth0 单独配置相同地址。
将永久固件下载到 RAM:
1 | cd /tmp |
下载后必须核对:
1 | ls -l /tmp/openwrt-ramips-mt7621-mt7621-squashfs-sysupgrade.bin |
九、绕过旧无线驱动导致的 sysupgrade 死锁
本次运行 sysupgrade -n 时,厂商脚本先关闭 Wi-Fi,MT76x2 私有驱动在 StopDmaRx 中死锁:
1 | INFO: rcu_sched detected stalls |
此时尚未出现 Erasing 或 Writing,说明 Flash 写入还没有开始,可以复位并重新进入 initramfs。
该系统的 mtd 工具支持:
1 | -e <device> erase <device> before executing the command |
在已通过 binwalk、大小和 MD5 校验的前提下,可绕过会关闭 Wi-Fi 的 sysupgrade 脚本,只擦写 firmware 分区:
1 | mtd -e firmware -r write \ |
该命令会完整擦除 firmware、写入合成固件,并在成功后自动重启。执行过程中严禁断电。不要增加 -f,除非已经明确理解镜像检查失败的原因和风险。
十、验证恢复结果
成功启动后检查:
1 | mount |
本次恢复后出现:
1 | /dev/mtdblock5 on /mnt/mtdblock5 type squashfs |
这说明内核、SquashFS 和可写数据分区已经被识别。SquashFS 显示 100% 属于正常现象,因为它是只读压缩文件系统。
验证可写数据是否持久化:
1 | touch /root/persist-test |
重启后文件仍存在,才说明 overlay 或 rootfs_data 已正常提供持久化写入。
十一、访问 Web 管理后台
查看 LAN 地址:
1 | ifconfig br-lan |
临时改为 192.168.1.1:
1 | ifconfig br-lan 192.168.1.1 netmask 255.255.255.0 up |
浏览器访问:
1 | http://192.168.1.1 |
永久修改地址:
1 | uci set network.lan.ipaddr='192.168.1.1' |
如果页面无法打开,检查 Web 服务:
1 | ps | grep uhttpd |
若固件没有包含 uhttpd 和 LuCI,需要在 OpenWrt 配置中选入对应软件包后重新编译。
十二、恢复过程的关键原则
uImage、initramfs和sysupgrade.bin用途不同,不能仅靠改名互换。- TFTP 临时启动应使用 initramfs;永久写入应使用包含内核和 rootfs 的合成固件。
- 写入前同时检查
binwalk、文件大小和 MD5。 - 根据
/proc/mtd确认分区,禁止盲目擦除整片 Flash。 Factory、Bootloader 和校准数据应优先备份。- 只有出现明确的擦写输出后,才表示真正进入 Flash 写入阶段。
- initramfs 中的文件位于 RAM,重启后必须重新上传。
- 旧厂商 SDK 的驱动和脚本可能存在死锁,应根据调用栈定位,而不是在卡死状态下反复等待。
