用TTL线在CFE环境下拯救半砖wrt54g路由器

缘起:路由器被刷成半砖

Linksys wrt54gs v4路由器,已刷入 tomato-dualwlan 1.23。使用数年,未出现任何故障。

在日用的wifi网络上,通过web界面刷入了错误的tomato-dualwlan的 R2 firmware。

路由器毫无意外地挂了。后查资料得知,以上的每一步都有风险,选错firmware则是致命的。

正确的刷机过程是:

  1. 路由器和刷机用的计算机脱离日用网络。用一根网线(有线而不是无线)链接路由器和计算机,组成一个干净的微型网络。

  2. 计算机上设置固定的ip地址。

  3. 刷机前进入路由器配置界面恢复缺省值。

  4. 仔细查看资料,确认正确的固件。如有任何疑问,放弃是理性的选择。

  5. 选择头脑清醒的时间,在适合工作的场所,跟懂技术的朋友交流讨论,不要喝酒……

唯一的好消息是路由器处于半砖状态。所谓半砖是指路由器的CFE(相当于计算机的BIOS)工作正常。
CFE只能通过JTAG刷,不用JTAG就刷不坏(其实用TTL线也可以更新CFE,这是后话)。

也就是说,此时的路由器相当于一台没有接显示器和键盘,有硬盘(flash芯片),
但操作系统已经不能正常工作的计算机。

devices

故障现象

插入电源后,全部灯亮,迅速熄灭,仅留下插网线的端口所对应的灯亮。

用计算机 ping 不通。该计算机已设置为:

	地址:192.168.1.2
	子网:255.255.255.0
	网关:192.168.1.1

tftp刷机失败

既然无法 ping 通,说明计算机无法与路由器建立TCP连接,那么,web界面肯定用不了。

下一步只能尝试tftp刷机。tftp ,顾名思义是基于网络ftp的协议。理论上有两种方式上传新的 firmware 固件:

  1. 路由器开tftp服务程序,操作计算机运行tftp客户端上传文件。

  2. 计算机开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命令的结果有两个:

  1. Invalid code partern

  2. Timeout

根据网路上的案例,前者是文件头不对,后者是tcp链接失败。

于是,在网络上搜索各种固件。固件的文件头有两个:

  1. 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
    
  2. 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的文件头呢?

操作结果是两种文件头都试过了,都没有成功。

分析问题,提出新的技术方案

经过多次刷机失败以后,攻城狮们放弃了……坐下来认真分析。

  1. 路由器上电后,网络链接并未建立。在 Linux 中这通常意味着驱动出错,或者网络被关闭。

  2. 无法确认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元左右的板子……只能祝福您了,相信您能从中学到很多经验和知识,呵呵。

六合一多功能串口模块CP2102

收到模块后,仔细阅读说明书,安装USB驱动。将USB插入计算机,在系统中查看USB串口的端口号,一般是COM3。

com3

下载并运行串行通讯软件。我选用的是putty。SecureCRT也可以,但这是付费软件。实际上windows的超级终端也可以。

putty-com3

putty-com3

设置端口为Serial COM3,速率为115200,N81。速率如果设置错了,收到的信息显示为乱码,试试改成9600/14400/57600等。

wrt54g的TTL串口插座

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)固件。

tftp-server

把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)。

最后上一张计算机侧的大图:点我查看


参考链接:

  1. http://wiki.openwrt.org/doc/techref/bootloader/cfe

  2. http://xinu.mscs.mu.edu/Common_Firmware_Environment

  3. HG320路由器盲刷64K CFE NVRAM固件

  4. nw755刷第三方固件测试

  5. 详解wr841n刷三方固件及变砖后如何用TTL口修复

posted @ 2015-10-11 00:26  ccpaging  阅读(18162)  评论(2编辑  收藏  举报