👁 30

这台光猫没有 TTL 排针,刷坏了只能拆机上编程器。没有自救能力、没有第二台能查资料的设备,不要刷。文中所有 MAC、SN、密码、密钥都已替换成示例值,照抄一定失败,必须换成你自己机器的现场数据。全文 15 节、10 张表,是我这台机器一次真实刷机从开始到验收的完整记录。
这篇文章到底写了什么
网上关于 AN7581 光猫刷机的资料,大多停在「能进 U-Boot 了」或者「刷完能开机了」。真正会让人卡住的其实是另外几件事:
- 原厂 17 个分区怎么在不拆机、不用 TFTP 的情况下完整备份出来,并且证明备份是对的;
- U-Boot 要的 1 MiB
factory板级数据怎么从原厂那堆文件里重建,格式是什么; - 六步刷写里每一步的期望输出是什么,哪些报错属于正常、哪些必须停下来;
- 刷完怎么验收,而不是「能亮灯、能上网」就算完。
这篇按顺序全部写清楚:原理、准备、开 Telnet、备份、重建 factory、装恢复引导、U-Boot 六步、验收、故障排查、救砖、以及最后的自动化。
一、这台机器是什么
| 项目 | 值 |
|---|---|
| 型号 | FiberHome HG5585F CT(中国电信定制) |
| SoC | Airoha AN7581,4 核 ARMv8 |
| 内存 | 512 MB |
| 闪存 | 256 MiB NAND |
| 原厂系统 | Linux 5.4.55 aarch64 |
| 原厂 Web | http://192.168.1.1:8080(80 端口只是 LuCI 前端壳) |
| 刷入系统 | PonWrt SNAPSHOT r41551-c3b518baec,内核 6.18.52,target airoha/an7581 |
同平台其它机型(AN7581 / AN7583 那一批光猫)的路子类似,但分区偏移、factory ABI、FIT 型号字符串都可能不同,不要跨机型套用。总览类资料可以看另一篇,这里的每个数字都只对 HG5585F CT 负责。
二、为什么可以免拆
刷机链路实际由三段组成,每段都只依赖上一段的产物:
原厂系统(Telnet root)
├─ 备份 17 个 MTD 分区(HTTP,MD5 校验)
├─ 导出 factory_conf / table / WiFi EEPROM
├─ 重建 1 MiB factory-1m.bin
└─ 写入 BL2 + FIP(an758x-stock2ubi),重启
▼
U-Boot 恢复模式(http://192.168.0.1/)
├─ flash-bl2
├─ ubi-rebuild
├─ flash-board-data(factory 卷)
├─ flash-uboot(FIP)
├─ flash(sysupgrade.itb)
└─ boot-production
▼
OpenWrt / PonWrt(http://192.168.1.1/)
└─ 型号、网络、Web、SSH、MAC、UBI 卷、回读哈希逐项验收
真正难的不是「刷」,是备份校验和 factory 重建。这两步错了,后面全白干。
三、准备清单
| 类别 | 需要的东西 | 说明 |
|---|---|---|
| 硬件 | 网线一根、电脑一台 | 全程不需要 TTL、不需要拆机 |
| 主机环境 | Linux,curl、Python 3、telnet 客户端 | Windows 也能刷,但备份和 factory 脚本都在 Linux 侧 |
| 工具 | an758x-stock2ubi(ARM64 静态二进制) | 跑在原厂系统里,提供备份和写引导的 HTTP 接口 |
| 引导 | preloader.bin(BL2)、bl31-u-boot.fip(FIP) | 必须是为 HG5585F CT 构建的产物,两处用同一组文件 |
| 系统 | *-squashfs-sysupgrade.itb | FIT 型号必须是 fiberhome,hg5585f-ct |
| 磁盘 | 至少 1 GB 空闲 | 17 个分区备份约 416 MB |
| 耐心 | 首次进入 U-Boot 网页要等 60–90 秒 | 25 MiB 固件上传可能要 5–15 分钟 |
关于引导文件有一个必须说清楚的点:BL2 和 FIP 不能从原厂 mtd0 里提取。原厂 mtd0 是厂商自己的引导,不是你要装的 U-Boot。要从 pbs05/uboot-an758x 这类项目拿为该机型构建的成品,并且「装恢复引导」和「U-Boot 六步」用的是同一组 preloader 和 FIP,不能一个用 A 版、一个用 B 版。
四、第一步:免拆开 Telnet
4.1 关键前提
必须先登录 8080 的 Web 管理页,否则所有 POST /cgi-bin/ajax 一律 404——加密写得再对也没用。80 端口那个 LuCI 页面只是前端,认证和接口都在 8080。
会话按客户端 IP 绑定,不需要 cookie。也就是说:同一台电脑登录一次,后面直接用。
4.2 五步接口
| 步骤 | 请求 | 作用 |
|---|---|---|
| 1 | POST /login.cgi(username=telecomadmin&psd=) | 建立管理会话,成功响应里含 window.location.href="main.html" |
| 2 | GET /cgi-bin/ajax?ajaxmethod=web_get_brmad | 读设备 MAC,返回 {"brmad":"AABBCC112233"} |
| 3 | 本地计算 | sha256(MAC大写) 的十六进制串:前 16 位做 IV,第 32–48 位做 key |
| 4 | GET /cgi-bin/ajax?ajaxmethod=web_get_refresh_sessionid | 取一次性 sessionid |
| 5 | POST /cgi-bin/ajax(AES 密文的十六进制) | 提交 telnet=1&action=telnet&sessionid= |
加密方式是 AES-128-CBC + PKCS7,key 和 IV 就是上面那两段 16 个字符(16 字节),输出小写十六进制作为请求体。
成功响应长这样,randstr 每次不同:
{"randstr":55407696,"services":{"ftp":"0","telnet":"1","dnsrelay":"1","portal":"0","access":"0","terminal_number":"255","status":"99","result":"99"}}
判断成功的唯一标准是响应里出现 "telnet":"1"。部分固件会把响应也加密成十六进制,脚本要兼容两种。
4.3 最小实现
import hashlib, binascii, urllib.request, urllib.parse, json
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
BASE = "http://192.168.1.1:8080"
UA = {"User-Agent": "Mozilla/5.0"}
def get(p):
return urllib.request.urlopen(urllib.request.Request(BASE + p, headers=UA), timeout=8).read().decode()
def post(p, body):
req = urllib.request.Request(BASE + p, data=body.encode(),
headers={**UA, "Content-Type": "application/x-www-form-urlencoded"}, method="POST")
return urllib.request.urlopen(req, timeout=8).read().decode()
# 1. 先登录,不登录后面全是 404
post("/login.cgi", urllib.parse.urlencode({"username": "telecomadmin", "psd": "你的Web密码"}))
# 2. MAC → 密钥
mac = json.loads(get("/cgi-bin/ajax?ajaxmethod=web_get_brmad"))["brmad"].strip().upper()
h = hashlib.sha256(mac.encode()).hexdigest()
iv, key = h[:16], h[32:48]
# 3. sessionid
sid = json.loads(get("/cgi-bin/ajax?ajaxmethod=web_get_refresh_sessionid"))["sessionid"].strip()
# 4. 加密提交
plain = f"telnet=1&action=telnet&sessionid={sid}&ajaxmethod=set_services".encode()
n = 16 - len(plain) % 16
enc = Cipher(algorithms.AES(key.encode()), modes.CBC(iv.encode())).encryptor()
body = binascii.hexlify(enc.update(plain + bytes([n]) * n) + enc.finalize()).decode()
print(post("/cgi-bin/ajax", body))
4.4 验证
nc -v 192.168.1.1 23 # 连上就说明端口开了
telnet 192.168.1.1 # 账号 telnetadmin
su # 提权到 root,id 应该是 uid=0(root)
Telnet 密码不是固定值,按 MAC 派生:Telnet 账号用 FH- 前缀 + MAC 后 6 位大写,su 用 Fh@ + MAC 后 6 位大写。具体字母和规则随机型不同,本文不贴固定串。
三点注意:
- Telnet 是明文协议,只在 LAN 内用,别映射到公网;
- 光猫重启后 23 端口是否保持,没有验证过,不通就重跑一次脚本;
- 开 Telnet 只调用 Web 自己的接口,不刷机、不改固件,可逆。
五、第二步:17 个分区,一个都不能少
5.1 分区表
| MTD | 名称 | 大小 | 物理偏移 | 性质 |
|---|---|---|---|---|
| mtd0 | boot | 2.5 MiB | 0x00000000 | 只读,必须一致 |
| mtd1 | bootflag | 512 KiB | 0x00280000 | 启动标志,救砖关键 |
| mtd2 | KernelA | 6 MiB | 0x00300000 | 只读 |
| mtd3 | RootfsA_Header | 8.2 KiB | 0x00900000 | 只读 |
| mtd4 | RootfsA_Data | 31.99 MiB | 0x009020cc | 只读 |
| mtd5 | RootfsA | 32 MiB | 0x00900000 | 只读 |
| mtd6 | KernelB | 6 MiB | 0x02900000 | 只读 |
| mtd7 | RootfsB_Header | 8.2 KiB | 0x02f00000 | 只读 |
| mtd8 | RootfsB_Data | 31.99 MiB | 0x02f020cc | 只读 |
| mtd9 | RootfsB | 32 MiB | 0x02f00000 | 只读 |
| mtd10 | apps | 120 MiB | 0x04f00000 | 运行中可写 |
| mtd11 | frameworka | 16 MiB | 0x0c700000 | 只读 |
| mtd12 | frameworkb | 16 MiB | 0x0d700000 | 只读 |
| mtd13 | factory | 3 MiB | 0x0e700000 | 板级数据,JFFS2,挂 /fhdata |
| mtd14 | userlocalct | 2 MiB | 0x0f700000 | 只读 |
| mtd15 | apps(UBI 卷) | 106.08 MiB | 无物理偏移 | 在 mtd10 内部 |
| mtd16 | userdata(UBI 卷) | 8.36 MiB | 无物理偏移 | 运行中可写 |
两个容易搞错的地方:
- mtd15 / mtd16 不是物理分区,它们是 mtd10(120 MiB
apps)内部的 UBI 卷,所以没有物理偏移。精确字节数:mtd15 = 111230976,mtd16 = 8761344。 - 表里的大小是给人看的约数。校验时必须用
/proc/mtd里的精确字节数,不能用 106.08 MiB 这种四舍五入的值。
5.2 怎么备份
把 an758x-stock2ubi 传到原厂系统上运行:
wget http://<你的电脑IP>:8000/an758x-stock2ubi -O /tmp/an758x-stock2ubi
chmod +x /tmp/an758x-stock2ubi
nohup /tmp/an758x-stock2ubi >/tmp/stock2ubi.log 2>&1 &
# 日志里应出现:AN758x Stock2UBI listening on http://0.0.0.0:3333
它自带备份接口,不用 TFTP,也不占 /tmp 空间:
for i in $(seq 0 16); do
curl -o mtd$i.bin http://192.168.1.1:3333/backup/$i
done
index 严格对应 /proc/mtd 的顺序,从 0 到 16,一共 17 个文件,约 416 MB。
5.3 校验规则(这一步决定你敢不敢往下走)
1. 本地文件大小必须与 /proc/mtd 的精确字节数一致;
2. 在设备上跑 md5sum /dev/mtdX,与本地 md5sum 逐项比对;
3. mtd0–mtd9、mtd11–mtd15 必须完全一致;
4. mtd10 和 mtd16 允许不一致——它们是运行中可写分区,你读第一遍和第二遍都会不同。这不是备份坏了;
5. 生成 backup_md5.txt 存档,和备份放在一起。
只要 mtd0–mtd9、mtd11–mtd15 有一个不一致,就重新下载那个分区;两次都不一致,停下来查 NAND 坏块,别继续。
六、第三步:重建 1 MiB 的 factory
6.1 为什么要重建
U-Boot 要的 factory 是 UBI 里一个固定 1 MiB(1048576 字节)的静态卷,格式由 an7581-fiberhome-ubi-parts.dtsi 定义。而原厂 mtd13 是一个 3 MiB 的 JFFS2 分区(挂载在 /fhdata),两者完全不是一回事。
绝对不能把 3 MiB 的 mtd13 备份直接写进 1 MiB 的 factory 卷。 写进去的结果是 MAC 变随机、PON 校准丢失、WiFi 起不来。
6.2 三份输入
| 来源 | 内容 |
|---|---|
/fhdata/factory_conf | UCI 文本:brmac(6 字节 MAC)、GponSN(8 字节 hex)、SerialNumber(ASCII) |
/fhdata/table | 2048 字节,magic fiberhomebdbob,PON 校准数据 |
/fhdata/wlan/AX3000_RT30xxEEPROM_5.bin | 前 4096 字节是 MT7916 的 WiFi EEPROM |
6.3 1 MiB 的布局
| 偏移 | 大小 | 内容 |
|---|---|---|
0x000000 | 0x800 | APONCAL PON 校准块 |
0x001000 | 0x1000 | MT7916 WiFi EEPROM |
0x002000 | 6 | 基础 MAC |
0x002010 | 8 | PON SN(二进制) |
0x002020 | 0x20 | 设备 SN(ASCII,NUL 补齐) |
| 其余 | — | 全部 0xFF |
APONCAL 头结构:
0x00 8 "APONCAL" + NUL(0x00)
0x08 u16 version = 1
0x0a u16 header_size = 0x80
0x0c u32 chip (1 = GN28L95, 2 = 另一种)
0x10 u32 format (1 = native)
0x14 u32 payload_size
0x18 u32 payload_crc
0x7c u32 header_crc (覆盖 0x00..0x7b)
0x80 ... payload
CRC 是标准 CRC-32(poly 0xEDB88320、init 0xFFFFFFFF、末尾异或 0xFFFFFFFF),跟 zlib.crc32 一样。注意原厂 fiberhomebdbob 表里那个 CRC 用的是变体:同样是反射多项式,但从 0 开始、末尾取反,等价于 crc32(data, 0) ^ 0xFFFFFFFF。
WiFi MAC 的派生规则:
wifi_2g = base_mac; wifi_2g[1] += 1
wifi_5g = wifi_2g; wifi_5g[5] += 8 (mod 256)
EEPROM 里的 device ID 必须是 0x7916。
6.4 写完的校验清单
- 文件长度恰好 1048576 字节;
APONCALmagic、version=1、header_size=0x80;- header CRC 和 payload CRC 都通过;
- 基础 MAC 是单播地址且不为全零;
- PON SN 是 8 字节,设备 SN 不超过 32 字节;
- WiFi EEPROM 的 device ID 是
0x7916; 0x2040之后全是0xFF。
任何一条不过,都不要往设备上写。
七、第四步:装恢复引导,进 U-Boot
在原厂系统里调 an758x-stock2ubi 的接口,multipart 提交 BL2 和 FIP:
curl -F "[email protected]" -F "[email protected]" http://192.168.1.1:3333/api/flash
期望响应:
{"message":"BL2 written to /dev/mtdblock0; bootstrap UBI at 0x20000..0xe0000; readback verified; rebooting"}
看到 readback verified; rebooting 就说明写进去并回读验证过了。设备重启后进入 U-Boot 的 HTTP 恢复模式:
- 地址变成
http://192.168.0.1/; - U-Boot 跑了
httpd dhcp,电脑会拿到192.168.0.100这类地址; - 页面可能要等 60–90 秒才出来,别急着断电。
没拿到 DHCP 就手动配静态 192.168.0.2/24,网关 192.168.0.1。
进去先读设备信息:
curl http://192.168.0.1/api/device
必须确认:
model是FiberHome HG5585F CT;ubi = true、rebuild = true;board_data里有{"kind":"ubi","target":"factory","size":1048576}。
从这一步开始,原厂系统已经没了,后面全靠 U-Boot 页面救。
八、第五步:U-Boot 六步刷写
8.1 接口长什么样
U-Boot 的 HTTP API 很朴素,但有两个坑必须先讲清楚:
| 接口 | 方法 | 说明 |
|---|---|---|
/api/device | GET | 型号、内存、闪存、U-Boot 版本、ubi、rebuild、board_data |
/api/storage | GET | 可写目标:mtd nand0、bl2、ubi |
/api/task | GET | 当前任务:id、state、busy、phase、code、upload_id、output |
/api/env | GET | U-Boot 环境变量 |
/api/upload | POST | 请求体就是文件原始字节,Content-Type: application/octet-stream |
/api/task | POST | JSON:{"operation":"...","upload_id":...} |
坑一:/api/upload 不解析 multipart,必须发原始字节。而第四步原厂那侧的 ...:3333/api/flash 恰恰是 multipart——两个接口长得像,用错就传不上去。
坑二:/api/upload 的响应里同时有 upload_id 和 id。upload_id 是这次上传的句柄,用来提交任务;id 只是当前任务快照,不是新任务 ID。把 id 当任务号去轮询,会一直看到别人的任务。
8.2 提交与轮询
POST /api/task
{"operation":"flash-bl2","upload_id":8338}
返回 state=queued、busy=true。记下它的 id,每 0.7–1 秒轮询 GET /api/task,直到 state=done;code=0 才算成功,否则 output 里是错误。
两个必须遵守的规则:
- 返回 HTTP 409 说明有任务在跑,等
busy=false再提交,不要并发重试; - 轮询到的
id和你提交的不一样,说明有另一个客户端(浏览器页面或另一个 agent)接管了,停下来重新读状态,不要假设你的任务执行过。
boot-production 是唯一例外:设备可能在 POST 返回前就重启,连接直接断。断开不等于失败,只有验收通过才算成功。
8.3 六步顺序与期望输出
| 顺序 | 操作 | 文件 | 期望输出 |
|---|---|---|---|
| 1 | flash-bl2 | preloader.bin | BL2 written and verified (131072 bytes) |
| 2 | ubi-rebuild | — | 创建 fip、ubootenv、ubootenv2、factory 卷 |
| 3 | flash-board-data(target=factory) | factory-1m.bin | Wrote and verified 1048576 bytes in UBI volume 'factory' |
| 4 | flash-uboot | bl31-u-boot.fip | FIP written and verified(FIP 340992 B) |
| 5 | flash | *-squashfs-sysupgrade.itb | Firmware FIT verified for fiberhome,hg5585f-ct + 回读 CRC |
| 6 | boot-production | — | 设备重启,恢复页失联 |
顺序不可换,理由是硬的:
- 先 BL2:没有 BL2 就没有启动链;
- 再重建 UBI:旧厂商卷和新布局冲突,首次安装跳过
ubi-rebuild必炸; - 板级数据必须在重建之后写:写在前面会被重建一起冲掉;
- 最后才是 U-Boot 和系统:这两步失败还能回恢复页重来,前面错了就只剩串口/编程器。
8.4 哪些输出看着像错、其实是正常
Skipping bad block:NAND 出厂坏块,正常,记录偏移继续(这台机器的坏块在0x0bfe0000、0x0c000000);- 写板级数据前出现
Read N bytes from volume factory to ...; Creating dynamic volume fit.new随后重命名为fit;code=0但output很长。
真正必须停的:
- 任何一步
code != 0; - FIT 校验报出别的型号;
- 任务输出里 factory CRC 不匹配;
flash之后没有fit卷;boot-production之后又回到192.168.0.1。
还有三个操作永远不要用来「修」失败:nand-scrub(擦掉出厂坏块标记)、flash-all(整片覆盖,连引导一起)、write(裸写目标)。它们只会把可恢复的问题变成不可恢复。
九、第六步:验收,别用「能亮灯」当标准
设备起来后,电脑应该通过 DHCP 拿到 192.168.1.x,网关 192.168.1.1。
# 1. Web 是否可达
curl -sS -o /dev/null -w '%{http_code}' http://192.168.1.1/; echo
# 2. 型号与系统
ssh [email protected] 'ubus call system board; cat /etc/openwrt_release'
# 3. 接口与 MAC
ssh [email protected] 'ip -br addr; cat /sys/class/net/eth0/address'
# 4. UBI 卷
ssh [email protected] 'ubinfo -a'
# 5. factory 卷与本地镜像比对(静态卷,可整卷 md5)
ssh [email protected] 'md5sum /dev/ubi0_3'
md5sum factory-1m.bin
# 6. fit 卷只比前 N 字节(动态卷会用 0xFF 补齐)
N=$(stat -c%s sysupgrade.itb)
ssh [email protected] "head -c $N /dev/ubi0_4 | md5sum"
md5sum sysupgrade.itb
/dev/ubi0_3、/dev/ubi0_4 是这台机器的卷号,换机器要先 ubinfo -a 确认编号,别照抄。
期望值:
| 检查项 | 期望 |
|---|---|
curl http://192.168.1.1/ | 200,跳转 cgi-bin/luci/ |
curl http://192.168.1.1/cgi-bin/luci | 403(未登录时的正常响应,403 body 就是登录页) |
ubus call system board | model FiberHome HG5585F CT,board_name fiberhome,hg5585f-ct |
| 系统 | PonWrt / OpenWrt,target airoha/an7581 |
br-lan | 192.168.1.1/24 |
| WAN | pon0,dhcp |
eth0 MAC | 等于 factory 里 0x2000 处的 MAC |
| SSH | dropbear 可连,初始 root 空密码——立刻设密码 |
| UBI 卷 | fip、ubootenv、ubootenv2、factory、fit、rootfs_data |
/overlay | 挂在 rootfs_data 上,有剩余空间 |
| WiFi | phy0-ap0、phy1-ap0 存在,MAC 是按规则派生的 |
任一红旗下出现就回恢复模式,别继续:
- MAC 是全零或者跟 factory 对不上;
- factory 卷哈希和本地不一致;
fit卷不存在或哈希对不上;- 型号报成了别的机器;
boot-production之后又回192.168.0.1。
十、换成自己的固件
PonWrt 只是「能跑」的跳板。换成自己编译的固件不用回 U-Boot,直接 sysupgrade:
1. LuCI → 系统 → 备份/刷写固件;
2. 上传同机型的 *-squashfs-sysupgrade.itb;
3. 取消勾选「保留配置」——跨固件保留配置是诡异故障的头号来源;
4. 等自动重启,重新用 192.168.1.1 进。
三条硬约束:固件必须为 fiberhome,hg5585f-ct 构建;分区布局必须一致(fip/factory/fit 卷名和大小对得上);刷完重新核对 MAC 和无线校准,WiFi 起不来先查 factory 卷,不要急着重刷。
十一、故障排查表
| 现象 | 原因 | 处理 |
|---|---|---|
/api/upload 返回里没有 upload_id | 用了 multipart | 改成原始字节 + application/octet-stream |
| 任务返回 HTTP 409 | 另有任务在跑 | 等 busy=false 再提交 |
轮询发现 id 变了 | 别的浏览器/agent 接管 | 停,重新读状态,别假设自己跑过 |
flash 拒绝镜像 | FIT 型号不符或文件损坏 | 核对型号,重新下载比对 MD5 |
ubi-rebuild 报 Skipping bad block | NAND 出厂坏块 | 正常,记录偏移继续 |
| mtd10 / mtd16 哈希和路由不一致 | 可写分区在变 | 正常,只要引导/factory 一致即可 |
| 恢复引导后一直没 DHCP | 网页还没起 / 旧租约 | 等 60–90 秒,续租,或静态 192.168.0.2/24 |
192.168.0.1 不通但链路是通的 | 设备还在启动或启动失败 | 等;断电重启;启动失败会自动回恢复页 |
| 新系统 Web 返回 403 | LuCI 未登录 | 正常,浏览器开 /cgi-bin/luci/ |
| SSH 拒绝登录 | 没设密码或客户端只认密钥 | 新系统 root 空密码可用,先设密码 |
| 刷完 MAC 全零/不对 | factory 没写或写错 | 重新 flash-board-data |
| 25 MiB 固件上传超时 | 客户端超时太短 | 留 5–15 分钟,单次原始 POST |
| 重启又回原厂系统 | 没执行 boot-production 或缺 fit 卷 | 回恢复页重跑 flash + boot-production |
| 需要重新进恢复模式 | 系统启动失败或按住复位 | U-Boot 会自动回 httpd dhcp 192.168.0.1 |
十二、救砖与回原厂
回恢复模式:断电重启,启动失败时 U-Boot 自动回 192.168.0.1;不行就按住复位再上电。
恢复顺序(从失败那一步重来,不要跳):
1. 192.168.0.1 通不通?不通查链路/DHCP/换 LAN 口,最后才是串口;
2. /api/device 型号是不是 HG5585F CT、ubi:true?不是就停,说明引导不对;
3. BL2 和 FIP 是否完好?先重跑 flash-bl2、flash-uboot,这两步可重复执行;
4. UBI 是否健康?重跑 ubi-rebuild → 板级数据 → FIP → 系统 → 启动。
回原厂:按 mtd0 → mtd16 顺序回写备份,并且恢复 bootflag(mtd1)。顺序错或漏 bootflag,机器起不来。 这一步没有 U-Boot 兜底,属于真正的最后手段。
最值钱的东西:17 个分区备份和 factory-1m.bin。别只存刷机那台电脑上,也别只存一份。
十三、八个常见误区
1. 开 Telnet 前不登录 8080 的 Web,接口全 404,误以为加密算法错了;
2. 在 80 端口的 LuCI 页面登录,以为已经登录,其实认证在 8080;
3. 备份时看到 mtd10/mtd16 哈希不一致就慌,其实那是可写分区;
4. 把 3 MiB 的 mtd13 写进 1 MiB 的 factory 卷,MAC、SN、校准全丢;
5. 首次安装跳过 ubi-rebuild,旧卷冲突,开机异常;
6. 跨机型套用 preloader / FIP,直接黑砖;
7. 用 nand-scrub / flash-all 去「修」失败,把可恢复变成不可恢复;
8. 刷完不验收 MAC 和 factory 卷,WiFi 不通又回头重刷,越刷越乱。
十四、这套流程能不能交给 agent 自动跑
可以,但前提是把「什么时候必须停」写进约束里。这次刷完,我把它整理成了两份东西:
- 一份任务提示词:角色、目标、硬性约束、阶段 0–5、每阶段门禁、失败处理、最终报告模板;
- 一个 Skill:
SKILL.md+ 4 份参考文档(API、分区布局、验收、故障排查)+ 4 个脚本(备份、重建 factory、U-Boot 客户端、原厂数据导出)。
门禁的设计是关键:不是「检查一下」,而是「把校验结果念出来,对不上就终止」。比如备份阶段的门禁是「mtd0–mtd9、mtd11–mtd15 的 MD5 必须与设备一致」,写成「检查备份完整性」,它就会自己脑补一个通过。
下载(提示词 + Skill + 脚本 + 现场记录,约 29 KB):
提示词和 Skill 的完整复盘,包括它当时怎么在没被授权的情况下把机器刷完的、哪三步其实很危险,写在另一篇:
十五、一句话总结
免拆刷 AN7581 光猫,真正决定成败的不是 U-Boot 那六下点击,而是备份有没有校验、factory 有没有重建对。这两件事做扎实,剩下的是照顺序点;这两件事糊弄,后面全是玄学。
同平台其它机型的路线差异、文件清单,看这篇总览:
AN758x 光猫刷机总览:一套 Web U-Boot,14 款机型的刷机路线与文件清单
💖 打赏支持
如果这篇文章帮到了你,欢迎打赏支持
微信扫一扫,赞赏支持
发表回复