Hi everyone,
I have done 16M Flash and 64M RAM hardware modification for TP-LINK TL-MR3420v1 and compiled a version openwrt for it. Everything works good as of now..
Original Hardware:
ar7241+ar9287 / 4M flash /32M RAM /USB2.0. What we need to do is replcing its flash/memory chip and flash openwrt to unleash its potential.
Part one: find a proper chip:
1. You need to check the flash chip data sheet, it shall be 64k size per sector since this is defined in uboot.
Working serial flash chip:
8M: MX25L6405
16M: MX25L12805, S25FL128PIF
Memroy:
66 Pin,16bit DDR400 64M chip, you may desolder one from your old memory bar to got a suitable chip.such as Hynix HY5DU121622DTP-D43
Part two: Compile uboot to support 8M/16M serial flash chip:
1. Download source code from tp-link gpl site: http://www.tp-link.com/support/todownlo … 2Etar%2Egz
2. Extract the package, goto mr3420_3220v1/ap99/boot/u-boot/include/configs/ap99.h to modify the source code as following, be ware that #define FLASH_SIZE 16 is the definition for your flash size, change it to 8 if you use a 8M chip.
/*
* This file contains the configuration parameters for the pb93 board.
*/
#ifndef __CONFIG_H
#define __CONFIG_H
#include <configs/ar7240.h>
//Support 8M/16M flash
#define FLASH_SIZE 16
#undef CFG_PROMPT
#define CFG_PROMPT "mr3420> " /* Monitor Command Prompt */
/*-----------------------------------------------------------------------
* FLASH and environment organization
*/
#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
#if (FLASH_SIZE == 16)
#define CFG_MAX_FLASH_SECT 256 /* max number of sectors on one chip, NEED TO CHECK FLASH DATASHEET */
#else
#if (FLASH_SIZE == 8)
#define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */
#else
#define CFG_MAX_FLASH_SECT 64 /* max number of sectors on one chip */
#endif
#endif
#ifdef CONFIG_K31
#define CFG_FLASH_SECTOR_SIZE (256*1024)
#define CFG_FLASH_SIZE 0x1000000 /* Total flash size */
#else
#define CFG_FLASH_SECTOR_SIZE (64*1024) /* NEED TO CHECK FLASH DATA SHEET 64k only*/
#if (FLASH_SIZE == 16)
#define CFG_FLASH_SIZE 0x01000000 /* Total flash size */
#else
#if (FLASH_SIZE == 8)
#define CFG_FLASH_SIZE 0x00800000 /* Total flash size */
#else
#define CFG_FLASH_SIZE 0x00400000 /* Total flash size */
#endif
#endif
#endif
#define ENABLE_DYNAMIC_CONF 1
#define CONFIG_SUPPORT_AR7241 1
#if (CFG_MAX_FLASH_SECT * CFG_FLASH_SECTOR_SIZE) != CFG_FLASH_SIZE
# error "Invalid flash configuration"
#endif
#define CFG_FLASH_WORD_SIZE unsigned short
/*
* We boot from this flash
*/
#define CFG_FLASH_BASE 0x9f000000
/*
* Defines to change flash size on reboot
*/
#ifdef ENABLE_DYNAMIC_CONF
#define UBOOT_FLASH_SIZE (256 * 1024)
#define UBOOT_ENV_SEC_START (CFG_FLASH_BASE + UBOOT_FLASH_SIZE)
#define CFG_FLASH_MAGIC 0xaabacada
#define CFG_FLASH_MAGIC_F (UBOOT_ENV_SEC_START + CFG_FLASH_SECTOR_SIZE - 0x20)
#define CFG_FLASH_SECTOR_SIZE_F *(volatile int *)(CFG_FLASH_MAGIC_F + 0x4)
#define CFG_FLASH_SIZE_F *(volatile int *)(CFG_FLASH_MAGIC_F + 0x8) /* Total flash size */
#define CFG_MAX_FLASH_SECT_F (CFG_FLASH_SIZE / CFG_FLASH_SECTOR_SIZE) /* max number of sectors on one chip */
#endif
/*
* The following #defines are needed to get flash environment right
*/
#define CFG_MONITOR_BASE TEXT_BASE
#define CFG_MONITOR_LEN (192 << 10)
#undef CONFIG_BOOTARGS
/* XXX - putting rootfs in last partition results in jffs errors */
#if (FLASH_SIZE == 16)
#define CONFIG_BOOTARGS "console=ttyS0,115200 root=31:02 rootfstype=jffs2 init=/sbin/init mtdparts=ar7240-nor0:256k(u-boot),64k(u-boot-env),13312k(rootfs),896k(uImage),64k(NVRAM),1792k(ART)"
#else
#if (FLASH_SIZE == 8)
#define CONFIG_BOOTARGS "console=ttyS0,115200 root=31:02 rootfstype=jffs2 init=/sbin/init mtdparts=ar7240-nor0:256k(u-boot),64k(u-boot-env),5120k(rootfs),896k(uImage),64k(NVRAM),1792k(ART)"
#else
#define CONFIG_BOOTARGS "console=ttyS0,115200 root=31:02 rootfstype=jffs2 init=/sbin/init mtdparts=ar7240-nor0:256k(u-boot),64k(u-boot-env),2752k(rootfs),896k(uImage),64k(NVRAM),64k(ART) REVISIONID"
#endif
#endif
/* default mtd partition table */
#undef MTDPARTS_DEFAULT
//#define MTDPARTS_DEFAULT "mtdparts=ar7240-nor0:256k(u-boot),64k(u-boot-env),2752k(rootfs),896k(uImage),64k(NVRAM),64k(ART)"
#if (FLASH_SIZE == 16)
#define MTDPARTS_DEFAULT "mtdparts=ar7240-nor0:256k(u-boot),64k(u-boot-env),13312k(rootfs),896k(uImage),64k(NVRAM),1792k(ART)"
#else
#if (FLASH_SIZE == 8)
#define MTDPARTS_DEFAULT "mtdparts=ar7240-nor0:256k(u-boot),64k(u-boot-env),5120k(rootfs),896k(uImage),64k(NVRAM),1792k(ART)"
#else
#define MTDPARTS_DEFAULT "mtdparts=ar7240-nor0:256k(u-boot),64k(u-boot-env),2752k(rootfs),896k(uImage),64k(NVRAM),64k(ART)"
#endif
#endif
#undef CFG_PLL_FREQ
#ifdef CONFIG_SUPPORT_AR7241
#define CFG_AR7241_PLL_FREQ CFG_PLL_400_400_200
//#define CFG_AR7241_PLL_FREQ CFG_PLL_400_200_200
#endif
#define CFG_PLL_FREQ CFG_PLL_400_400_200
#undef CFG_HZ
/*
* MIPS32 24K Processor Core Family Software User's Manual
*
* 6.2.9 Count Register (CP0 Register 9, Select 0)
* The Count register acts as a timer, incrementing at a constant
* rate, whether or not an instruction is executed, retired, or
* any forward progress is made through the pipeline. The counter
* increments every other clock, if the DC bit in the Cause register
* is 0.
*/
/* Since the count is incremented every other tick, divide by 2 */
/* XXX derive this from CFG_PLL_FREQ */
#if (CFG_PLL_FREQ == CFG_PLL_200_200_100)
# define CFG_HZ (200000000/2)
#elif (CFG_PLL_FREQ == CFG_PLL_300_300_150)
# define CFG_HZ (300000000/2)
#elif (CFG_PLL_FREQ == CFG_PLL_350_350_175)
# define CFG_HZ (350000000/2)
#elif (CFG_PLL_FREQ == CFG_PLL_333_333_166)
# define CFG_HZ (333000000/2)
#elif (CFG_PLL_FREQ == CFG_PLL_266_266_133)
# define CFG_HZ (266000000/2)
#elif (CFG_PLL_FREQ == CFG_PLL_266_266_66)
# define CFG_HZ (266000000/2)
#elif (CFG_PLL_FREQ == CFG_PLL_400_400_200) || (CFG_PLL_FREQ == CFG_PLL_400_400_100)
# define CFG_HZ (400000000/2)
#elif (CFG_PLL_FREQ == CFG_PLL_320_320_80) || (CFG_PLL_FREQ == CFG_PLL_320_320_160)
# define CFG_HZ (320000000/2)
#elif (CFG_PLL_FREQ == CFG_PLL_410_400_200)
# define CFG_HZ (410000000/2)
#elif (CFG_PLL_FREQ == CFG_PLL_420_400_200)
# define CFG_HZ (420000000/2)
#elif (CFG_PLL_FREQ == CFG_PLL_240_240_120)
# define CFG_HZ (240000000/2)
#elif (CFG_PLL_FREQ == CFG_PLL_160_160_80)
# define CFG_HZ (160000000/2)
#elif (CFG_PLL_FREQ == CFG_PLL_400_200_200)
# define CFG_HZ (400000000/2)
#endif
/*
* timeout values are in ticks
*/
#define CFG_FLASH_ERASE_TOUT (2 * CFG_HZ) /* Timeout for Flash Erase */
#define CFG_FLASH_WRITE_TOUT (2 * CFG_HZ) /* Timeout for Flash Write */
/*
* Cache lock for stack
*/
#define CFG_INIT_SP_OFFSET 0x1000
/* lsz 081222
#define CFG_ENV_IS_IN_FLASH 1
#undef CFG_ENV_IS_NOWHERE
*/
#undef CFG_ENV_IS_IN_FLASH
#define CFG_ENV_IS_NOWHERE 1
/* Address and size of Primary Environment Sector */
#define CFG_ENV_ADDR 0x9f040000
#define CFG_ENV_SIZE CFG_FLASH_SECTOR_SIZE
#if defined(CONFIG_K31)
define CONFIG_BOOTCOMMAND "bootm 0x9f050000"
#else
#if (FLASH_SIZE == 16)
#define CONFIG_BOOTCOMMAND "bootm 0x9f020000"
#else
#if (FLASH_SIZE == 8)
//#define CONFIG_BOOTCOMMAND "bootm 0x9f550000"
#define CONFIG_BOOTCOMMAND "bootm 0x9f020000"
#else
//#define CONFIG_BOOTCOMMAND "bootm 0x9f300000"
#define CONFIG_BOOTCOMMAND "bootm 0x9f020000"
#endif
#endif
#endif
//#define CONFIG_FLASH_16BIT
/* DDR init values */
#define CONFIG_NR_DRAM_BANKS 2
/* DDR values to support AR7241 */
#ifdef CONFIG_SUPPORT_AR7241
#define CFG_7241_DDR1_CONFIG_VAL 0xc7bc8cd0
//#define CFG_7241_DDR1_CONFIG_VAL 0x6fbc8cd0
#define CFG_7241_DDR1_MODE_VAL_INIT 0x133
#define CFG_7241_DDR1_EXT_MODE_VAL 0x0
#define CFG_7241_DDR1_MODE_VAL 0x33
//#define CFG_7241_DDR1_MODE_VAL 0x23
#define CFG_7241_DDR1_CONFIG2_VAL 0x9dd0e6a8
#define CFG_7241_DDR2_CONFIG_VAL 0xc7bc8cd0
#define CFG_7241_DDR2_MODE_VAL_INIT 0x133
#define CFG_7241_DDR2_EXT_MODE_VAL 0x402
#define CFG_7241_DDR2_MODE_VAL 0x33
#define CFG_7241_DDR2_CONFIG2_VAL 0x9dd0e6a8
#endif /* _SUPPORT_AR7241 */
/* DDR settings for AR7240 */
#define CFG_DDR_REFRESH_VAL 0x4f10
#define CFG_DDR_CONFIG_VAL 0xc7bc8cd0
#define CFG_DDR_MODE_VAL_INIT 0x133
#ifdef LOW_DRIVE_STRENGTH
# define CFG_DDR_EXT_MODE_VAL 0x2
#else
# define CFG_DDR_EXT_MODE_VAL 0x0
#endif
#define CFG_DDR_MODE_VAL 0x33
#define CFG_DDR_TRTW_VAL 0x1f
#define CFG_DDR_TWTR_VAL 0x1e
#define CFG_DDR_CONFIG2_VAL 0x9dd0e6a8
#define CFG_DDR_RD_DATA_THIS_CYCLE_VAL 0x00ff
/* DDR2 Init values */
#define CFG_DDR2_EXT_MODE_VAL 0x402
#ifdef ENABLE_DYNAMIC_CONF
#define CFG_DDR_MAGIC 0xaabacada
#define CFG_DDR_MAGIC_F (UBOOT_ENV_SEC_START + CFG_FLASH_SECTOR_SIZE - 0x30)
#define CFG_DDR_CONFIG_VAL_F *(volatile int *)(CFG_DDR_MAGIC_F + 4)
#define CFG_DDR_CONFIG2_VAL_F *(volatile int *)(CFG_DDR_MAGIC_F + 8)
#define CFG_DDR_EXT_MODE_VAL_F *(volatile int *)(CFG_DDR_MAGIC_F + 12)
#endif
#define CONFIG_NET_MULTI
#define CONFIG_AG7240_SPEPHY /* choose eth1 first for tftpboot interface added by tiger 07/20/09*/
#define CONFIG_MEMSIZE_IN_BYTES
#define CONFIG_PCI
/*-----------------------------------------------------------------------
* Cache Configuration
*/
/*
#define CONFIG_COMMANDS (( CONFIG_CMD_DFL | CFG_CMD_DHCP | CFG_CMD_ELF | CFG_CMD_PCI | CFG_CMD_FLS |\
CFG_CMD_MII | CFG_CMD_PING | CFG_CMD_NET | CFG_CMD_JFFS2 | CFG_CMD_ENV | CFG_CMD_PLL| \
CFG_CMD_FLASH | CFG_CMD_LOADS | CFG_CMD_RUN | CFG_CMD_LOADB | CFG_CMD_ELF | CFG_CMD_DDR | CFG_CMD_ETHREG))
*/
/* 091123 - tiger reduced */
#define CONFIG_COMMANDS (CFG_CMD_LOADB | CFG_CMD_MEMORY | CFG_CMD_FLASH | CFG_CMD_NET)
#define CONFIG_IPADDR 192.168.1.1
#define CONFIG_SERVERIP 192.168.1.100
#define CONFIG_ETHADDR 0x00:0xaa:0xbb:0xcc:0xdd:0xee
//lzn
#define CONFIG_ETH1ADDR 00:11:0B:00:00:02
#define CFG_FAULT_ECHO_LINK_DOWN 1
#define CFG_PHY_ADDR 0
#define CFG_AG7240_NMACS 2
#define CFG_GMII 0
#define CFG_MII0_RMII 1
#define CFG_AG7100_GE0_RMII 1
#define CFG_BOOTM_LEN (16 << 20) /* 16 MB */
/* lsz 081222
#define DEBUG
#define CFG_HUSH_PARSER
#define CFG_PROMPT_HUSH_PS2 "hush>"
*/
#undef DEBUG
#undef CFG_HUSH_PARSER
#undef CFG_PROMPT_HUSH_PS2
/*
** Parameters defining the location of the calibration/initialization
** information for the two Merlin devices.
** NOTE: **This will change with different flash configurations**
*/
#if defined(CONFIG_K31)
#define WLANCAL 0x9f3f1000
#else
#define WLANCAL 0xbfff1000
#endif
#define BOARDCAL 0xbfff0000
#define ATHEROS_PRODUCT_ID 137
#define CAL_SECTOR (CFG_MAX_FLASH_SECT - 1)
/* For Merlin, both PCI, PCI-E interfaces are valid */
#define AR7240_ART_PCICFG_OFFSET 12
/* move from autoconf.h of kernel src, added by tiger 20091225 */
/* For GPIO setting
*
* JumpStart LED
*/
#define CONFIG_GPIO_JUMPSTART_LED_BIT 0
#define CONFIG_GPIO_JUMPSTART_LED_ON 0
/*
* Ready Status
*/
#define CONFIG_GPIO_READY_STATUS_BIT 1
#define CONFIG_GPIO_READY_STATUS_ON 0
/*
* USB(TMS) LED
*/
#define CONFIG_GPIO_USB_LED_BIT 8
#define CONFIG_GPIO_USB_LED_ON 0
/*
* Reset Factory Default
*/
#define CONFIG_GPIO_RESET_FAC_BIT 11
#define CONFIG_GPIO_FAC_RST_HOLD_TIME 5
/*
* JumpStart Switch
*/
#define CONFIG_GPIO_JUMPSTART_SW_BIT 12
#include <cmd_confdefs.h>
#endif /* __CONFIG_H */
3. Got build directory:
mv Makefile Makefile.bak
mv Makefile.ap99 Makefile
mkdir /home/YourUserName/images/ap99
make BOARD_TYPE=ap99 uboot
then you will have a u-boot.bin in /home/<YouUserName>/images/ap99.
4. Since the u-boot.bin shall be 128k in length. Use WinHEX or other hexadecimal editor to create a empty project, in my instance I use Winhex, use replace function to fill all bytes with FF and paste the u-boot.bin(Ctrl+A select all, Ctrl+B to write from 0x000000) to the template from the begining so that you got a 128k u-boot with FF appended.
5. Check the back of you router box, write down your MAC and PIN, write the mac and pin to your uboot.bin:
MAC 6 bytes from 0x1FC00
MODEL 8byte from 0x1FD00 (need to check the model flag, it shall be something like 34 20 00 01 00 00 00 01)
PIN 8 bytes from 0x1FE00
Now the u-boot is ready and save it for furture usage.
Part Three: Compile your openwrt firmware:
1. Checkout trunk and update feeds as other common tutorials
2. Modify Openwrt code to support and partition your flash:
2.1. Modify firmware utility so that it can generate firmware up to 8M/16M for you model.
/trunk/tools/firmware-utils/src/mktplinkfw.c
fw_max_len = 0x7c0000 /* for 8M Flash, use 0xfc0000 for 16M flash*/
2.2 Adjust firmware partition for 8M/16M flash.
2013-July-11 udpate: ATTENTION: THIS SECTION 2.2 IS OBSOLETED.
The trunk code has been changed after this tutorial. as discussion in below reply, new probe function can automatically detect and adjust partion size so that you don't need to do anythings. this change affects 12.09 and latest trunk.
////////////////////////////////////keep below codes only for reference, please goto next step.
target/linux/ar71xx/files/arch/mips/ar71xx/mach-tl-mr3x20.c
4M:
.name = "u-boot",
.offset = 0,
.size = 0x020000,
.mask_flags = MTD_WRITEABLE,
}, {
.name = "kernel",
.offset = 0x020000,
.size = 0x140000,
}, {
.name = "rootfs",
.offset = 0x160000,
.size = 0x290000,
}, {
.name = "art",
.offset = 0x3f0000,
.size = 0x010000,
.mask_flags = MTD_WRITEABLE,
}, {
.name = "firmware",
.offset = 0x020000,
.size = 0x3d0000,
}
};
8M:
.name = "u-boot",
.offset = 0,
.size = 0x020000,
.mask_flags = MTD_WRITEABLE,
}, {
.name = "kernel",
.offset = 0x020000,
.size = 0x140000,
}, {
.name = "rootfs",
.offset = 0x160000,
.size = 0x690000,
}, {
.name = "art",
.offset = 0x7f0000,
.size = 0x010000,
.mask_flags = MTD_WRITEABLE,
}, {
.name = "firmware",
.offset = 0x020000,
.size = 0x7d0000,
}
};
16M:
.name = "u-boot",
.offset = 0,
.size = 0x020000,
.mask_flags = MTD_WRITEABLE,
}, {
.name = "kernel",
.offset = 0x020000,
.size = 0x140000,
}, {
.name = "rootfs",
.offset = 0x160000,
.size = 0xe90000,
}, {
.name = "art",
.offset = 0xff0000,
.size = 0x010000,
.mask_flags = MTD_WRITEABLE,
}, {
.name = "firmware",
.offset = 0x020000,
.size = 0xfd0000,
}
};
////////////////////////////////////////////////
3. menuconfig and make your image as common tutorials. save the image openwrt-ar71xx-generic-tl-mr3420-v1-squashfs-factory.bin for future usage.
4. ATTENTION THIS IS IMPORTANT! WITHOUT ART YOU WIRELESS WON'T WORK!
back up your 64k art (wirelss driver data, without it your wireless does not work.) this is important! you can also use the backup one from other tp-link ar7241 chipset routers.
you can't backup your ART within factory firmware web GUI. so there are two ways.
a. Desoder you factory chip. dump whole factory firmware to a file and truncate last 64K byte. man, this is too rough, I prefer the next.
b. From the factory firmware web GUI, flash to a openwrt(any openwrt that works with you current flash unchanged, you can use openwrt official release), use mtd command line to dump ART to a file.
Part Four: Make up a flash programmer file:
1. Use Winhex to create a empty 16M template, use replace to replace all 00 to FF.
2. Open the u-boot.bin previously you created, copy all (Ctrl+A) and Write(Ctrl+b) the 128k bytes from begining to the template.
3. Open the openwrt firmware openwrt-ar71xx-generic-tl-mr3420-v1-squashfs-factory.bin write all data(about 15.75M) as step 2 from 0x000000020000 to the file.
4. Open the art file, write the 64k file to the lastest 64k from 0x000000ff0000 to your template.
5. save all to a new file such as New.bin for future usage.
Part five: Solder the chip
1. Flash the whole file to your flash chip by flash programmer ( you shall have this hardware or ask help from others)
2. Solder the flash and memory chip, 64M RAM can be detected after changing the chip, no need to modify the uboot code to support 64M RAM
3. Solder the TTL pin for TTL debugging.
You will be noticed as below infos are from the boot log in TTL:
AP99 (ar7241 - Virian) U-boot
DRAM:
sri
ar7240_ddr_initial_config(133): virian ddr1 init
#### TAP VALUE 1 = 0xf, 2 = 0x10 [0x0: 0x1f]
64 MB
id read 0x100000ff
sector count = 256
Flash: 16 MB
Using default environment
In: serial
Out: serial
Err: serial
Net: ag7240_enet_initialize...
No valid address in Flash. Using fixed address
No valid address in Flash. Using fixed address
Virian MDC CFG Value ==> 4
: cfg1 0xf cfg2 0x7014
eth0: 00:03:7f:09:0b:ad
eth0 up
Virian MDC CFG Value ==> 4
: cfg1 0xf cfg2 0x7214
eth1: 00:03:7f:09:0b:ad
ATHRS26: resetting s26
ATHRS26: s26 reset done
eth1 up
eth0, eth1
Autobooting in 1 seconds
## Booting image at 9f020000 ...
Uncompressing Kernel Image ... OK
...more logs ....
Creating 5 MTD partitions on "spi0.0":
0x000000000000-0x000000020000 : "u-boot"
0x000000020000-0x000000160000 : "kernel"
0x000000160000-0x000000ff0000 : "rootfs"
mtd: partition "rootfs" set to be root filesystem
mtd: partition "rootfs_data" created automatically, ofs=3A0000, len=C50000
0x0000003a0000-0x000000ff0000 : "rootfs_data"
0x000000ff0000-0x000001000000 : "art"
0x000000020000-0x000000ff0000 : "firmware"
...more logs ....
NOW YOU GOT A UPGRADED ROUTER! ENJOY!
(Last edited by pupie on 11 Jul 2013, 04:20)