Lately I’ve been experimenting with OpenWRT firmware on my Mercusys MR70X router. After some playing around, I’ve decided to flash the OEM firmware back without reading the guides. Instant brick and regret followed.
Broken (and fixed) things
Bad Magic Number
01221: the firmware software version dismatched
(not entirely fixed, see Caveats)No filesystem could mount root, tried: squashfs
00331: factory boot check integer flag is not 1
How to break it
-
Flash OpenWRT using WEB UI
-
Flash OEM firmware package, don’t read guides, ignore the warnings (that’s how you ask for a brick)
-
Say hello to a soft-brick:
3: System Boot system code via Flash. ## Booting image at bc040000 ... Bad Magic Number,00E058EC
How to fix it
Easy, if you are lucky
-
Connect router to the PC via ethernet cable
-
Set PC network settings to static IP
- IP: 192.168.1.5
- Netmask: 255.255.255.0
- Gateway: 192.168.1.1
-
Open page
http://192.168.1.1
- If the page doesn’t open up, make sure that go to hard mode below
-
Select OEM firmware, upload
- If you get an error before the progress completes, you are flashing wrong file. It must be original OEM file with .bin extension
-
If the recovery page is just refreshed after completion, you are not lucky. Time go get hands dirty. Get yourself a 3.3V UART dongle.
-
During the flash you should probably see a log in the serial console:
[NM_Error](nm_checkUpdateContent) 01221: the firmware software version dismatched
Which prevents you from flashing any software via Web UI
-
Hard, most probably your case if you are reading this article
What will you need:
- TFTPserver software
- For MacOSX I recommend Transfer, free trial is all you need
- 3.3v UART to USB dongle with some wires to connect it to the router
- Terminal
- On MacOSX or linux a built-in terminal is all you need
- On windows, I’ve heard that Putty can be used
Begin the operation
Setup UART
-
If you’ve already fiddled with UART, you can skip this part and jump right to the
BEGIN FIX
part below -
Open the case, connect the UART cable ignore the VCC PIN, it MUST remain disconnected
- If the ethernet port does not start with the UART connected, disconnect the VCC cable from UART !
-
Start terminal and connect to the UART serial
-
On MacOSX:
-
Find you UART device:
ls /dev/tty.*
One of the devices should containusbserial
, that should be the one. Copy its path. -
Connect to the serial:
sudo cu -s 115200 -l /dev/tty.{your uart device}
-
-
Power cycle the router (unplug and plug the power adapter)
-
You should see in the terminal lines like the following:
U-Boot 1.1.3 (Dec 21 2020 - 16:49:33) Board: Ralink APSoC DRAM: 128 MB relocate_code Pointer at: 87f58000
- If you instead see the garbage characters, baud rate is set wrong. It must be
115200
- If you don’t see any characters, Rx and Tx cables are probably connected other way around, invert them
- If you instead see the garbage characters, baud rate is set wrong. It must be
-
Begin the fix
Prepare the OEM sysupgrade
- Download the latest OEW firmware from https://www.mercusys.com/en/download/mr70x/v1#Firmware
- Unzip to get the
.bin
file - Go to https://argsnd.github.io/tp-link-stock-firmware-converter/index.html
- Upload the firmware
.bin
file to get thesysupgrade.bin
file
Prepare the initramfs image file
- Download the OpenWRT kernel initramfs .bin from https://downloads.openwrt.org/releases/23.05.3/targets/ramips/mt7621/openwrt-23.05.3-ramips-mt7621-mercusys_mr70x-v1-initramfs-kernel.bin
-
Rename it to
test.bin
-
Start your TFTP server in the directory where
test.bin
is- In the Transfer you can just drop the
test.bin
file into the Transfer window. It should appear on the file list.
- In the Transfer you can just drop the
-
Open the terminal with the serial console, power-cycle the router
-
As soon as you see the new output in the terminal, press
t
-
You should end up seeing the CLI:
4: System Enter Boot Command Line Interface. U-Boot 1.1.3 (Dec 21 2020 - 16:49:33) MT7621 #
-
If you instead see
KSEG1ADDR(NetTxPacket) = 0xA7FE7180 Trying Eth0 (10/100-M) Waitting for RX_DMA_BUSY status Start... done ETH_STATE_ACTIVE!! HTTP server is starting at IP: 192.168.1.1 HTTP server is ready!
Then you’ve pressed
t
too late or your terminal doesn’t send keystrokes properly or TX cable isn’t properly connected.
-
-
Type
t
again and pressenter
. You should enter TFTPboot mode.-
You should see
*** Warning: no boot file name; using 'test.bin' TFTP from server 192.168.1.5; our IP address is 192.168.1.1 Filename 'test.bin'. TIMEOUT_COUNT=10,Load address: 0x84000000 Loading: *
- Note the file name, if it is different from
test.bin
, you should rename the file in TFTP server to match - Note the server IP address, if it is different from
192.168.1.5
, you must change your PC static IP address settings, so they would match
- Note the file name, if it is different from
-
If download doesn’t start, and you see
Retry count exceeded; starting again
message, your TFTP server is not running or cannot be reached, check IP, ethernet connection and TFTP server
-
-
After the download, you should see the message:
Bytes transferred = 5744144 (57a610 hex) LoadAddr=84000000 NetBootFileXferSize= 0057a610 MT7621 #
-
Type
b
and pressenter
, you should be able to boot into the firmware-
If you end up with
No filesystem could mount root, tried: squashfs Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,2)
You’ve flashed the wrong file, you need to use
kernel
image astest.bin
in TFTP
-
Flashing the OEM sysupgrade
If you haven’t done that already, begin by preparing the sysupgrade.bin
from OEM firmware, see Prepare the OEM sysupgrade steps above.
-
After the system starts (LED should stop blinking), you should be able to access
http://192.168.1.1/cgi-bin/luci/
root
/root
are the default credentials
-
Go to „Backup / Flash firmware”
-
Flash the
sysupgrade.bin
that we’ve got by converting the OEM firmware- It is not the OpenWRT sysupgrade, it is the converted one from Prepare the OEM sysupgrade steps !
Uncheck „Keep settings”, check „Force upgrade” (ignore the warnings, this time we know what we do), and click „Continue”
-
Wait for the completion. If the router reboots to OEM firmware, you are good to go, router is fixed.
-
If you end up with dreaded
[NM_Error](nm_api_checkInteger) 00331: factory boot check integer flag is not 1.
keep reading.
-
Fixing thefactory boot check integer flag is not 1.
Important: First finish the Begin Fix steps, as we need MTD to be set up properly before OEM initramfs could be started from TFTP
This error seems to be fixable ONLY by using OEM Web UI flash (unless you know which partition to back up and how and which bytes to edit. I could not figure it out).
To do that, we are going to do the opposite of what we did just now: Use OEM initramfs to flash OpenWRT first.
-
Get the OEM converted sysupgrade file if you haven’t already (see Prepare the OEM sysupgrade)
-
Rename the
sysupgrade.bin
totest.bin
so we could boot from it using -
Boot from TFTP, follow the steps in Prepare the initramfs image file (but using
sysupgrade.bin
astest.bin
instead of kernel image)-
If you end up with
No filesystem could mount root, tried: squashfs Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,2)
You need to perform Begin Fix steps all over again, as something didn’t work as intended there.
-
-
System should boot up to OEM firmware
-
After the LED stops blinking, the Web UI should be available at
http://192.168.1.1
- Important: router could start with the configuration that was set up before you even flashed OpenWRT, as those settings doesn’t seem to be cleared during the process. If the Web UI is not reachable, press and hold the reset button until the router restarts. Then you need to repeat the TFTP boot process again.
-
Now perform flashing the OpenWRT factory image using Web UI
- You can skip the initial setup in the upper-right corner by clicking „Skip setup” button
-
Go to „Advanced” -> „System” -> „Firmware Update”
-
Select and update the
factory
OpenWRT image file.-
It must be the
factory
image, not theinitramfs
that we’ve used previously. Eg.openwrt-23.05.3-ramips-mt7621-mercusys_mr70x-v1-squashfs-factory.bin
-
If you see a nice
vendorName : Mercusys vendorUrl : www.mercusys.com productName : MR70X productLanguage : US productId : 18000001 productVer : ff010000 specialId : 45550000 hwId : BEA9246D14969065F575BC7D4814655B oemId : F9DCD93DFBF1273E4C14A4BAFBB84C8C
In the UART console, then everything should be fine.
-
-
Wait for the process to complete. Router should stop blinking after the system boots up.
-
Go to
http://192.168.1.1
-
If you end up with
Not Found The requested URL /webpages/index.html?t=1e83e2a8 was not found on this server.
Then you are refreshing the flash page, this will not work. You need to go directly to
http://192.168.1.1
page, not just refresh.
-
-
Router is now booted from internal memory, integer flag should be properly set to
1
, we can now process with proper OEM firmware flash, instead of the mess that made us do all the de-bricking in the first place.
Proper OEM flash
Follow the steps in Flashing the OEM sysupgrade
Caveats
- You won’t be able to perform the OEM firmware update via Web UI without going to OpenWRT first.
You may have noticed a weird version number in OEM firmware:
0.0.0 Build 20240322 Rel. 23809(4555)
This is (probably?) a leftover from the OpenWRT firmware metadata, saved somewhere in the flash memory.
This breaks the OEM update system, resulting in the 01221: the firmware software version dismatched
error.
Until a method to fix the issue properly is found, you will have to first flash the OpenWRT, then convert the new OEM firmware to a sysupgrade, and flash it via the OpenWRT’s Web UI.
Epilogue
If you’ve successfully un-bricked your router, well done! You’ve just saved a couple of bucks!
Instead of throwing money on a new router, you can buy me a coffee at ko-fi.com. Thanks!