OpenWrt Forum Archive

Topic: TL-MR3420 flash modification

The content of this topic has been archived between 15 Apr 2018 and 1 May 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

I have successfully modified flash size on TP-Link TL-MR3420.
I substituted original 4MB Spansion flash with Eon EN25Q64.

Eon flash is avaible here:

HW modifications:
The main problem was to copy first flash content to second one without
SPI flash programmer.
I soldered both flashes in parallel (all lines except Chip Select - CS).
CS of both chips were pulled up with addinational 10k resistors. Using
jumper i could connect first or second flash CS pin with CPU CS.
(schematics soon).

To copy flash content:
1/ I booted board with old flash and entered u-boot
2/ copied content of flash to RAM - cp.b 0x9f000000 0x81000000 0x3effff
3/ switched jumper to new flash
4/ set no protection to flash - protect off 0x9f000000 0x3effff
5/ copied flash content form RAM to flash - cp.b 0x81000000 0xf9000000 0x3effff
6/ rebooted board - u-boot successfully started

Now first problem is current linux kernel has no EN25Q80A JEDEC ID, so it hungs on
no rootfs. Here is the clue:

In file linux- add line:
        { "en25p64", 0x1c2017, 0, 64 * 1024, 128, },
-->   { "en25q64", 0x1c3017, 0, 64 * 1024, 128, },

Next modification in kernel was extending partition info:
in file linux-

static struct mtd_partition tl_mr3x20_partitions[] = {
                .name           = "u-boot",
                .offset         = 0,
                .size           = 0x020000,
                .mask_flags     = MTD_WRITEABLE,
        }, {
                .name           = "kernel",
                .offset         = 0x020000,
                .size           = 0x140000,
        }, {
                .name           = "rootfs",
                .offset         = 0x160000,
                .size           = 0x690000,     // 0x290000
        }, {
                .name           = "art",
                .offset         = 0x7f0000,     // 0x3f0000
                .size           = 0x010000,
//              .mask_flags     = MTD_WRITEABLE,
        }, {
                .name           = "firmware",
                .offset         = 0x020000,
                .size           = 0x7d0000,

I found that there are some problems with Wifi calibration.
So I soldered back old flash, and copied content of art partition to host.

After making art partition in new kernel writable I copied previous content
to new art partition. After reboot it worked.

So I think now all works -> all hardware is working and also Wifi.

BusyBox v1.17.3 (2011-01-26 03:27:28 CET) 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
 KAMIKAZE (bleeding edge, r25131) ------------------
  * 10 oz Vodka       Shake well with ice and strain
  * 10 oz Triple sec  mixture into 10 shot glasses.
  * 10 oz lime juice  Salute!
root@OpenWrt:~# dmesg
Linux version (bizewskik@wicomm) (gcc version 4.3.3 (GCC) ) #5 Fri Jan 28 01:20:54 CET 2011
prom: fw_arg0=00000008, fw_arg1=a1f87fb0, fw_arg2=a1f88470, fw_arg3=00000004
MyLoader: sysp=f0f0f0f0, boardp=f0f0f0f0, parts=f0f0f0f0
bootconsole [early0] enabled
CPU revision is: 00019374 (MIPS 24Kc)
Atheros AR7241 rev 1, CPU:400.000 MHz, AHB:200.000 MHz, DDR:400.000 MHz
Determined physical RAM map:
 memory: 02000000 @ 00000000 (usable)
Initrd not found or empty - disabling initrd
Zone PFN ranges:
  Normal   0x00000000 -> 0x00002000
Movable zone start PFN for each node
early_node_map[1] active PFN ranges
    0: 0x00000000 -> 0x00002000
On node 0 totalpages: 8192
free_area_init_node: node 0, pgdat 802af8b0, node_mem_map 81000000
  Normal zone: 64 pages used for memmap
  Normal zone: 0 pages reserved
  Normal zone: 8128 pages, LIFO batch:0
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 8128
Kernel command line: rootfstype=squashfs,jffs2 noinitrd console=ttyS0,115200 board=TL-MR3420
PID hash table entries: 128 (order: -3, 512 bytes)
Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
Primary instruction cache 64kB, VIPT, 4-way, linesize 32 bytes.
Primary data cache 32kB, 4-way, VIPT, cache aliases, linesize 32 bytes
Writing ErrCtl register=00000000
Readback ErrCtl register=00000000
Memory: 29468k/32768k available (1978k kernel code, 3300k reserved, 390k data, 148k init, 0k highmem)
SLUB: Genslabs=7, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
Hierarchical RCU implementation.
Calibrating delay loop... 266.24 BogoMIPS (lpj=1331200)
Mount-cache hash table entries: 512
NET: Registered protocol family 16
MIPS: machine is TP-LINK TL-MR3420
registering PCI controller with io_map_base unset
bio: create slab <bio-0> at 0
pci 0000:00:00.0: fixup device configuration
pci 0000:00:00.0: reg 10 64bit mmio: [0x000000-0x00ffff]
pci 0000:00:00.0: supports D1
pci 0000:00:00.0: PME# supported from D0 D1 D3hot
pci 0000:00:00.0: PME# disabled
PCI: mapping irq 48 to pin1@0000:00:00.0
Switching to clocksource MIPS
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 1024 (order: 1, 8192 bytes)
TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
TCP: Hash tables configured (established 1024 bind 1024)
TCP reno registered
NET: Registered protocol family 1
squashfs: version 4.0 (2009/01/31) Phillip Lougher
Registering mini_fo version $Id$
JFFS2 version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
msgmni has been set to 57
io scheduler noop registered
io scheduler deadline registered (default)
Serial: 8250/16550 driver, 1 ports, IRQ sharing disabled
serial8250.0: ttyS0 at MMIO 0x18020000 (irq = 11) is a 16550A
console [ttyS0] enabled, bootconsole disabled
Atheros AR71xx SPI Controller driver version 0.2.4
m25p80 spi0.0: en25q64 (8192 Kbytes)
spi0.0: searching for MyLoader partition table at offset 0x10000
spi0.0: searching for MyLoader partition table at offset 0x20000
spi0.0: searching for MyLoader partition table at offset 0x30000
spi0.0: searching for MyLoader partition table at offset 0x40000
spi0.0: no MyLoader partition table found
Searching for RedBoot partition table in spi0.0 at offset 0x7e0000
Searching for RedBoot partition table in spi0.0 at offset 0x7f0000
No RedBoot partition table detected in spi0.0
spi0.0: no WRT160NL signature found
Creating 5 MTD partitions on "spi0.0":
0x000000000000-0x000000020000 : "u-boot"
0x000000020000-0x000000160000 : "kernel"
0x000000160000-0x0000007f0000 : "rootfs"
mtd: partition "rootfs" set to be root filesystem
mtd: partition "rootfs_data" created automatically, ofs=2E0000, len=510000
0x0000002e0000-0x0000007f0000 : "rootfs_data"
0x0000007f0000-0x000000800000 : "art"
0x000000020000-0x0000007f0000 : "firmware"
ag71xx_mdio: probed
eth0: Atheros AG71xx at 0xba000000, irq 5
eth0: Found an AR7240 built-in switch
eth1: Atheros AG71xx at 0xb9000000, irq 4
eth1: using fixed link parameters
Atheros AR71xx hardware watchdog driver version 0.1.0
ar71xx-wdt: timeout=15 secs (max=21)
TCP westwood registered
NET: Registered protocol family 17
802.1Q VLAN Support v1.8 Ben Greear <>
All bugs added by David S. Miller <>
VFS: Mounted root (squashfs filesystem) readonly on device 31:2.
Freeing unused kernel memory: 148k freed
Please be patient, while OpenWrt loads ...
input: gpio-buttons as /devices/platform/gpio-buttons/input/input0
Button Hotplug driver version 0.4.1
eth0: link up (1000Mbps/Full duplex)
Registered led device: tl-mr3x20:green:system
Registered led device: tl-mr3x20:green:qss
Registered led device: tl-mr3x20:green:3g
mini_fo: using base directory: /
mini_fo: using storage directory: /overlay
eth0: link down
eth0: link up (1000Mbps/Full duplex)
device eth0 entered promiscuous mode
br-lan: port 1(eth0) entering forwarding state
eth1: link up (100Mbps/Full duplex)
Compat-wireless backport release: compat-wireless-2011-01-06-3-g8db1608
Backport based on wireless-testing.git master-2011-01-21-2
cfg80211: Calling CRDA to update world regulatory domain
SCSI subsystem initialized
cfg80211: World regulatory domain updated:
cfg80211:     (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
cfg80211:     (2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
cfg80211:     (2457000 KHz - 2482000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)
cfg80211:     (2474000 KHz - 2494000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)
cfg80211:     (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
cfg80211:     (5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
PCI: Setting latency timer of device 0000:00:00.0 to 64
ath: EEPROM regdomain: 0x0
ath: EEPROM indicates default country code should be used
ath: doing EEPROM country->regdmn map search
ath: country maps to regdmn code: 0x3a
ath: Country alpha2 being used: US
ath: Regpair used: 0x3a
ieee80211 phy0: Selected rate control algorithm 'minstrel_ht'
Registered led device: ath9k-phy0
ieee80211 phy0: Atheros AR9287 Rev:2 mem=0xb0000000, irq=48
cfg80211: Calling CRDA for country: US
cfg80211: Regulatory domain changed to country: US
cfg80211:     (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
cfg80211:     (2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2700 mBm)
cfg80211:     (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 1700 mBm)
cfg80211:     (5250000 KHz - 5330000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
cfg80211:     (5490000 KHz - 5600000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
cfg80211:     (5650000 KHz - 5710000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
cfg80211:     (5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 3000 mBm)
PPP generic driver version 2.4.2
ip_tables: (C) 2000-2006 Netfilter Core Team
NET: Registered protocol family 24
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ar71xx-ehci ar71xx-ehci: Atheros AR91xx built-in EHCI controller
ar71xx-ehci ar71xx-ehci: new USB bus registered, assigned bus number 1
ar71xx-ehci ar71xx-ehci: irq 3, io mem 0x1b000000
ar71xx-ehci ar71xx-ehci: USB 2.0 started, EHCI 1.00
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
nf_conntrack version 0.5.0 (462 buckets, 1848 max)
CONFIG_NF_CT_ACCT is deprecated and will be removed soon. Please use
nf_conntrack.acct=1 kernel parameter, acct=1 nf_conntrack module option or
sysctl net.netfilter.nf_conntrack_acct=1 to enable it.
xt_time: kernel timezone is -0000
IMQ driver loaded successfully.
        Hooking IMQ before NAT on PREROUTING.
        Hooking IMQ after NAT on POSTROUTING.
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
device wlan0 entered promiscuous mode
br-lan: port 2(wlan0) entering forwarding state
device wlan0 left promiscuous mode
br-lan: port 2(wlan0) entering disabled state
device wlan0 entered promiscuous mode
br-lan: port 2(wlan0) entering forwarding state
ar71xx-wdt: enabling watchdog timer
usb 1-1: new high speed USB device using ar71xx-ehci and address 2
usb 1-1: configuration #1 chosen from 1 choice
scsi0 : SCSI emulation for USB Mass Storage devices
usb-storage: device found at 2
usb-storage: waiting for device to settle before scanning
scsi 0:0:0:0: Direct-Access     UT163    USB Flash Disk   0.00 PQ: 0 ANSI: 2
usb-storage: device scan complete
sd 0:0:0:0: [sda] 1974271 512-byte logical blocks: (1.01 GB/963 MiB)
sd 0:0:0:0: [sda] Write Protect is off
sd 0:0:0:0: [sda] Mode Sense: 00 00 00 00
sd 0:0:0:0: [sda] Assuming drive cache: write through
sd 0:0:0:0: [sda] Assuming drive cache: write through
 sda: sda1
sd 0:0:0:0: [sda] Assuming drive cache: write through
sd 0:0:0:0: [sda] Attached SCSI removable disk
root@OpenWrt:~# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/root                 1536      1536         0 100% /rom
tmpfs                    14808       304     14504   2% /tmp
tmpfs                      512         0       512   0% /dev
/dev/mtdblock3            5184      3412      1772  66% /overlay
mini_fo:/overlay          1536      1536         0 100% /

Also RAM size is modified with 64MB DDR from Infineon

root@OpenWrt:~# free
              total         used         free       shared      buffers
  Mem:        62104        22060        40044            0         1412
 Swap:            0            0            0
Total:        62104        22060        40044

To be continued...


(Last edited by BizonGod on 10 Mar 2011, 13:15)

Please share schematics & Pic tutorial....

very well: I wanted to to the same, so you saved my time smile)) thanks for sharing it

BizonGod wrote:

To be continued...

we waited

How to copy art partition ?

With dd or in uboot.

You can detail the specific commands?

@BizonGod good. i am trying the same.
I you are capabe of soldering the chip and flashing it via a SPI programmer, you gotta check my post and have a trying with 64M RAM/16M Flash with modified u-boot.(support 16M flash)

to BizonGod
We are still waiting schematics and pic tutorial....
Please share

Did you order the chip Eon EN25Q64  as bulk ? . I am not able to order one unit .


I just upgraded my TL-WR703n last weekend following this method. The idea is brilliant since you don't need any chip programmer.

I ordered my chip on eBay for $4.70 with free worldwide delivery. It is possible to order just one unit. You can search for EN25Q64-104HIP

Since BizonGod has not written here in a very long time and some people were asking for schematics I have made a picture with the connections:

Here you can find the datasheet from the EN25Q64 where you can see the function of each pin (first picture in page 2)

The theory is very simple, just solder both chips in parallel and to the board except the chip_select (pin1). Each chip_select is connected with a 10K "pull-up" resistor to Vcc and then you can easily switch between both chips by connecting one or the other chip_select to the board.

In practice it requires some delicate soldering and it is easy to make a bit of a mess with the cables. First I removed the old 4MB chip from the board and I used very thin wires to do the connections in the picture.

For some reason my uboot didn't recognize the "protect off" command but it looks that it is not needed. May be this is a difference with the TL-WR703n.
These are the steps I used:
   - Make sure you save a backup of your "art" partition since you will need it later.
   - Boot the router with the old 4MB chip connected and enter uboot.
   - Copy content of flash to RAM:    cp.b 0x9f000000 0x81000000 0x3effff
   - Switch chip_select cable to 8MB chip.
   - May be not needed, but I did run:   erase all
   - Copy old flash content form RAM to new flash:   cp.b 0x81000000 0x9f000000 0x3effff
   - When finished I rebooted the board with:  bootm 9f020000

In modern versions of OpenWrt you don't need any additional modification for using a 8MB flash so the router should boot correctly, but as indicated by BizonGod in the first post, your wifi interface will not work because the "art" partition was not copied during the uboot steps.

You will need to load a firmware compiled to allow writing in the "art" partition. Then you can just restore you "art" backup with:

    mtd -r write art.backup art

After this you router will reboot and the wifi interface should be working. Now I recommend you to load again a firmware with write protection for the "art" partition.

If someone needs a firmware for TL-703n with the write protection for "art" removed you can send me a pm and I will send you the file.

Otherwise you will need to compile it yourself. You just need to modify the "art" section in the file:
and replace "MTD_WRITEABLE" with a "0" in the mask_flags. The section will look something like this:

parts[3].name = "art";
parts[3].offset = art_offset;
parts[3].size = TPLINK_ART_LEN;
parts[3].mask_flags = 0;

When you have checked that everything is working you can finally solder only the 8MB chip to the board and close the box again.

Good luck!  wink

(Last edited by griguolcomerranas on 26 Sep 2012, 04:26)

How to make a backup "art"?

backup u-boot:

cat /dev/mtd0 > /tmp/backup_u-boot.bin

backup art:

cat /dev/mtd4 > /tmp/backup_art.bin

buckup firmware with your settings:

cat /dev/mtd5 > /tmp/backup_firmware.bin

This firmware you can flash through the Web interface or the MTD method!

buckup fullflash:

cat /dev/mtd0 > /tmp/backup_fullflash.bin
cat /dev/mtd5 >> /tmp/backup_fullflash.bin
cat /dev/mtd4 >> /tmp/backup_fullflash.bin

then copy bin file from tmp dir on router in your computer via WinSCP.

(Last edited by Dioptimizer on 28 Oct 2012, 05:57)

griguolcomerranas and Dioptimizer
Thank you so much!

(Last edited by kmzz on 25 Oct 2012, 04:37)

Im looking for the compiled version with writeable art. can anyone help me out here? I've gotta as far as to get the the flash chip on and all the stuff copied over. router boots fine, just WIFI doesnt work, as stated before.

A writeup how to do it would be helpful to.

Unless theres another way to load my ART backup.


thanks! so if I flash that image, then use winscp to put my backup_art.bin in the root then

mtd -r write art.backup art

Ok, I got everything working!! only thing is when I boot it still says

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

forsakenrider wrote:

Ok, I got everything working!! only thing is when I boot it still says

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

What do you expect ?

the flash to read "8 MB"

But it says

root@OpenWrt:~# dmesg | grep en25q64
[    0.490000] m25p80 spi0.0: found en25q64, expected m25p80
[    0.500000] m25p80 spi0.0: en25q64 (8192 Kbytes)

does this use an SD card for flash? is there an english version? I cant get google translate to work!

That's pretty neat. Please do an english translation. So, do I understand it right, that with this solution, you will loose the serial port on AR933x SoCs? And what is it about CS1 and CS2? Would that mean, that even a second spi device could easily be accessed this way?
But, what I finally got in mind is: What about completely replacing the flash with a SD card? Would that work, or would the bootloader have too much troubles with such solution?
Or another scenario: go with your solution, but unsolder and lift the CS of the flash. Have a circuit that by default pulls down CS to GND, and at some point during bootup switch it using any free GPIO and thus switch over to the SD card. What do you think?