緣起:路由器被刷成半磚
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)。
最后上一張計算機側的大圖:點我查看
參考鏈接: