Hacking into Xiaomi Mi Router 3G and OpenWrt Firmware

Having heard about the recent OpenWrt and LEDE projects merge back and unification under the OpenWrt name and the new rules taken from LEDE, we think it’s a good time to update firmware on your devices, as they are going to switch off old OpenWrt releases support in the near future.


Also, having one of the new cheap but quite powerful Xiaomi Mi Router 3G devices on hands, we found it to be a good opportunity to try it out, as its original “Made in China” firmware is based on the old OpenWrt as well. So, I took my time and opened the router shield. That’s the beautiful internals I discovered:

First step to work with that kind of devices is to get full read+write control over the memory. That’s usually done by booting it into the service mode and the best way to do it is to have the UART connection to it. Luckily, there are connectors for that on the board, but unfortunately they are not soldered. So, first of all I had to get at least 3 pins and solder them into the RX/TX/GND hookups. Well, that’s exactly what I did and here is the result of my hand-making:

Looks nice as now I can connect the board to the PC with an USB to Serial UART converter module! The only challenge here that I came across was… both of my CP2102/RS232 modules were found dead under unclear circumstances. But if you’re like me, that’s not a problem if you have one of that awesome Arduino boards as it has a built-in UART converter module on-board! All you have to do to use it is to connect RESET pin to GND pin with a “jumper” cable…

… and now you can hook up Arduino RX to the router RX and Arduino TX to the router TX. Yeah, not the RX<->TX cross-connection as we usually do with the conversion boards… For some reason Arduino has them already swapped. Another warning is – NEVER connect the V+ pin on the router board to the voltage input. The router must be powered with the separate supply that came with the board and there should be no any other power source. So, that’s what we have now:

Arduino pin# mi 3g pin#
0 (RX) 2 (Green/RX)
1 (TX) 4 (White/TX)
GND 3 (Black/GND)

Now, once Arduino board is connected to the PC, the new USB port should appear (in my case, /dev/ttyUSB0) and we can use any TTY COM application (cu, minicom, screen, putty etc.) at the baud rate equal to 115200  to see what’s going on with the UART port and send commands there. I just started the cu program:

$ cu -l /dev/ttyUSB0 -s 115200

When ready, just power up the router board and you should see its loading output similar to this:

In a second or so, the boot menu will appear! Just like on the multi-boot PC! Nice, isn’t it?

So, what we are interested in is the command line interface. All we have to do is type “4” and it will be loaded for us. Booting in that mode will grant us a full access to all segments of the board memory through the /dev/md* files. Now, there can be only one right first-thing-to-do once this point is reached – of cause it’s to back up everything that’s already in there! I used a USB flash drive for that. Basically mount it, switch to it and copy full memory dumps there:

$ mount /dev/sda1/ /extdisks/sda1

$ cd /extdisks/sda1

$ for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13; do cat /dev/mtdblock$i > mtdblock$i.bin; done

Now, we finally can write the OpenWrt firmware. I’ve got my images from


If for some reason you still need the LEDE images, as of March 2018 they are still available here:


Once they are copied on the same USB drive and the drive is mounted on the router, we can use the mtd tool to flush them into the device:

$ mtd write lede-ramips-mt7621-mir3g-squashfs-kernel1.bin kernel1

$ mtd write lede-ramips-mt7621-mir3g-squashfs-rootfs0.bin rootfs0

$ mtd erase kernel0

$ reboot

That’s it! Now the router will boot into the brand new firmware. My suggestion is to connect it with the wan port (marked with blue plastic) to DHCP-enabled network and connect your PC to any of the remaining ports to control it. As usually, you can access it with the IP via the telnet protocol.

Do not forget to set the root password and switch to ssh access on first login. And after that full-functional GNU/Linux distro with the opkg package manager is available to you!

Also, do not be surprised to see the 4 CPU kernels on that little board.

It’s actually only 2 real ones, the other are only Multi-Threading ARM feature (Intel’s Hiber-Threading analog). Anyway, it has a lot of power to be used in any type of project that you want from that little box.

Hope, that article can grow interest to the open-source firmware and software in general. And I’ll be glad if it helps someone. In the next topic, I’ll share the first setup steps and my small research on an unexpected behavior that I came across with while setting up the router for a real-world usage.