TP-Link WR941ND v5.0 4MB to 16MB flash upgrade

I have this router laying around and decided to make a flash upgrade for better use with OpenWRT.

The original flash is an EON EN25Q32(A/B) 4096 kB SPI, replaced to a Winbond W25Q128.V 16384 kB, SPI.

A Raspberry Pi with a SOIC/SOP8 test clip, basic soldering skills and flashrom are needed (


The first step is to desolder the original flash chip from the board and fit it into the test clip. I find it's much easier to deal with it already desoldered from the board. The pinout diagrams for both SPI and Raspberry Pi GPIO are avaiable in this page's_EFI_Install_Guide/Disabling_the_Intel_Management_Engine, note that /WP and /HOLD pins are not needed in our case.

It's a good advise to make two full dumps and make a md5sum to play safe. If something goes wrong, you can always flash it back to the original state.

flashrom -r fulldump.bin -c "EN25Q32(A/B)" -p linux_spi:dev=/dev/spidev0.0,spispeed=8000
flashrom -r fulldump2.bin -c "EN25Q32(A/B)" -p linux_spi:dev=/dev/spidev0.0,spispeed=8000
md5sum fulldump*

If both hashes are identical you are fine to continue, if not, check your connections until you get two identical hashes.

Very important: two partitions from the original dump are needed, original u-boot and art. Their addresses are described in the spi.layout file.

echo -e "000000:01FFFF u-boot\n020000:16940B kernel\n16940C:3EFFFF rootfs\n3A0000:3EFFFF rootfs_data\n020000:3EFFFF firmware\n3F0000:3FFFFF art" > spi.layout
flashrom -r u-boot.bin -c "EN25Q32(A/B)" -l spi.layout -i u-boot -p linux_spi:dev=/dev/spidev0.0,spispeed=8000
flashrom -r art.bin -c "EN25Q32(A/B)" -l spi.layout -i art -p linux_spi:dev=/dev/spidev0.0,spispeed=8000

Download the modified u-boot for the WR841N V8 model, it's compatible with WR941ND V5 and have many advantages over the original u-boot, such as DHCP, u-boot and art upgrade from the recovery mode web server, and support many flash models.

Github page can be found here:
Download file here:, search for u-boot_mod__tp-link_tl-wr841n_v8__20180223__git_master-7a540a78.bin file.

I'm not going deep into why the next procedures are needed, they are all explained in the the github page shown above, in a nutsheel, they are needed to copy router info from the original u-boot partition such as MAC and model number, and fit in a new 16MB image.

Create a blank 16MB image:

dd if=/dev/zero bs=1M count=16 of=padded.bin

Merge the original and modified u-boot into it:

dd if=u-boot.bin conv=notrunc of=padded.bin
dd if=u-boot_mod__tp-link_tl-wr841n_v8__20180223__git_master-7a540a78.bin conv=notrunc of=padded.bin

Flash it into the new 16MB SPI:

flashrom -w padded.bin -c "W25Q128.V" -p linux_spi:dev=/dev/spidev0.0,spispeed=8000

Now solder it back to the router board.

DHCP should work automatically and router recovery mode web server is now accesible from the gateway address, but if it's not working, set your machine to static IP and gateway

First go to and send art.bin previously backed up, this procedure is fast and takes just a few seconds, router will automatically reboot again in recovery mode (page is not updated automatically or any message is shown). Now you can send OpenWRT firmware (squashfs sysupgrade) from (, file openwrt-18.06.1-ar71xx-tiny-tl-wr941nd-v5-squashfs-sysupgrade.bin).

Router now have 11.84mb free memory instead of the few kbs before.

Next steps are RAM upgrade when I find a chip donor and build a proper 16MB image, the latter one is probably more complicated to me.


Just as a head's up, more than 8 MB flash will be tricky for firmware upgrades (factory via mtd or relatively 'full' sysupgrades) given the limited RAM size (32 MB).

That's why the next step is a RAM upgrade, I just need to find a suitable and cheap RAM stick with at least 64MB modules. :grinning:

If a firmware upgrade from LuCi is not possible, I'll boot from recovery mode.

I've done the W25Q128 upgrade on several similar TP-Links. It's a nice upgrade.

Modified u-boot is not really necessary. The stock u-boot will boot with a larger chip. It can only write to the first 4 MB of the chip though.

Instead of making large firmware images, it works to use a release image (built to fit in 4 MB) then install packages (from the release repository) at run-time. The release image contains code to auto-detect the flash size and use the additional space.

If you only copy the bootloader and firmware into the new chip, OpenWrt will still boot up (but no wifi without the ART). The kmod-mtd-rw package and mtd can be used to install the ART after first boot.

I would suggest first running OpenWrt on the stock router and using it to read the bootloader and ART from the original chip (and scp them to your PC) before opening up the case.


It can be useful

Does anyone hase experience with flash upgrade of TL-WR941ND v3, which use AR9132 SOC which is not supported by pepe2k/u-boot_mod?
As I understand, I must edit some configuration files, put there correct flash size and compile my own firmware. I used to compile my own firmware, but I don't understand what I must edit in config files for building firmware for biggest flash chip.
Help, please.

A good guide can be found here (in German): It is for tl-wr 841. You will need to edit mk config files before building.

can be add 1 GB RAM ? :rofl:

can be add 2 flash 16 MB and Setup 2 Firmware at the same time ?
example in motherboard dual bios ? and used switch key ????

You can add socket to the router and exchange then flash chip. The RAM can be upgraded to 64 MB.

can you please tell, how that can be done?

This process is one of those "if you have to ask basic questions, you shouldn't be doing it" kinds of things.

If you pooch your flash, you have a brick.

The seemingly endless set of threads describing an inexpert user that just used low-level tools to flash an upgrade image on a device and spent days (weeks?) trying to recover should be evidence of this.

For NOR flash, and not for NAND flash, dd is an appropriate tool to make a copy of every /dev/mtdNro partition.

Something along the lines of

dd if=/dev/mtdNro of=/tmp/mtdNro.bin

for every partition would be wise. Since you're on a very resource-constrained device, you may have to do it a partition or two at a time, so you don't fill up /tmp/ and run out of memory.
after going to above link I figured out that mtd0 is the bootloader and mtd4 is the art .

I first created a backup of mtd4 a.k.a. ART : step1

then creates a backup of mtd0 a.k.a. boot: step2

I successfully upgraded RAM and ROM FLASH of my tp-link mr3220 v2 router.

check my repo:

Hi all,

yesterday I managed to replace the 4MB with 8MB (that was what I had) of my WR940N.v1.
Initially I just desoldered and read the entire 4MB contents and burned them at address 0x00000 of the 8MB. Of course, I did not pay enough attention to backup the ART partition and wifi was a gonner.
So after issuing cat /proc/mtd on the 8MB flashed version, I get that mtd4 "art" partition is located at 0x7f0000, while in the old 4MB it was at 0x3f0000.

Using WinHex I extracted the 64k art partition bytes from the original image and saved them in art.bin file inside /tmp directory over SCP. Since this partition in flash is non-writable, I needed to add the kmod-mtd-rw to a new build (couldn't use opkg). Finally, using

dd if=/tmp/art.bin of=/dev/mtd4

was successful and now the router has it's wifi back.

On a side note, it may be just easier to desolder the flash chip and write the last 64k ART with the programmer instead of doing the hassle wtih kmod-mtd-rw.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.