用TTL线在CFE环境下拯救半砖wrt54g路由器
缘起:路由器被刷成半砖
Linksys wrt54gs v4路由器,已刷入 tomato-dualwlan 1.23。使用数年,未出现任何故障。
在日用的wifi网络上,通过web界面刷入了错误的tomato-dualwlan的 R2 firmware。
路由器毫无意外地挂了。后查资料得知,以上的每一步都有风险,选错firmware则是致命的。
正确的刷机过程是:
-
路由器和刷机用的计算机脱离日用网络。用一根网线(有线而不是无线)链接路由器和计算机,组成一个干净的微型网络。
-
计算机上设置固定的ip地址。
-
刷机前进入路由器配置界面恢复缺省值。
-
仔细查看资料,确认正确的固件。如有任何疑问,放弃是理性的选择。
-
选择头脑清醒的时间,在适合工作的场所,跟懂技术的朋友交流讨论,不要喝酒……
唯一的好消息是路由器处于半砖状态。所谓半砖是指路由器的CFE(相当于计算机的BIOS)工作正常。
CFE只能通过JTAG刷,不用JTAG就刷不坏(其实用TTL线也可以更新CFE,这是后话)。
也就是说,此时的路由器相当于一台没有接显示器和键盘,有硬盘(flash芯片),
但操作系统已经不能正常工作的计算机。
故障现象
插入电源后,全部灯亮,迅速熄灭,仅留下插网线的端口所对应的灯亮。
用计算机 ping 不通。该计算机已设置为:
地址:192.168.1.2
子网:255.255.255.0
网关:192.168.1.1
tftp刷机失败
既然无法 ping 通,说明计算机无法与路由器建立TCP连接,那么,web界面肯定用不了。
下一步只能尝试tftp刷机。tftp ,顾名思义是基于网络ftp的协议。理论上有两种方式上传新的 firmware 固件:
-
路由器开tftp服务程序,操作计算机运行tftp客户端上传文件。
-
计算机开tftp服务程序,操作路由器运行tftp客户端从服务器上读取软件。
以上任何一种方式都需要 ping 通计算机,于是问题又回到起点。
经过查资料和实测可以用短路法,即将路由器的flash芯片(mx29lv320)的16、17脚短接,使路由器进入safe mode,恢复ping,同时打开tftp服务,使用上述第1种方式从计算机上传新的固件到路由器。
又据网络资料称,正常情况下路由器上电后启动运行CFE,然后进入linux操作系统,期间有0-1秒的时间运行了tftp服务程序,此时可以用计算机上传固件。
于是为了这个0-1秒的时间,我们使用了各种奇怪而扭曲的操作方案。
我设置计算机的网络链接。打开 CMD 窗口,执行ping命令:
ping 192.168.1.1 -t
计算机上安装的是windows 2008,缺省未安装tftp,需要增加新功能……熟悉tftp命令……另开一个 CMD 窗口输入tftp命令:
tftp -t -i 192.168.11.1 put xxx.bin
旋转计算机屏幕以利于观察何时接通。
硬件攻城狮用镊子短接flash 芯片的16、17脚.
软件攻城狮(我)插上电源,观察屏幕。在 ping 通1秒以内,按下回车键。
tftp命令的结果有两个:
-
Invalid code partern
-
Timeout
根据网路上的案例,前者是文件头不对,后者是tcp链接失败。
于是,在网络上搜索各种固件。固件的文件头有两个:
-
W54S
WRT54GS-v4_1.06.3.002_fw.bin WRT54GV4.0_4.20.9_SC_code.bin FreemanBasic_V1.0.2_wrt54gs.bin tomato_dual_1.23\Firmware\WRT54GSv4.bin dd-wrt.v24_mini_wrt54gs.bin
-
HDR0
Tomato-1.28.2890-R1-4M.trx
然现在的问题并没有那么简单。路由器原来用的是tomato_dual_1.23\Firmware\WRT54GSv4.bin
,刷的是Tomato-1.28.2890-R1-4M.trx
,那么问题来了,路由器里边是1.23还是1.28的文件头呢?
操作结果是两种文件头都试过了,都没有成功。
分析问题,提出新的技术方案
经过多次刷机失败以后,攻城狮们放弃了……坐下来认真分析。
-
路由器上电后,网络链接并未建立。在 Linux 中这通常意味着驱动出错,或者网络被关闭。
-
无法确认tftp服务程序是否开通过,何时开通。
此路不通……必须另外设想其它的方案。可选的有TTL刷机,JTAG刷机。
TTL接口其实是串行端口。对软件攻城狮来说就是类似com1—9600速率—N81
的东西。对硬件攻城狮来说就是RX接收,TX发送,GND地
三条线,±12V。只不过由于终端设备的电源供电通常为0~3.3/5V,因此对数据0和1的高低电平、临界值进行了调整,接计算机时需要升压电路。
串行端口在终端上通常具有多重功能,显示信息(串行终端,在unix系统上常见),输入命令,传递数据。它是类似路由器这样的设备的显示接口键盘接口和数据接口。
JTAG是并行接口。对软件攻城狮来说就是类似ltp1
的东西。对硬件攻城狮来说就是25pin,多条数据线,控制线和地,0~5V电平,多用于数据输出接打印机扫描仪等,数据传输速率高。
因此,使用TTL接口时,路由器被视为主机,计算机则是作为提供输入输出的显示器和键盘的外围设备。使用JTAG接口时,计算机是主机,路由器是被控制的外围设备。
最后,我们选择的是TTL接口。硬件攻城狮首先在路由器的TTL接口(和JTAG接口)上焊接了双排插针。
选购USB-TTL刷机线,建立调试环境
熟悉TTL接口的知识以后,下一步就是上某宝购买TTL接口线。我们公司一直在某宝上购买硬件设备,尤其是这类小接口。一般来说,不要选最便宜的,如果一个芯片10元左右,你要是买个10元左右的板子……只能祝福您了,相信您能从中学到很多经验和知识,呵呵。
收到模块后,仔细阅读说明书,安装USB驱动。将USB插入计算机,在系统中查看USB串口的端口号,一般是COM3。
下载并运行串行通讯软件。我选用的是putty。SecureCRT也可以,但这是付费软件。实际上windows的超级终端也可以。
设置端口为Serial COM3,速率为115200,N81。速率如果设置错了,收到的信息显示为乱码,试试改成9600/14400/57600等。
wrt54g有两个TTLL串口,分别为:
-
串口1, uart0,pin 4/6/10
-
串口2, uart1,pin 3/5/9
我的路由器上用的是串口1。用杜邦线连接串口模块和wrt54g上对应的双排插针。注意不要连接到3.3v/5v的电源脚。
路由器上电,在USB-TTL转换板上能看到RX灯闪烁,putty的窗口上显示接收到的数据。若无反应,拔掉路由器电源,换一个路由器串口重新接线试试。
再次拔掉/插入路由器电源,注意观察putty窗口上显示的数据。
wrt54g是一台嵌入式的Linux主机
此时感觉就很不一样了!wrt54g不再只是一个黑匣子,而是一台“主机”,透过运行在计算机上的putty和TTL连线,我们有了“显示器”,“键盘”,它还有操作系统——Linux,硬盘——Flash芯片,文件系统,串口,网卡等等。
路由器上电以后首先启动CFE(Common Firmware Environment),然后启动Linux操作系统。
CFE相当于计算机上的BIOS,ntldr,grub for dos,common.com,是路由器的Boot loader。以下为CFE的刷屏:
CFE version 1.0.37 for BCM947XX (32bit,SP,LE)
Build Date: Tue Aug 7 17:14:08 CST 2007 (crazy@sw1.rd)
Copyright (C) 2000,2001,2002,2003 Broadcom Corporation.
Initializing Arena
Initializing Devices.
No DPN
et0: Broadcom BCM47xx 10/100 Mbps Ethernet Controller 3.90.37.0
CPU type 0x29008: 200MHz
Total memory: 16384 KBytes
Total memory used by CFE: 0x80300000 - 0x803A39B0 (670128)
Initialized Data: 0x803398C0 - 0x8033BFD0 (10000)
BSS Area: 0x8033BFD0 - 0x8033D9B0 (6624)
Local Heap: 0x8033D9B0 - 0x803A19B0 (409600)
Stack Area: 0x803A19B0 - 0x803A39B0 (8192)
Text (code) segment: 0x80300000 - 0x803398C0 (235712)
Boot area (physical): 0x003A4000 - 0x003E4000
Relocation Factor: I:00000000 - D:00000000
Boot version: v3.7
The boot is CFE
mac_init(): Find mac [00:06:25:00:02:DB] in location 0
Nothing...
No eou key find
Device eth0: hwaddr 00-06-25-00-02-DB, ipaddr 192.168.1.1, mask 255.255.255.0
gateway not set, nameserver not set
Loader:raw Filesys:raw Dev:flash0.os File: Options:(null)
Loading: .. 5192 bytes read
Entry at 0x80001000
Closing network.
Starting program at 0x80001000
显然,半砖路由器的CFE启动正常,运行Linux(Starting program at 0x80001000)即挂死。
短接Flash芯片的16、17脚导致CFE读取Linux的image文件异常,不停地显示:
Reading :: Failed.: Timeout occured
路由器被停在了CFE中。如果CFE中有tftp服务程序,高版本的CFE还有web服务程序,那么,您此时可以在计算机上用tftp刷机或者用浏览器刷机。
但说好的tftp和web在这台路由器的CFE中——并不存在,CFE版本low至3.7。二位攻城狮以各种时间序列凹出各种造型,然都没有用。
好消息是CFE打开了网络口,正常,直到退出CFE。在计算机侧输入命令:
ping 192.168.1.1 -t
是成功。
玩不坏的 CFE
拔掉路由器电源。
在计算机上激活putty终端窗口,左手放在键盘的Ctrl C
上。
右手插入路由器电源,电源接通后,左手立刻按下Ctrl C
——中断CFE的自动运行命令,进入CFE命令环境。
putty上显示:
No eou key find
Device eth0: hwaddr 00-06-25-00-02-DB, ipaddr 192.168.1.1, mask 255.255.255.0
gateway not set, nameserver not set
Automatic startup canceled via Ctrl-C
CFE> ^C
CFE> ^C
CFE>
- ^C,就是我们在计算机上按
Ctrl C
此即进入 CFE 命令模式。在计算机键盘输入help
,回车:
CFE> help
Available commands:
rndis Broadcom USB RNDIS utility.
et Broadcom Ethernet utility.
modify Modify flash data.
nvram NVRAM utility.
reboot Reboot.
flash Update a flash memory device
memtest Test memory.
f Fill contents of memory.
e Modify contents of memory.
d Dump memory.
u Disassemble instructions.
autoboot Automatic system bootstrap.
batch Load a batch file into memory and execute it
go Verify and boot OS image.
boot Load an executable file into memory and execute it
load Load an executable file into memory without executing it
save Save a region of memory to a remote file via TFTP
ping Ping a remote IP host.
arp Display or modify the ARP Table
ifconfig Configure the Ethernet interface
show devices Display information about the installed devices.
unsetenv Delete an environment variable.
printenv Display the environment variables
setenv Set an environment variable.
help Obtain help for CFE commands
For more information about a command, enter 'help command-name'
*** command status = 0
-
command status, 命令返回状态,0表示没有出现错误。
-
reboot, Reboot. 重启动路由器。
-
flash, Update a flash memory device. 刷固件
在计算机键盘输入show devices
,回车:
CFE> show devices
Device Name Description
------------------- ---------------------------------------------------------
uart0 NS16550 UART at 0x18000300
uart1 NS16550 UART at 0x18000400
flash0.boot New CFI flash at 1C000000 offset 00000000 size 256KB
flash0.trx New CFI flash at 1C000000 offset 00040000 size 1KB
flash0.os New CFI flash at 1C000000 offset 0004001C size 3808KB
flash0.nvram New CFI flash at 1C000000 offset 003F8000 size 32KB
flash1.boot New CFI flash at 1C000000 offset 00000000 size 256KB
flash1.trx New CFI flash at 1C000000 offset 00040000 size 3808KB
flash1.nvram New CFI flash at 1C000000 offset 003F8000 size 32KB
flash0 New CFI flash at 1C000000 size 4096KB
eth0 Broadcom BCM47xx 10/100 Mbps Ethernet Controller
*** command status = 0
-
uart0 传说中的串口,就是我们的TTL线连接的那个接口。
-
flash0.boot, size 256KB ROM中的CFE文件。flash0 开头的都是ROM文件,刷不进去,只能读不能写。
-
flash1.boot, size 256KB RAM中的CFE文件。flash1 开头的都是RAM文件,可以刷。忍耐克制……不要刷CFE,CFE要是被刷坏了,只能自制JTAG了。当然,这也意味着没有TTL或JTAG,CFE就不会被刷坏,因为刷不到它头上,除非Flash芯片坏了。
-
flash1.trx, size 3808KB 传说中的固件(Firmware),即Linux操作系统的image。这个路由器就“砖”在这个文件上——被刷错了,运行即挂。
-
flash1.nvram,size 32KB 配置文件。一般在刷机前和刷机后都要将其设置成缺省值——俗称清理nvram。
在计算机键盘输入printenv
,回车:
CFE> printenv
Variable Name Value
-------------------- --------------------------------------------------
BOOT_CONSOLE uart0
CFE_VERSION 1.0.37
CFE_BOARDNAME BCM947XX
CFE_MEMORYSIZE 16384
NET_DEVICE eth0
NET_IPADDR 192.168.1.1
NET_NETMASK 255.255.255.0
NET_GATEWAY 0.0.0.0
NET_NAMESERVER 0.0.0.0
STARTUP go;
*** command status = 0
- BOOT_CONSOLE, uart0 所以TTL线要接在路由器的串口1上。
在计算机键盘输入nvram show
,回车:
CFE> nvram show
opo=0x02
os_ram_addr=80001000
boardrev=0x10
il0macaddr=00:90:4c:5f:00:2a
bootnv_ver=4
et0macaddr=00:06:25:00:02:DB
boot_wait=off
watchdog=5000
et0mdcport=0
pmon_ver=CFE 3.91.37.0
vlan0ports=3 2 1 0 5*
os_flash_addr=bfc40000
sromrev=2
boardtype=0x0467
lan_netmask=255.255.255.0
wl0id=0x4320
ag0=0x02
wl0gpio2=0
wl0gpio3=0
boardflags2=0
pa0itssit=62
cctl=0
pa0maxpwr=0x4e
clkfreq=200
lan_ipaddr=192.168.1.1
vlan1hwname=et0
aa0=3
sdram_config=0x0062
vlan1ports=4 5
scratch=a0180000
ccode=0
boardflags=0x2558
sdram_refresh=0x0000
sdram_ncdl=0xfe0008
et0phyaddr=30
pa0b0=0x168b
pa0b1=0xfabf
pa0b2=0xfeaf
sdram_init=0x010b
vlan0hwname=et0
dl_ram_addr=a0001000
boot_ver=v3.7
boardnum=42
size: 700 bytes (32068 left)
*** command status = 0
-
boot_wait=off,启动等待,关闭。
-
boot_ver=v3.7,CFE版本号。
用CFE命令刷入firmware
在计算机键盘输入flash
,回车:
CFE> flash
flash [options] filename [flashdevice]
Copies data from a source file name or device to a flash memory device.
The source device can be a disk file (FAT filesystem), a remote file
(TFTP) or a flash device. The destination device may be a flash or eeprom.
If the destination device is your boot flash (usually flash0), the flash
command will restart the firmware after the flash update is complete
-noerase Don't erase flash before writing
-offset=* Begin programming at this offset in the flash device
-size=* Size of source device when programming from flash to flash
-ctheader Check header of CyberTAN
-noheader Override header verification, flash binary without checking
先熟悉以下flash命令。
如果将路由器设置为tftp服务器,计算机侧运行客户端上传到路由器,命令如下(未测试,后果自负):
flash -noheader : flash1.trx
而我计划在计算机侧开tftp服务器,路由器侧用tftp客户端到计算机上获取(get)固件。
把Tomato的固件文件名Tomato-1.28.2890-R1-4M.trx
换成简单的,例如128.bin
。
计算机侧设置好了以后,在putty窗口中输入命令:
CFE> flash -noerase -noheader 192.168.1.2:128.bin flash1.trx
Reading 192.168.1.2:128.bin: Done. 3665920 bytes read
fname=(null)
Programming...done. 3665920 bytes written
**Exception 8: EPC=80313388, Cause=00008008 (TLBMissRd)
RA=8031C618, VAddr=00000000
0 ($00) = 00000000 AT ($01) = 80340008
v0 ($02) = 00000066 v1 ($03) = 00000000
a0 ($04) = 00000000 a1 ($05) = 80337174
a2 ($06) = 00000000 a3 ($07) = 00000066
t0 ($08) = 00000000 t1 ($09) = 8033D840
t2 ($10) = 00000000 t3 ($11) = 00000005
t4 ($12) = B8000000 t5 ($13) = 000000A0
t6 ($14) = 00000055 t7 ($15) = 000000AA
s0 ($16) = 00000002 s1 ($17) = 80345000
s2 ($18) = 803A3608 s3 ($19) = 80345030
s4 ($20) = 00000000 s5 ($21) = 00000000
s6 ($22) = 00000000 s7 ($23) = 00000003
t8 ($24) = 01000000 t9 ($25) = 00000000
k0 ($26) = 2E323931 k1 ($27) = 00322E31
gp ($28) = 803418C0 sp ($29) = 803A3550
fp ($30) = 00000001 ra ($31) = 8031C618
-
noerase, 写入flash之前不擦除
-
ctheader, 检查文件头
-
noheader, 不检查文件头,直接覆盖
-
filename, 源文件,格式为
host:path/firmware.binformat.
。 -
host, 192.168.1.2, 运行tftpd服务程序的计算机地址
-
firmware.binformat, 128.bin, 获取的固件文件。path为空,即128.bin与tftpd在同一目录下。
-
flash1.trx, 路由器上的目标文件。详见
show devices
命令。
正当我看到Exception以为刷机失败的时候,putty显示了大量的信息,似乎重启动了两次,最后路由器竟然——快活地正常启动了。
立刻在计算机侧登录路由器的web管理界面,设置配置为缺省值(清理mvram)。
最后上一张计算机侧的大图:点我查看
参考链接: