引言
家里的宽带最近升级了200M上行, 装维说200M上行必须得用XGPON光猫, 买了一个二手xgpon猫, 注册的时候卡在了29%, 过程是O3, 证明我的线路支持XGPON, 但是可能被ONU拦下了.
参考itu的说明: ITU-T G.987.3 明确规定: ONU取得下行同步以后才进入 O2-3 Serial Number 状态; 在这个状态, ONU响应 OLT 的 Serial Number grant, 把自己的 SN 发给 OLT. 只有 OLT 随后发送一个与这个 SN 匹配的
Assign_ONU-ID, ONU才会进入 O4.

于是想着是不是ONU侧认光猫的SN, 就TELNET上去修改了一下新光猫的SN为老光猫SN, 结果输入的时候忘了输入Vender ID, 本来12位的SN只输入了8位, reboot之后power灯一直闪烁, 插到电脑甚至显示网络线缆未连接.
于是乎就有了这篇救砖博客.
获取超级密码和开启Telnet
博通方案的天邑TEWA-1108V在未成功注册前的超级密码为nE7jA%5m.
账号一般是useradmin.
使用超密登录后, 进入http://192.168.1.1:8080/enableTelnet.html
根据恩山帖子 https://www.right.com.cn/forum/forum.php?mod=viewthread&tid=8402465 开启入口也可能是http://192.168.1.1/enableTelnet.html
即可进入开启界面

开启TELNET后, 连接TELNET
telnet可以不用su密码卡BUG获得root权限, 先按照常规方式登录Telnet, 打一个;回车, 这时会报错: sh: syntax error: unexpected “;”, 再输入命令echo $USER, 就是root权限
或者可以通过光猫的MAC地址计算出来, 计算器网址
Telnet可用命令如下, 来源恩山
常用网页入口
地址 用途 http://192.168.2.1:8080/enableTelnet.html 开启 Telnet http://192.168.2.1:8080/backupsettings.conf 下载配置 http://192.168.2.1:8080/updatesettings.html 上传配置 http://192.168.1.1:8080/NN_WAN1.html 删除 TR069 NVRAM / 地区相关
命令 用途 ls /etc/default_configs查询地区配置 cat /proc/nvram/LocationCode查看当前地区 cat /proc/nvram/BaseMacAddr查询 MAC echo XX:XX:XX:XX:XX:XX > /proc/nvram/BaseMacAddr修改 MAC echo 0x0B00 > /proc/nvram/LocationCode切换地区,以北京为例 地区代码
地区 代码 地区 代码 地区 代码 地区 代码 北京 0x0B00内蒙古 0x0F00黑龙江 0x1700福建 0x2300天津 0x0C00辽宁 0x1500安徽 0x2200江西 0x2400河北 0x0D00吉林 0x1600浙江 0x2100重庆 0x32005山西 0x0E00上海 0x1F00江苏 0x2000四川 0x3300山东 0x2500河南 0x2900湖北 0x2A00湖南 0x2B00广东 0x2C00广西 0x2D00海南 0x2E00贵州 0x3400云南 0x3500陕西 0x3D00甘肃 0x3E00青海 0x3F00西藏 0x3600宁夏 0x4000新疆 0x4100qoecmd / MDM 常用命令
命令 用途 sh进入 Shell qoecmd help查看命令 qoecmd mdm -h查看 MDM 命令用法 qoecmd dumpmdm查看配置信息 qoecmd dumpcfg查看可配置信息 qoecmd gponSN get查看 GPON SN qoecmd gponSN set XXXXXXXXXXXX修改 GPON SN qoecmd telecomadmin get获取超级管理员密码 qoecmd restoredefault恢复出厂设置 qoecmd Register set status 0 result 1ITMS 注册 qoecmd bobdata dump查看光模块型号 ct_getITMSRegistStat查看 ITMS 注册状态 cqct_itms查看 LOID mdm dumpobj 2查看配置 mdm setpv修改配置 mdm getpv InternetGatewayDevice.DeviceInfo.X_CT-COM_MACAddress查看 MAC mdm getpv InternetGatewayDevice.DeviceInfo.Manufacturer查看制造商 mdm getpv InternetGatewayDevice.DeviceInfo.SerialNumber查看设备标识后十七位 mdm getpv InternetGatewayDevice.DeviceInfo.ManufacturerOUI查看设备标识前六位 mdm getpv InternetGatewayDevice.DeviceInfo.ProductClass查看设备型号 mdm getpv InternetGatewayDevice.DeviceInfo.X_CT-COM_CheckKey查看 X_CT-COM_CheckKeymdm getpv InternetGatewayDevice.DeviceInfo.X_CT-COM_ServiceManage查看 X_CT-COM_ServiceManage
变砖过程
在光猫正常运行时, 通过 Telnet 查询 GPON SN:
qoecmd gponSN get
返回值是 12 个文本字符, 形式类似:
gponsn:SCTY12345678
随后把它改成了只有 8 个十六进制字符的值, 并重启:
qoecmd gponSN set A1B2C3D4 # 不要执行!!!!!
重启后的表现是:
- POWER 灯持续闪烁.
- 电脑直连时获取不到 DHCP 地址.
- Web 管理页面无法访问.
- 手动指定地址后也无法 ping 通.
reset之后依旧如此, 光猫的reset只能重置用户配置, 不会将所有设置重置.
后来的串口日志表明, 设备能够启动 U-Boot 和 Linux, 但在 PON 初始化期间出现 SN 校验错误, 随后 kernel panic, 等待 5 秒后再次启动.
修复过程
本来以为80块钱打水漂变成电子垃圾了, 结果在冲浪时发现光猫可以通过ttl拯救, 但我手头没有usb-ttl设备, 但有一个Arduino Uno(Uno 兼容板, ATmega328P / 16 MHz, CH340 USB 串口). 接下来的操作都是通过Uno和光猫的ttl口连接操作的. 其中执行命令连接SIN的时候需要用1个2k欧姆的电阻和一个1k欧姆电阻分压实现3.3V输入.
光猫拆解
光猫背面有两颗螺丝, 其中一颗

另一颗需要撕开标签

都拧下之后, 就可以硬撬外壳了, 外壳的卡扣很紧, 很难做到无损拆除请注意.
拆机后如下

其中右下角有四个触点, 名字分别是
SIN SOUT GND 3.3V
其中SIN是写入, SOUT是对外输出, GND是接地.
连接光猫TTL
我使用Arduino与其共地, 然后D2号口接受SOUT的信息转发给PC. 关键错误日志如下
[ERROR ploamFsm] parseSNPW ,138:
Invalid SN Number (1) ([A-Z]4[0-9a-fA-F]8). Given: BRCM12345678
[ERROR ploamFsm] bcm_ploamCreate,443: parseSNPW failed.
Kernel panic - not syncing: Fatal exception
Rebooting in 5 seconds..
这里有一个容易误解的地方, BRCM12345678并不是我实际写入的那个SN, 应该只是个例子.
不过还能启动证明系统本身没坏, 只要想办法把SN改回来就能拯救.
修复过程
根据博通官方的文档可以得知这款光猫的启动流程为
Boot ROM → SPL → TPL → U-Boot proper → Linux → PON 初始化
在出现以下标记时也就是SPL阶段立即发送小写 a, 无需回车:
$SPL: 5.04L.02@348603 $
实际返回:
Use enter to confirm input menu selection
go - continue
ddr - mcb override(hex) or DDR safe mode.
r - Boot Fallback; 1 - recovery
bid - Ignore boardid while booting
mcb - List all the mcb selectors
wdt - Disable spl wdt
h - halt
发送 h 加回车后返回 Halted, 可以暂时停住启动. 后续菜单命令需要回车.
这里参考了 Broadcom 的
early_abort.c.
SPL 的 Recovery 和 Fallback 没解决问题
实际测试结果:
| 操作 | 设备响应 | 后续结果 |
|---|---|---|
r 1, 随后 go | Boot Image: Recovery | 仍加载 Image 2, 发生相同 SN 错误和 panic |
r, 随后 go | Boot Image: Fallback | 选择 Image 1, 但 FIT 头认证失败 |
备用镜像的报错:
SELECTED Image 1 FIT_VOL_ID is 3
padding_pss_verify: invalid pss padding (0xbc is missing)
FAILED to authenticate FIT header!!!
resetting board...
此后热重启仍选择 Image 1; 断电约 5 秒再上电后, 重新回到可加载的正常镜像. 没有查明备用镜像认证失败的根因, 也没修改它.
小写 ty: 进入 U-Boot 命令行
以为没救了, 但翻输出日志看到这么一行
Enter specific characters to stop autoboot in 1s
尝试发送Ctrl+C, 26个字母10个数字都无效 .
Codex帮我在恩山的一篇帖子中的日志找到了 Enter 'ty' to stop autoboot, 因此试了试 ty , 成功看到 => 提示符. 天邑 TEWA-7100A 启动日志
具体就是按下ty, 不需要回车.
看到 => 后, 执行 help、printenv 均可正常返回.
临时启动 Linux 应急 shell
进入 U-Boot 后, 先查询:
=> printenv bootcmd bootargs bootargs_append
bootcmd=run once;sdk boot_img
## Error: "bootargs" not defined
## Error: "bootargs_append" not defined
参考代码支持通过 bootargs_append 追加 Linux 启动参数. Broadcom 参考启动参数处理
本机正常可加载的是 Image 2, 因此执行:
setenv bootargs_append init=/bin/sh
printenv bootargs_append
sdk boot_img 2
这里不执行 saveenv. 参数只用于这一次启动, 重启后消失.
Linux 返回:
VFS: Mounted root (squashfs filesystem) readonly on device 254:0.
Run /bin/sh as init process
#
这时已进入 root shell, 通常的初始化服务没有运行, 因此尚未触发 PON 崩溃路径.
处理看门狗
第一次应急 shell 在约 80 秒后被看门狗重启. 重新进入后, 挂载必要的虚拟文件系统和内存目录, 再启动原厂喂狗程序:
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t tmpfs tmpfs /var
mkdir -p /var/run /var/tmp
/bin/sh /etc/init.d/wdtd.sh start
这一顺序为守护进程提供可写的运行目录.
实际排查时, 在创建 /var/run 前启动 wdtd, 报了 PID 文件错误, 但进程仍持有 /dev/watchdog; 再次启动便提示 EBUSY.
不能看到 PID 文件错误就认为喂狗进程已经退出, 要检查实际进程.
查询真正保存的 SN
cat /proc/environment/gponsn
输出为误写的 8 位值. 本例该节点权限是只读:
-r-------- ... /proc/environment/gponsn
直接运行 qoecmd gponSN get 返回:
could not initialize msg, ret=9002
因为应急 shell 没有qoecmd所依赖的服务.
最终没通过 qoecmd 执行修复, 而是用 U-Boot 修改保存 SN 的环境变量.
修改前, 备份两个环境所在的 Flash 块
其实这里不备份也没啥, 但是想着阴性结果也是结果, 就备份了一下.
U-Boot 查询环境位置:
=> printenv env_boot_magic
env_boot_magic=16384@0x40000,0xaf000
本机存在两个环境副本. Linux 的 /proc/mtd 显示:
dev: size erasesize name
mtd0: 10000000 00020000 "brcmnand.0"
mtd1: 00200000 00020000 "loader"
mtd2: 0fd00000 00020000 "image"
环境副本分别落在以下 128 KiB 擦除块中:
| 环境地址 | 所在块起点 | 对 /dev/mtd1 的读取参数 |
|---|---|---|
0x40000 | 0x40000 | bs=131072 skip=2 count=1 |
0xaf000 | 0xa0000 | bs=131072 skip=5 count=1 |
loader 分区从物理偏移 0 开始, 所以这里的分区内偏移与物理偏移相同. 其他分区布局不能直接套用.
只读 Flash, 写入内存中的 /var/tmp:
dd if=/dev/mtd1 of=/var/tmp/env-block-before.bin bs=131072 skip=2 count=1
sha256sum /var/tmp/env-block-before.bin
dd if=/dev/mtd1 of=/var/tmp/env-block2-before.bin bs=131072 skip=5 count=1
sha256sum /var/tmp/env-block2-before.bin
经串口把备份传回电脑
由于软件串口连续输出时会丢字节, 使用 OpenSSL Base64 编码, 并在每行之后短暂停顿:
echo ENV_BACKUP_BEGIN
openssl base64 -in /var/tmp/env-block-before.bin | while IFS= read -r L; do echo "$L"; usleep 5000; done
echo ENV_BACKUP_END
第二份使用不同标记:
echo ENV_SECOND_BEGIN
openssl base64 -in /var/tmp/env-block2-before.bin | while IFS= read -r L; do echo "$L"; usleep 5000; done
echo ENV_SECOND_END
电脑端把 RX 原始字节保存成 .bin, 截取开始、结束标记之间的 Base64, 再解码为 131072 字节的二进制文件. 两份文件的 SHA-256 都与光猫端计算值一致, 另外检查了环境内部 CRC.
这台精简系统里没有可用的 printf 命令, sleep 0.05 也不接受小数, 最后使用 echo 和 BusyBox 的 usleep.
备份的是故障时的环境块, 其中仍包含误写的 SN; 作用是保留修改前现场.
在 U-Boot 中恢复原始 SN
备份完成后, 从应急 shell 执行 reboot -f, 重新在 U-Boot 倒计时处输入 ty.
先核对三项:
printenv gponsn env_boot_magic bootargs_append
本次确认:
gponsn仍是误写值.- 环境副本位置与备份时一致.
- 临时的
bootargs_append已经不存在.
然后恢复自己设备记录过的原始 SN:
# 以下 SN 是例子, 执行前必须换成自己设备的原值.
setenv gponsn SCTY12345678
printenv gponsn
读回正确后, 保存:
=> saveenv
Saving Environment to BOOT_MAGIC... save to 40000
save to af000
OK
这里的 saveenv 会真正写入 Flash. 它保存当前环境, 因此在执行前确认临时启动参数没有混入非常重要. 参考实现会读入对应擦除块, 更新环境区域, 再写回整块; 前面的备份覆盖了两个实际涉及的块. Broadcom 参考 BOOT_MAGIC 保存实现
执行 reset, 再次输入 ty, 再读一次:
=> printenv gponsn bootargs_append
gponsn=SCTY12345678
## Error: "bootargs_append" not defined
这次读值发生在重新启动、重新加载环境之后, 因此验证了保存结果, 不只是修改后的 RAM 值.
最后执行:
boot
恢复正常启动流程.
修复结果与验证边界
正常启动后, 看串口日志
[NTC ploamFsm] bcm_ploamCreate: ploam driver created.
:::::Broadcom OMCI Stack v4.2 ...
并且POWER灯常亮, 光纤灯闪红(因为没插光纤).
吐槽
谁家好人写光猫系统保存sn不校验, bootloader校验SN不通过导致kernel panic啊??
参考资料
- Broadcom源码
- https://www.right.com.cn/forum/thread-8412122-1-1.html
- https://www.right.com.cn/forum/thread-8426017-1-1.html
- https://www.right.com.cn/forum/thread-8455169-1-1.html
- https://www.right.com.cn/forum/forum.php?mod=viewthread&tid=8402465
- https://www.right.com.cn/forum/forum.php?mod=viewthread&tid=8470716
- https://www.right.com.cn/forum/thread-8428331-1-1.html