TP-LINK 845N V1与TP-LINK 841N V8硬件部分基本一样,差别在于Flash、RAM容量。手头的TP-LINK 845N V1的Flash是2M的Winbond 25Q16BVSIG,RAM是16M的Zentel A3S28D40FTP-G5。平常运行不算稳定,特别夏天的时候无线很容易挂掉。学了一段时间OpenWRT以后决定对路由器进行软硬件方面的修改。硬件方面把RAM换成64M的HY5DU121622DTP-D43,Flash换成16M的MX25L12835F,引出USB接口,USB供电使用LM2596可调降压模块。软件方面自己ubuntu下修改编译支持845N V1的OpenWRT固件。
一、硬改部分
先换内存,换上以后再测试是否还能正常启动,如果不能正常启动有可能是内存芯片没焊好,还有可能是电路板少了R63这颗贴片电阻。因当时焊了几次内存都不行,google了下845N V1的拆机图,跟图对比的下发现少了R63这个电阻,阻值不清楚,参考R62阻值51Ω,焊到R63上,结果开机OK。(手头的贴片电阻没那么小的,用了一个大一点点的贴片电阻+0Ω电阻立起来焊接),如下图:
内存换成功以后,就可以开始换Flash。先拆掉原来的flash芯片,用CH341A编程器读出原有的固件。目的是要得到art无线校正数据。为了无线能正常工作,art数据是必须的,art数据在原固件的最后64KiB部分。然后编译出来的uboot、openwrt factory固件、art数据合成一个完整的16MiB的编程器固件(uboot、openwrt编译以及合并成编程器固件见第二部分),用编程器刷入flash芯片换上。正常无误的话上电就能启动openwrt系统了。
接着就是刮出USB的D+、D-引线。取下散热片。845N V1用的CPU是AR9341。查datasheet和网络上找的图,确定usb引脚的位置,如下图:
用美工刀慢慢的刮,本人第一次刮没什么经验,花了2个钟头才刮好。挖开后,用0.1毫米的漆包线焊接,将D+、D-引出。注意:引脚非常小,焊完用万用表量下是否短路或者是否有焊接上。D+、D-跟D-旁边那根线间电阻,本人量的下貌似都是几兆欧。
引出usb数据线后,接上LM2596电源模块和USB母口,USB母口的外壳接地,调整usb电源模块输出5V。接线图如下:
usb的D+、D-引出后,换好点的粗线,然后热熔胶粘上:
最后整体图:
接线都完成后,上电待系统启动完成,ssh登录路由。插上u盘,ls /dev看看有没有识别到u盘。也可以用dmesg命令查看内核调试信息,这之中就有会有跟usb相关的信息。
二、软改部分
OpenWRT没有原生支持TP-LINK 845N V1,只因Flash、RAM太小了。因此软件部分必须自己修改编译。从svn co svn://svn.openwrt.org/openwrt/trunk/下载源码。版本r40804。2014年5月21日下载好的。
2.1、修改target/linux/ar71xx/generic/profiles/tp-link.mk,找到$(eval $(call Profile,TLWR842)),在此之下添加:
define Profile/TLWR845 NAME:=TP-LINK TL-WR845N PACKAGES:=kmod-usb-core kmod-usb2 kmod-ledtrig-usbdev endef define Profile/TLWR845/Description Package set optimized for the TP-LINK TL-WR845N. endef $(eval $(call Profile,TLWR845))
2.2、修改target/linux/ar71xx/base-files/lib/ar71xx.sh,找到
"084200"*) model="TP-Link TL-WR842N/ND" ;;在此之下添加:
"084500"*) model="TP-Link TL-WR845N" ;;再找到:
*"TL-WR842N/ND v2") name="tl-wr842n-v2" ;;在此之下添加:
*"TL-WR845N v1") name="tl-wr845n-v1" ;;
2.3、修改target/linux/ar71xx/base-files/lib/upgrade/platform.sh,找到
tl-wr841n-v8 | \ tl-wr841n-v9 | \ tl-wr842n-v2 | \
在此之下添加:
tl-wr845n-v1 | \
2.4、修改arget/linux/ar71xx/base-files/etc/uci-defaults/01_leds,找到
tl-wa801nd-v2 | \ tl-wa901nd-v3)
在此之上(是这之上),添加
tl-wr845n-v1) ucidef_set_led_netdev "wan" "WAN" "tp-link:green:wan" "eth0" ucidef_set_led_switch "lan1" "LAN1" "tp-link:green:lan1" "switch0" "0x02" ucidef_set_led_switch "lan2" "LAN2" "tp-link:green:lan2" "switch0" "0x04" ucidef_set_led_switch "lan3" "LAN3" "tp-link:green:lan3" "switch0" "0x08" ucidef_set_led_switch "lan4" "LAN4" "tp-link:green:lan4" "switch0" "0x10" ucidef_set_led_wlan "wlan" "WLAN" "tp-link:green:wlan" "phy0tpt" ucidef_set_led_usbdev "usb" "USB" "tp-link:green:qss" "1-1" ;;注:这里用845N V1的QSS那个灯(就是最后一个锁标志的那个)来当USB的指示灯。因刷openwrt后qss灯基本没有用处,因此可以当usb指示灯用。另外lan1、lan2、lan3、lan4的端口顺序依次是0x02、0x04、0x08、0x10,否则导致led灯与路由器后面的wan、lan口对应不上。部分信息可参看后面的mach-tl-wr845n-v1.c文件。
2.5、修改target/linux/ar71xx/base-files/etc/uci-defaults/02_network,找到
tl-mr3420-v2 |\ tl-wr841n-v8 |\ tl-wr842n-v2 |\在此之下添加
tl-wr845n-v1 |\
2.6、修改target/linux/ar71xx/base-files/etc/diag.sh,找到
tl-wr841n-v7 | \ tl-wr841n-v8 | \ tl-wr842n-v2 | \
在此之下添加
tl-wr845n-v1 | \2.7、修改target/linux/ar71xx/image/Makefile,找到
$(eval $(call SingleProfile,TPLINK-LZMA,64kraw,TLWR841NV8,tl-wr841n-v8,TL-WR841N-v8,ttyS0,115200,0x08410008,1,4Mlzma)) $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,TLWR841NV9,tl-wr841n-v9,TL-WR841N-v9,ttyS0,115200,0x08410009,1,4Mlzma)) $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,TLWR842V2,tl-wr842n-v2,TL-WR842N-v2,ttyS0,115200,0x8420002,1,8Mlzma))在此之下添加
$(eval $(call SingleProfile,TPLINK-LZMA,64kraw,TLWR845V1,tl-wr845n-v1,TL-WR845N-v1,ttyS0,115200,0x8450001,1,16Mlzma)注:因使用的是16M的Flash,所以是16Mlzma。然后再找到
$(eval $(call MultiProfile,TLWR743,TLWR743NV1 TLWR743NV2)) $(eval $(call MultiProfile,TLWR841,TLWR841NV15 TLWR841NV3 TLWR841NV5 TLWR841NV7 TLWR841NV8 TLWR841NV9)) $(eval $(call MultiProfile,TLWR842,TLWR842V1 TLWR842V2))在此之下添加
$(eval $(call MultiProfile,TLWR845,TLWR845V1))
2.8、修改target/linux/ar71xx/base-files/lib/preinit/05_set_preinit_iface_ar71xx,找到
tl-wr720n-v3 |\ tl-wr841n-v8 |\ tl-wr842n-v2 |\
在此之下添加
tl-wr845n-v1 |\2.9、修改target/linux/ar71xx/config-3.10,找到
CONFIG_ATH79_MACH_TL_WR841N_V1=y CONFIG_ATH79_MACH_TL_WR841N_V8=y CONFIG_ATH79_MACH_TL_WR841N_V9=y在此之下添加
CONFIG_ATH79_MACH_TL_WR845N_V1=y
2.10、在target/linux/ar71xx/files/arch/mips/ath79/下新建文件mach-tl-wr845n-v1.c,文件内容如下:
/* * TP-LINK TL-WR845N v1 board support * * Copyright (C) 2012 Gabor Juhos <[email protected]> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. */ #include <linux/gpio.h> #include <linux/platform_device.h> #include <asm/mach-ath79/ath79.h> #include <asm/mach-ath79/ar71xx_regs.h> #include "common.h" #include "dev-eth.h" #include "dev-gpio-buttons.h" #include "dev-leds-gpio.h" #include "dev-m25p80.h" #include "dev-usb.h" #include "dev-wmac.h" #include "machtypes.h" #define TL_WR845NV1_GPIO_LED_WLAN 13 #define TL_WR845NV1_GPIO_LED_QSS 15 #define TL_WR845NV1_GPIO_LED_WAN 18 #define TL_WR845NV1_GPIO_LED_LAN1 19 #define TL_WR845NV1_GPIO_LED_LAN2 20 #define TL_WR845NV1_GPIO_LED_LAN3 21 #define TL_WR845NV1_GPIO_LED_LAN4 12 #define TL_WR845NV1_GPIO_LED_SYSTEM 14 #define TL_WR845NV1_GPIO_BTN_RESET 17 #define TL_WR845NV1_GPIO_SW_RFKILL 16 /* WPS for MR3420 v2 */ #define TL_MR3420V2_GPIO_LED_3G 11 #define TL_MR3420V2_GPIO_USB_POWER 4 #define TL_WR845NV1_KEYS_POLL_INTERVAL 20 /* msecs */ #define TL_WR845NV1_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR845NV1_KEYS_POLL_INTERVAL) static const char *tl_wr845n_v1_part_probes[] = { "tp-link", NULL, }; static struct flash_platform_data tl_wr845n_v1_flash_data = { .part_probes = tl_wr845n_v1_part_probes, }; static struct gpio_led tl_wr845n_v1_leds_gpio[] __initdata = { { .name = "tp-link:green:lan1", .gpio = TL_WR845NV1_GPIO_LED_LAN1, .active_low = 1, }, { .name = "tp-link:green:lan2", .gpio = TL_WR845NV1_GPIO_LED_LAN2, .active_low = 1, }, { .name = "tp-link:green:lan3", .gpio = TL_WR845NV1_GPIO_LED_LAN3, .active_low = 1, }, { .name = "tp-link:green:lan4", .gpio = TL_WR845NV1_GPIO_LED_LAN4, .active_low = 1, }, { .name = "tp-link:green:qss", .gpio = TL_WR845NV1_GPIO_LED_QSS, .active_low = 1, }, { .name = "tp-link:green:system", .gpio = TL_WR845NV1_GPIO_LED_SYSTEM, .active_low = 1, }, { .name = "tp-link:green:wan", .gpio = TL_WR845NV1_GPIO_LED_WAN, .active_low = 1, }, { .name = "tp-link:green:wlan", .gpio = TL_WR845NV1_GPIO_LED_WLAN, .active_low = 1, } }; static struct gpio_keys_button tl_wr845n_v1_gpio_keys[] __initdata = { { .desc = "Reset button", //QSS/RESET按钮 .type = EV_KEY, .code = KEY_RESTART, .debounce_interval = TL_WR845NV1_KEYS_DEBOUNCE_INTERVAL, .gpio = TL_WR845NV1_GPIO_BTN_RESET, .active_low = 1, } }; static void __init tl_ap123_setup(void) { u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); /* Disable JTAG, enabling GPIOs 0-3 */ /* Configure OBS4 line, for GPIO 4*/ ath79_gpio_function_setup(AR934X_GPIO_FUNC_JTAG_DISABLE, AR934X_GPIO_FUNC_CLK_OBS4_EN); /* config gpio4 as normal gpio function */ ath79_gpio_output_select(TL_MR3420V2_GPIO_USB_POWER, AR934X_GPIO_OUT_GPIO); ath79_register_m25p80(&tl_wr845n_v1_flash_data); ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_SW_ONLY_MODE); //改AR934X_ETH_CFG_SW_PHY_SWAP为AR934X_ETH_CFG_SW_ONLY_MODE ath79_register_mdio(1, 0x0); ath79_init_mac(ath79_eth0_data.mac_addr, mac, -1); ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); /* GMAC0 is connected to the PHY0 of the internal switch */ //修正lan1会变成wan,lan2变成lan1,wan口变成lan4的问题。 ath79_switch_data.phy4_mii_en = 1; ath79_switch_data.phy_poll_mask = BIT(4); ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; ath79_eth0_data.phy_mask = BIT(4); ath79_eth0_data.mii_bus_dev = &ath79_mdio1_device.dev; ath79_register_eth(0); /* GMAC1 is connected to the internal switch */ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; ath79_register_eth(1); ath79_register_wmac(ee, mac); } static void __init tl_wr845n_v1_setup(void) { tl_ap123_setup(); ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr845n_v1_leds_gpio), tl_wr845n_v1_leds_gpio); ath79_register_gpio_keys_polled(1, TL_WR845NV1_KEYS_POLL_INTERVAL, ARRAY_SIZE(tl_wr845n_v1_gpio_keys), tl_wr845n_v1_gpio_keys); /* enable power for the USB port */ gpio_request_one(TL_MR3420V2_GPIO_USB_POWER, GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, "USB power"); ath79_register_usb(); //加上,我们要usb功能 } MIPS_MACHINE(ATH79_MACH_TL_WR845N_V1, "TL-WR845N-v1", "TP-LINK TL-WR845N v1", tl_wr845n_v1_setup);
2.11、修改tools/firmware-utils/src/mktplinkfw.c,添加“HWID_TL_WR845N_V1”宏定义,然后将16M的布局中的fw_max_len都改成0xfc0000,如下所示:
#define HWID_TL_WR845N_V1 0x08450001
}, { .id = "16M", .fw_max_len = 0xfc0000, .kernel_la = 0x80060000, .kernel_ep = 0x80060000, .rootfs_ofs = 0x140000, }, { .id = "16Mlzma", .fw_max_len = 0xfc0000, .kernel_la = 0x80060000, .kernel_ep = 0x80060000, .rootfs_ofs = 0x100000, }, { .id = "16Mppc", .fw_max_len = 0xfc0000, .kernel_la = 0x00000000, .kernel_ep = 0xc0000000, .rootfs_ofs = 0x2a0000, }, { /* terminating entry */ }然后再在boards数组中找到
{ .id = "TL-WR941NDv2", .hw_id = HWID_TL_WR941ND_V2, .hw_rev = 2,
在此之上(注:之上)添加一条845Nv1相关部分的代码,修改后如下:
}, { .id = "TL-WR841NDv7", .hw_id = HWID_TL_WR841ND_V7, .hw_rev = 1, .layout_id = "4M", }, { .id = "TL-WR845Nv1", .hw_id = HWID_TL_WR845N_V1, .hw_rev = 1, .layout_id = "16Mlzma", }, { .id = "TL-WR941NDv2", .hw_id = HWID_TL_WR941ND_V2, .hw_rev = 2, .layout_id = "4M", }, {2.12、在target/linux/ar71xx/patches-3.10/下创建文件999-MIPS-ath79-add-845nv1-support.patch,文件内容如下:
--- a/arch/mips/ath79/Kconfig 2014-05-29 10:36:56.000000000 +0800 +++ b/arch/mips/ath79/Kconfig 2014-05-30 09:08:42.699124426 +0800 @@ -725,6 +725,16 @@ select ATH79_DEV_M25P80 select ATH79_DEV_WMAC +config ATH79_MACH_TL_WR845N_V1 + bool "TP-LINK TL-WR845N v1 support" + select SOC_AR934X + select ATH79_DEV_ETH + select ATH79_DEV_GPIO_BUTTONS + select ATH79_DEV_LEDS_GPIO + select ATH79_DEV_M25P80 + select ATH79_DEV_USB + select ATH79_DEV_WMAC + config ATH79_MACH_TL_WR941ND bool "TP-LINK TL-WR941ND support" select SOC_AR913X --- a/arch/mips/ath79/machtypes.h 2014-05-29 10:36:56.000000000 +0800 +++ b/arch/mips/ath79/machtypes.h 2014-05-30 09:10:35.431127534 +0800 @@ -126,6 +126,7 @@ ATH79_MACH_TL_WR841N_V8, /* TP-LINK TL-WR841N/ND v8 */ ATH79_MACH_TL_WR841N_V9, /* TP-LINK TL-WR841N/ND v9 */ ATH79_MACH_TL_WR842N_V2, /* TP-LINK TL-WR842N/ND v2 */ + ATH79_MACH_TL_WR845N_V1, /* TP-LINK TL-WR845N v1 */ ATH79_MACH_TL_WR941ND, /* TP-LINK TL-WR941ND */ ATH79_MACH_UBNT_AIRROUTER, /* Ubiquiti AirRouter */ ATH79_MACH_UBNT_BULLET_M, /* Ubiquiti Bullet M */ --- a/arch/mips/ath79/Makefile 2014-05-29 10:36:56.000000000 +0800 +++ b/arch/mips/ath79/Makefile 2014-05-30 09:18:14.711140199 +0800 @@ -101,6 +101,7 @@ obj-$(CONFIG_ATH79_MACH_TL_WR841N_V1) += mach-tl-wr841n.o obj-$(CONFIG_ATH79_MACH_TL_WR841N_V8) += mach-tl-wr841n-v8.o obj-$(CONFIG_ATH79_MACH_TL_WR841N_V9) += mach-tl-wr841n-v9.o +obj-$(CONFIG_ATH79_MACH_TL_WR845N_V1) += mach-tl-wr845n-v1.o obj-$(CONFIG_ATH79_MACH_TL_WR941ND) += mach-tl-wr941nd.o obj-$(CONFIG_ATH79_MACH_TL_WR1041N_V2) += mach-tl-wr1041n-v2.o obj-$(CONFIG_ATH79_MACH_TL_WR1043ND) += mach-tl-wr1043nd.o
至此文件都修改完成。make menuconfig,对编译前进行配置。把Build the OpenWrt based Toolchain选上,在编译uboot要用的到。其他可选的软件包可以参考《编译HG255D的openwrt固件》,选好之后make V=s编译。编译完成后在bin/ar71xx/会得到openwrt-ar71xx-generic-tl-wr845n-v1-squashfs-factory.bin和openwrt-ar71xx-generic-tl-wr845n-v1-squashfs-sysupgrade.bin,前者在制作编程器固件会用到,后者在以后对openwrt系统升级会用到。还有一个OpenWrt-Toolchain-ar71xx-for-mips_34kc-gcc-4.8-linaro_uClibc-0.9.33.2.tar.bz2,这个在编译uboot会用到。其他的文件不用理会。
有了OpenWrt-Toolchain-ar71xx-for-mips_34kc-gcc-4.8-linaro_uClibc-0.9.33.2.tar.bz2就可以编译uboot了,去下载u-boot_mod源码https://github.com/pepe2k/u-boot_mod,在u-boot_mod源码下创建toolchain目录,把OpenWrt-Toolchain-ar71xx-for-mips_34kc-gcc-4.8-linaro_uClibc-0.9.33.2.tar.bz2解压到此toolchain目录下,如图
修改u-boot_mod目录下的Makefile文件,找到
export MAKECMD=make --silent ARCH=mips CROSS_COMPILE=mips-linux-gnu-修改添加
export MAKECMD=make --silent ARCH=mips CROSS_COMPILE=mips-openwrt-linux-uclibc- export PATH:=$(BUILD_TOPDIR)/toolchain/bin/:$(PATH)然后make tplink_wr841n_v8编译uboot固件,得到uboot_for_tp-link_tl-wr841n_v8.bin文件,大小64KiB。
三、制作编程器固件
拷贝uboot_for_tp-link_tl-wr841n_v8.bin为uboot.bin并用0xFF填充成128KiB大小。在0x1fc00处填入6字节原路由器的mac地址。在0x1fd00处填入8字节数据08 45 00 01 00 00 00 01。在0x1fe00处填入原路由的pin码字符串(8字节)。845n v1的编程器固件=uboot.bin(128k)+openwrt-ar71xx-generic-tl-wr845n-v1-squashfs-factory.bin(16128k)+64k的0xFF填充+64k原路由的art,得到的固件刚好16M,直接用编程器烧录Flash芯片。
四、OpenWrt运行图