This page describes hacking of TP-Link MR3220 and running Debian on it. The procedure of running Debian can be used on other similar devices too.
TP-Link MR3220 is a very cheap (500 CZK or $30) device featuring
With original firmware, it is usable as a soho wifi router, however, you can run full-featured linux distro (Debian) on it!
It's easy, just download the prebuilt firmware (local mirror of a tested build from 2011-10-27), go to web admin, upload and wait a minute.
opkg install ip opkg install usbutils opkg install kmod-usb-storage opkg install kmod-fs-ext4
If you brick your system, you can always debug it with a serial port or boot fresh working image.
Serial port communicates on 3.3V TTL levels and the pinout is described here. It is a bit difficult to solder GND, because that small pin is directly connected with the big groundplate, so take GND somewhere else.
Configuration of Minicom is
pu port /dev/ttyUSB0 pu baudrate 115200 pu rtscts No
Then power on your device. When Autobooting in 1 seconds
appears, type tpl
as fast as possilbe (try it multiple times :-). Hooray, you are in an U-Boot prompt!
Connect to LAN interface and set up a TFTP server on 129.168.1.27/24. Enter to U-Boot:
tftpboot 0x81000000 filename_on_the_tftp_server # download file to specified address in RAM bootm 0x81000000 # fire it!
If you want to write this new firmware to flash, use
erase 0x9f020000 +0x3c0000 # erase old firmware tftpboot 0x81000000 filename_on_the_tftp_server # download file to specified address in RAM cp.b 0x81000000 0x9f020000 0x3c0000 # copy it from RAM to flash
We can connect mass-storage device with installed Debian and run it on this device!
Debian-MIPS binaries require CONFIG_MIPS_FPU_EMU in Linux kernel. However, default openWRT kernels don't have this support. You can either build your own image (make kernel_menuconfig
and Enable FPU emulation
on the first screen) or download my prebuilt image (warning: it is compiled without IPv6 and kernel crypto support, so you probably don't want to use it in production environment!).
Then flash your firmware and install "must-have" packages specified above (ip usbutils kmod-usb-storage kmod-fs-ext4). Create an ext2/3/4 partition on your USB storage (300 MB for minimal system, 1 GB recommended) and try to mount it on your WRT device.
You can also download my system image. Use it this way: tar xvf debian_mips.tar.bz2 --strip-components=2
We are going to prepare the system on an Intel 486 desktop machine. However, our WRT device is MIPS.
Start with debootstrap as usual
debootstrap --foreign --arch=mips squeeze /some/where http://debian.sh.cvut.cz/debian/
Debootstrap will unpack some packages and then fail on chroot. Now mount the /some/where dir on your target machine and
mount -o bind /dev /mnt/dev mount -t proc none /mnt/proc chroot /mnt/some/where /bin/bash for f in /var/cache/apt/archives/*.deb; do dpkg --unpack --force-all $f; done dpkg --configure -a
After editing sources.list
and apt-get update
, you should be able to install Debian packages as usual. Install a SSH server. But remember, we are still chrooted.
I decided to mod the openWRT init system do automatically chroot to Debian after booting. I then created my own init in the Debian chroot.
First disable all services in openWRT. The /etc/rc.d/ dir should look like this
root@rubisco:/# ls /etc/rc.d/ K40network K50dropbear K90network K99umount S39usb S97watchdog K45firewall K50telnet K98boot S05defconfig S95done S99sysctl K50cron K60dnsmasq K98sysntpd S10boot S96led
Then edit /etc/rc.local
# Put your custom commands here that should be executed once # the system init finished. By default this file does nothing. date -s @1320792150 while [ ! -b /dev/sda1 ]; do date >> /tmp/log date sleep 1 done mount /dev/sda1 /mnt mount -o bind /dev /mnt/dev mount -t proc none /mnt/proc chroot /mnt /myinit exit 0
We don't want root automatically logged on ttyS0, so create a login script and put appropriate line to inittab
#!/bin/ash while read foo; do if [ "x$foo" == xbrm ]; then /bin/ash --login fi sleep 1 done ttyS0::askfirst:/bin/login
I use homebrew init /myinit in the target Debian system.
#!/bin/dash mount -t sysfs none /sys /etc/init.d/udev start sleep 3 hostname rubisco.hrach.eu dhclient eth1 /etc/init.d/ssh start mount -a /etc/init.d/cron start mount /dev/pts ntpdate europe.pool.ntp.orgif problems with /dev/pts/ appear when you try to SSH in, try
ssh root@machine "/bin/bash -i"
Maybe /var/log, lock, tmp to ramdisk? ext2/3 commit=1200?
There we go…
echo 0 > /sys/class/leds/tl-mr3x20\:green\:qss/brightness echo 1 > /sys/class/leds/tl-mr3x20\:green\:qss/brightness
factory NVRAM factory firmware