Zobrazují se příspěvky se štítkemtp-link. Zobrazit všechny příspěvky
Zobrazují se příspěvky se štítkemtp-link. Zobrazit všechny příspěvky

čtvrtek 2. října 2014

TP-Link recovery

Flashing routers with custom firmware if fun. Especially a firmware compiled by yourself. But it may occur that things goes wrong and you will brick you router. If you have untouched a bootloader, unbricking process is really easy.

This article is about unbricking routers with working bootloader, in this case a TP-Link TL-WR703N which is using U-Boot. If your router has other bootloader, following procedure probably will not work.

For recovery you must have access to device serial console. I'm using a Debian machine.

Get information about your memory

To safely brick your device, you have to perform some terrain reconnaissance. You have to know how flash memory of your router looks like and which blocks can be rewritten without causing serious damage to device functionality.

Flash memory is divided into parts like hard drive is partitioned in traditional computers. But in this case, we are not dealing with hard drive and real partitions, but with mtd and named memory offsets instead. That means that these “partitions” doesn't contains any meta data about them, can overlap each other and also writing operations can overrun their boundaries.

Let's look how many partitions are there and how long they are.

root@OpenWrt:/# cat /proc/mtd 
dev:    size   erasesize  name 
mtd0: 00020000 00010000 "u-boot" 
mtd1: 00102050 00010000 "kernel" 
mtd2: 002cdfb0 00010000 "rootfs" 
mtd3: 000c0000 00010000 "rootfs_data" 
mtd4: 00010000 00010000 "art" 
mtd5: 003d0000 00010000 "firmware"

Ok, there are six partitions. Surely at the zero offset starts “u-boot” partition, because this one contains bootloader, which is executed at first, when device is turned on. With the rest we can only guess for now, where they are placed.

You can get more complete view, how they are arranged by checking boot log.

root@OpenWrt:/# dmesg

This command spits out lot of output, but we are looking for something like this.

[    0.490000] 5 tp-link partitions found on MTD device spi0.0 
[    0.490000] Creating 5 MTD partitions on "spi0.0":
[    0.500000] 0x000000000000-0x000000020000 : "u-boot" 
[    0.510000] 0x000000020000-0x000000122050 : "kernel" 
[    0.520000] 0x000000122050-0x0000003f0000 : "rootfs" 
[    0.550000] 0x000000330000-0x0000003f0000 : "rootfs_data" 
[    0.560000] 0x0000003f0000-0x000000400000 : "art" 
[    0.560000] 0x000000020000-0x0000003f0000 : "firmware" 

Nice, now we have exact position of each individual region, so we can set up complete view.

Regions which have to be untouched are u-boot and art. There contains critical data to keep device working. Firmware partition between them can be rewritten as you like.

Make a brick

First step is bricking a device. You probably will not do that intentionally but it can happen. For example by flashing a file, which you shouldn't.

root@OpenWrt:/# cd /tmp
root@OpenWrt:/tmp# wget http://192.168.1.1/openwrt-ar71xx-generic-root.squashfs
root@OpenWrt:/tmp# mtd -r write openwrt-ar71xx-generic-root.squashfs firmware

Yes, this is how I bricked my TP-Link. I build image which was too large and therefore factory.bin file doesn't appear in my bin directory. I didn't realized that problem, so I tried another file and it of course didn't work.

openwrt-ar71xx-generic-root.squashfs is only file with filesystem. It is really not good idea to flash it at the firmware offset. If you want to browse its content, you can install squashfs-tools package and extract it.

buben@debian:~$ unsquashfs openwrt-ar71xx-generic-root.squashfs
buben@debian:~$ ls squashfs-root/ 
bin  dev  etc  lib  mnt  overlay  proc  rom  root  sbin  sys  tmp  usr  var  www

Issued command mtd above rewrites only mtd5 partition, where firmware is located, so mtd0 with bootloader leave untouched and fully working.

There is one big catch. If you write bigger file than 3904 KiB, you will rewrite also mtd4. In this location it stored calibration data for your wireless hardware and it is device specific. If you don't have backup of art for restore, your router can't use WiFi anymore.

Principe

In normal conditions, when device is turned on, first what is executed is a bootloader. Bootloader perform some hardware check, known as POST, copies kernel into RAM and executes it. When firmware is broken, router restart itself and these things are repeated in infinite loop.

Some bootloaders, such as U-Boot, have implemented rescue mechanisms, for example loading new firmware using TFTP.

Install TFTP server

For installing TFTP server in Debian machine, issue following command.

buben@debian:~$ sudo apt-get install tftpd-hpa

For security reasons, I recommend you to disable automatic starting of the server during the boot time. It is aways good idea to use some service only when you need it and not keep it running for all the time.

buben@debian:~$ sudo update-rc.d -f tftpd-hpa remove

Now all init scripts for tftpd-hpa are removed, but service is still running. You can test it by following command

buben@debian:~$ sudo service tftpd-hpa status 
[ ok ] in.tftpd is running.

Serial console

As I mentioned at the beginning, you need working serial console. My favorite program is minicom.

buben@debian:~$ sudo apt-get install minicom

To use it as a regular user, you have to be in dialout group.

buben@debian:~$ sudo usermod -a -G dialout buben

After that command you have to relog your account to take the effect.

After that you can connect to device.

buben@debian:~$ minicom -D /dev/ttyUSB0 -b 115200

On my bricked router, I have got the following output repeating over and over.

U-Boot 1.1.4 (Mar 18 2013 - 17:36:20) 

AP121 (ar9330) U-boot 

DRAM:  32 MB 
led turning on for 1s... 
id read 0x100000ff 
flash size 4194304, sector count = 64 
Flash:  4 MB 
Using default environment 

In:    serial 
Out:   serial 
Err:   serial 
Net:   ag7240_enet_initialize... 
No valid address in Flash. Using fixed address 
No valid address in Flash. Using fixed address 
: cfg1 0x5 cfg2 0x7114 
eth0: 00:03:7f:09:0b:ad 
ag7240_phy_setup 
eth0 up 
: cfg1 0xf cfg2 0x7214 
eth1: 00:03:7f:09:0b:ad 
athrs26_reg_init_lan 
ATHRS26: resetting s26 
ATHRS26: s26 reset done 
ag7240_phy_setup 
eth1 up 
eth0, eth1 
Autobooting in 1 seconds 
## Booting image at 9f020000 ... 
   Uncompressing Kernel Image ... Too big uncompressed streamLZMA ERROR 1 - must RESET

Uploading new firmware

At first, copy your working firmware file into tftpd directory.

buben@debian:~$ sudo cp openwrt-ar71xx-generic-tl-wr703n-v1-squashfs-factory.bin /srv/tftp/firmware

Link your computer with the router using ethernet cable and turn it on. U-Boot can be configured for another remote address where it expects TFTP server, default address is 192.168.1.100.

buben@debian:~$ sudo ifconfig eth0 192.168.1.100

Power on your router and type “tpl” into serial console during boot. You should get rescue hornet prompt.

hornet>
hornet> help 
?       - alias for 'help' 
bootm   - boot application image from memory 
cp      - memory copy 
erase   - erase FLASH memory 
help    - print online help 
md      - memory display 
mm      - memory modify (auto-incrementing) 
mtest   - simple RAM test 
mw      - memory write (fill) 
nm      - memory modify (constant address) 
printenv- print environment variables 
progmac - Set ethernet MAC addresses 
reset   - Perform RESET of the CPU 
setenv  - set environment variables 
tftpboot- boot image via network using TFTP protocol 
version - print monitor version

Now we are ready to upload new image into the device.

Following command contains memory offsets which I leave unexplained for now. These are basically addresses into memory and they are platform dependent (TL-WR703N uses MIPS architecture processor).

Download image file from remote server.

hornet> tftpboot 0x81000000 firmware 
dup 1 speed 1000 
Using eth1 device 
TFTP from server 192.168.1.100; our IP address is 192.168.1.111 
Filename 'firmware'. 
Load address: 0x81000000 
Loading: ################################################################# 
         ################################################################# 
         ################################################################# 
         ################################################################# 
         ################################################################# 
         ################################################################# 
         ################################################################# 
         ################################################################# 
         ################################################################# 
         ################################################################# 
         ################################################################# 
         ###################################################### 
done 
Bytes transferred = 3932160 (3c0000 hex)

Then erase memory where firmware will be stored.

hornet> erase 0x9f020000 +0x3c0000 

First 0x2 last 0x3d sector size 0x10000 
  61 
Erased 60 sectors

Copy firmware into cleaned memory. Notice “cp.b” command. Cp takes three arguments, first is source memory offset, second is destination offset and third one is count of units. By default, cp takes one unit of long word (32 bits), cp.b is a byte version of copy. Tftpboot command above tells us, that 3932160 bytes were transferred (3c0000 in hex), so let's copy them into flash memory.

hornet> cp.b 0x81000000 0x9f020000 0x3c0000 
Copy to Flash... write addr: 9f020000 
done

Now you can restart the router or boot system by following command.

hornet> bootm 9f020000

Now your router should work again.

At the end, remember to stop TFTP server.

buben@debian:~$ sudo service tftpd-hpa stop

středa 23. října 2013

Installing OpenWRT on TP-Link router

It is some time, when I started experimenting with OpenWRT - an operating system for routers. It starts as a school project, when I had to write an article about operating systems for embedded devices.

OpenWRT is Linux based operating system. It is completely open source with a large community. Also it has huge list of supported devices. You can find more information on the official page.

Hardware

OpenWRT supports lot of procesor architectures, so it can run basically on anything. Except few devices which has not enough resources, such as flash storage or RAM.

I chose very popular TP-LINK TL-WR703N. It is very small and cost about 22 USD. It has 4 MB of flash, 32 MB RAM and MIPS architecture CPU at 400 MHz. It also supports 802.11n wireless standard and has one USB host port.

Serial console

If you are working with some embedded device, it is always good idea to have serial console. It is very handy for its management and configuration and really necessary for device rescue, if something goes wrong.

Every TP-Link router what I met has nice unpopulated PCB header with UART, providing serial console. But because this router is really small, it has only little pads with RX and TX (labeled TP_IN and TP_OUT).

You can find lot of tutorials on the Internet about accessing serial console. But basically each of them requires making holes into PCB for soldering pins or some other invasive method. I solved this by gluing 3-pin header with a hot glue on the back side of the Ethernet connector. Then I just connected RX and TX wires and third wire to the ground.

Identify a target

If your device is listed in supported devices, look at the device target. In case of TL-WR703N, target is ar71xx. If you are not sure about right target of your device, please look at this table. Target is based on the router chipset, not only on the processor's architecture. But let's suppose that you have device supported by OpenWRT.

Filesystem

Next you have to decide, which filesystem you want. There are two basic options.

  • JFFS2 – writable compressed filesysem. It supports wear leveling and journaling. Compressed with LZMA compression.
  • SquashFS – read-only filesystem compressed with LZMA. It is used in conjunction with overlayfs. In the result, there are two filesystems merged into one. This mechanism is called UnionFS. Lower one is read-only SquashFS and upper one is writable JFFS2.

I prefer two layered filesystem. It's writable and any changes can be easily restored into default state by erasing upper layer.

Please note, that SquashFS shouldn't be used on the NAND flash storage. If your router has NAND flash, you have to use another filesystem.

Installation

After determining correct target and identifying your needs, installation is really simple. Fist download image file. In my case it is http://downloads.openwrt.org/attitude_adjustment/12.09/ar71xx/generic/openwrt-ar71xx-generic-tl-wr703n-v1-squashfs-factory.bin

On most devices (and TL-WR703N isn't exception) you simply can access web interface and upload firmware image into appropriate upgrade form.

First of all, you have to connect to the router. I prefer wired connections. Most devices are configured with some reasonable address. You can read manual or simply guess it.

buben@debian:~$ sudo ifconfig eth0 192.168.1.10
buben@debian:~$ ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 
64 bytes from 192.168.1.1: icmp_req=1 ttl=255 time=1.48 ms 
64 bytes from 192.168.1.1: icmp_req=2 ttl=255 time=3.09 ms 
64 bytes from 192.168.1.1: icmp_req=3 ttl=255 time=1.40 ms 
64 bytes from 192.168.1.1: icmp_req=4 ttl=255 time=2.02 ms

In my case, I had to use crossover cable. If you can't ping a device, make sure that this is not an issue.

I bought my TP-Link on ebay and it came with Chinese localization. I didn't have character sets installed for displaying page correctly. But it is not hard to find firmware upload form, even if I can't read basicaly anything.

Main menu in on the left side. The last item should be system management. After clicking on it, another sub-menu appears.

Menu items are nothing more than links. If you move a mouse on the link, most browsers will show you its location. Third menu item should be, what I'm looking for (mouse cursor isn't captured on the screenshot).

Before you upload an image file to the form, it's not bad idea to rename it to some short name. Also the file should have .bin suffix. In my case a file name length have to be up to 64 characters long and .bin suffix is also required.

buben@debian:~$ mv openwrt-ar71xx-generic-tl-wr703n-v1-squashfs-factory.bin openwrt.bin

Next select image file and submit it.

Firmware upgrade is most critical step in this process. Don't unplug a power source for your router. If you will do so, you will brick it. Brick can be restored, but I have no experience with that.

After successful flashing, you can access a serial console a see nice welcome message.

BusyBox v1.19.4 (2013-03-14 11:28:31 UTC) built-in shell (ash)
Enter 'help' for a list of built-in commands.

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 ATTITUDE ADJUSTMENT (12.09, r36088)
 -----------------------------------------------------
  * 1/4 oz Vodka      Pour all ingredients into mixing
  * 1/4 oz Gin        tin with ice, strain into glass.
  * 1/4 oz Amaretto
  * 1/4 oz Triple sec
  * 1/4 oz Peach schnapps
  * 1/4 oz Sour mix
  * 1 splash Cranberry juice
 -----------------------------------------------------
root@OpenWrt:/#