最近折腾 TL-MR10U, 可直接刷 WR703N 固件, 不过 USB 不能供电, 网络, LED 正常. 所以需要修复下. 记录+教程.

假定已经有了完整 OpenWrt 开发环境. 包括编辑器, 配置好的 quilt 工具.

经过本人实践, 当前(20130522)在互联网上能找到的大部分教程都不靠谱, 或多或少有错误或者坑, 有的干脆就是错的.

配置开发环境

请参考其他文献设置开发环境. 前几篇恰好写过.

简单介绍下 quilt 工具, quilt 是用来管理代码树中的 patch 的, 嵌入式内核开发利器!

请通过软件包管理器安装 quilt. 然后写入以下配置文件到 ~/.quiltrc , 另外需要 export EDITOR="你编辑利器" .

QUILT_DIFF_ARGS="--no-timestamps --no-index -pab --color=auto"
QUILT_REFRESH_ARGS="--no-timestamps --no-index -pab"
QUILT_PATCH_OPTS="--unified"
QUILT_DIFF_OPTS="-p"
EDITOR="emacs --no-init --quick"

准备工作

假定 ~/openwrt 是你的开发目录, 建议直接在 git branch 下开发.

假设之前已经编译过 bin, 有完整的 .config 和 toolchain.

建立开发 branch: (git 教程自行脑补)

~/openwrt$ git checkout -b add-tl-mr10u-support

清理 tmp 目录!!!!!! 这个是大坑. 直接删除.

~/openwrt$ rm -rvf tmp/

修改 OpenWrt 代码

进入设备硬件目录:

~/openwrt$ cd target/linux/ar71xx

修改以下文件, 里面涉及到 TL-MR10U 固件中设备ID的部分, 是 0x00100101, 这个值从 tp-link 官方网站下载的固件中可以获得.

  • base-files/etc/
  • base-files/etc/uci-defaults/02_network
  • base-files/lib/ar71xx.sh
  • base-files/lib/upgrade/platform.sh
  • config-3.8
  • generic/profiles/tp-link.mk
  • image/Makefile

新建文件: files/arch/mips/ath79/mach-tl-mr10u.c , 内容参考 TL-WR703N 设备的文件 mach-tl-wr703n.c, 修改所有出现 wr703n, WR703N 等等大小写混合的部分, emacs 无痛苦完成.

添加 Linux patch

这里就完成了 OpenWrt 的设备支持代码. 为了支持我们的设备, Linux 代码树的部分文件也需要做改动, OpenWrt 采用了 patch 的方式实现.

回退到根目录 ~/openwrt .

清理并准备 patch 树:

~/openwrt$ make target/linux/{clean,prepare} # 后面可加 V=s QUILT=1 参数, 表示静默无输出

进入内核代码目录(其中版本号可能与你的不一致):

~/openwrt$ cd build_dir/target-mips_r2_uClibc-0.9.33.2/linux-ar71xx_generic/linux-3.8.12/

这里就是内核代码树了, 里面的代码是已经打过所有 patch 的, 可以用 quilt push 检查看是不是这样:

$ quilt push
File series fully applied, ends at patch platform/902-unaligned_access_hacks.patch

这条输入也告诉我们, 当前最顶的 patch 是 platform/902 (这个是坑啊, 官方文档不带 platform 前缀, 是错的).

为我们的 TL-MR10U 新建个 patch:

$ quilt new platform/920-add-tl-mr10u-support.patch

选择的数字需要大于刚才的那个 902, 然后 quilt 会自动把这个 patch 设置为当前 patch, 所有的改动都针对这个 patch.

然后就是增加代码了

$ quilt edit arch/mips/ath79/Kconfig
$ quilt edit arch/mips/ath79/Makefile
$ quilt edit arch/mips/ath79/machtypes.h

至于怎么改, 参考这些文件里其他硬件的配置, 基本上说 copy TL-WR703N 的就可以了. 保证不重不漏.

然后验证下修改的内容:

$ quilt diff # 查看 diff
$ quilt refresh # 保存所有 diff 到 patch 文件

这个时候我们的 patch 文件还在 build_dir 里, 大概位置是 patches/platform/ 下. 需要同步到 OpenWrt 代码树.

# 退回到顶层工作目录, 执行:
~/openwrt$ make target/linux/update V=s

同步完成后, patch 文件会出现在 target/linux/ar71xx/patches-3.8/ 下.

固件工具代码修改

OpenWrt 包含一个 TP-LINK 固件小工具, tools/firmware-utils/src/mktplinkfw.c , 里面包含 TP-LINK 固件 bin 文件的结构和 md5 hash 验证算法.

修改内容参考 WR703N 就好.

查看效果

这里应该已经完成了所有操作. 可以编译了

# 再次记得, 删除 tmp 目录
~/openwrt$ rm -rvf tmp/
~/openwrt$ make menuconfig
.....
自己编译

所有修改文件

diff --git a/target/linux/ar71xx/base-files/etc/ b/target/linux/ar71xx/base-files/etc/
index ed269b2..c279cb3 100755
--- a/target/linux/ar71xx/base-files/etc/
+++ b/target/linux/ar71xx/base-files/etc/
@@ -134,6 +134,7 @@ get_status_led() {
;;
tl-wdr4300 | \
tl-wr703n | \
+       tl-mr10u | \
tl-wr720n-v3)
status_led="tp-link:blue:system"
;;
diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/02_network b/target/linux/ar71xx/base-files/etc/uci-defaults/02_network
index a9a3ff2..01733d9 100755
--- a/target/linux/ar71xx/base-files/etc/uci-defaults/02_network
+++ b/target/linux/ar71xx/base-files/etc/uci-defaults/02_network
@@ -200,6 +200,7 @@ tl-mr3040 |\
tl-wa901nd |\
tl-wa901nd-v2 |\
tl-wr703n |\
+tl-mr10u |\
wndap360 |\
wp543)
ucidef_set_interface_lan "eth0"
diff --git a/target/linux/ar71xx/base-files/lib/ar71xx.sh b/target/linux/ar71xx/base-files/lib/ar71xx.sh
index 194a40b..2ba26e5 100755
--- a/target/linux/ar71xx/base-files/lib/ar71xx.sh
+++ b/target/linux/ar71xx/base-files/lib/ar71xx.sh
@@ -132,6 +132,9 @@ tplink_board_detect() {
"254300"*)
model="TP-Link TL-WR2543N/ND"
;;
+       "100101"*)
+               model="TP-Link TL-MR10U"
+               ;;
"110101"*)
model="TP-Link TL-MR11U"
;;
@@ -441,6 +444,9 @@ ar71xx_board_detect() {
*"TL-WR720N v3")
name="tl-wr720n-v3"
;;
+       *"TL-MR10U")
+               name="tl-mr10u"
+               ;;
*"TL-MR11U")
name="tl-mr11u"
;;
diff --git a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh
index 817123b..8838234 100755
--- a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh
@@ -154,6 +154,7 @@ platform_check_image() {
platform_check_image_openmesh "$magic_long" "$1" && return 0
return 1
;;
+       tl-mr10u | \
tl-mr11u | \
tl-mr3020 | \
tl-mr3040 | \
diff --git a/target/linux/ar71xx/config-3.8 b/target/linux/ar71xx/config-3.8
index ea2be6b..389799d 100644
--- a/target/linux/ar71xx/config-3.8
+++ b/target/linux/ar71xx/config-3.8
@@ -61,6 +61,7 @@ CONFIG_ATH79_MACH_RW2458N=y
CONFIG_ATH79_MACH_TEW_632BRP=y
CONFIG_ATH79_MACH_TEW_673GRU=y
CONFIG_ATH79_MACH_TEW_712BR=y
+CONFIG_ATH79_MACH_TL_MR10U=y
CONFIG_ATH79_MACH_TL_MR11U=y
CONFIG_ATH79_MACH_TL_MR3020=y
CONFIG_ATH79_MACH_TL_MR3X20=y
diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr10u.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr10u.c
new file mode 100644
index 0000000..e3906e1
--- /dev/null
+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr10u.c
@@ -0,0 +1,89 @@
+/*
+ *  TP-LINK TL-MR10U board support
+ *
+ *  Copyright (C) 2011 dongyuqi <729650915@>
+ *  Copyright (C) 2013 andelf <andelf@>
+ *
+ *  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 <asm/mach-ath79/ath79.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_MR10U_GPIO_LED_SYSTEM       27
+#define TL_MR10U_GPIO_BTN_RESET        11
+
+#define TL_MR10U_GPIO_USB_POWER        8
+
+#define TL_MR10U_KEYS_POLL_INTERVAL    20      /* msecs */
+#define TL_MR10U_KEYS_DEBOUNCE_INTERVAL        (3 * TL_MR10U_KEYS_POLL_INTERVAL)
+
+static const char *tl_mr10u_part_probes[] = {
+       "tp-link",
+       NULL,
+};
+
+static struct flash_platform_data tl_mr10u_flash_data = {
+       .part_probes    = tl_mr10u_part_probes,
+};
+
+static struct gpio_led tl_mr10u_leds_gpio[] __initdata = {
+       {
+               .name           = "tp-link:blue:system",
+               .gpio           = TL_MR10U_GPIO_LED_SYSTEM,
+               .active_low     = 1,
+       },
+};
+
+static struct gpio_keys_button tl_mr10u_gpio_keys[] __initdata = {
+       {
+               .desc           = "reset",
+               .type           = EV_KEY,
+               .code           = KEY_RESTART,
+               .debounce_interval = TL_MR10U_KEYS_DEBOUNCE_INTERVAL,
+               .gpio           = TL_MR10U_GPIO_BTN_RESET,
+               .active_low     = 0,
+       }
+};
+
+static void __init tl_mr10u_setup(void)
+{
+       u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
+       u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
+
+       /* disable PHY_SWAP and PHY_ADDR_SWAP bits */
+       ath79_setup_ar933x_phy4_switch(false, false);
+
+       ath79_register_m25p80(&tl_mr10u_flash_data);
+       ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_mr10u_leds_gpio),
+                                tl_mr10u_leds_gpio);
+       ath79_register_gpio_keys_polled(-1, TL_MR10U_KEYS_POLL_INTERVAL,
+                                       ARRAY_SIZE(tl_mr10u_gpio_keys),
+                                       tl_mr10u_gpio_keys);
+
+       gpio_request_one(TL_MR10U_GPIO_USB_POWER,
+                        GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED,
+                        "USB power");
+       ath79_register_usb();
+
+       ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0);
+
+       ath79_register_mdio(0, 0x0);
+       ath79_register_eth(0);
+
+       ath79_register_wmac(ee, mac);
+}
+
+MIPS_MACHINE(ATH79_MACH_TL_MR10U, "TL-MR10U", "TP-LINK TL-MR10U",
+            tl_mr10u_setup);
diff --git a/target/linux/ar71xx/generic/profiles/tp-link.mk b/target/linux/ar71xx/generic/profiles/tp-link.mk
index 4ac6ba9..3057cfa 100644
--- a/target/linux/ar71xx/generic/profiles/tp-link.mk
+++ b/target/linux/ar71xx/generic/profiles/tp-link.mk
@@ -5,6 +5,17 @@
# See /LICENSE for more information.
#
 
+define Profile/TLMR10U
+       NAME:=TP-LINK TL-MR10U
+       PACKAGES:=kmod-usb-core kmod-usb2
+endef
+
+define Profile/TLMR10U/Description
+       Package set optimized for the TP-LINK TL-MR10U.
+endef
+$(eval $(call Profile,TLMR10U))
+
+
define Profile/TLMR11U
NAME:=TP-LINK TL-MR11U
PACKAGES:=kmod-usb-core kmod-usb2 kmod-ledtrig-usbdev
diff --git a/target/linux/ar71xx/image/Makefile b/target/linux/ar71xx/image/Makefile
index c6b4dc4..d0485b0 100644
--- a/target/linux/ar71xx/image/Makefile
+++ b/target/linux/ar71xx/image/Makefile
@@ -927,6 +927,7 @@ $(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLWR941NV3,tl-wr941nd-v3,TL-WR94
$(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLWR941NV4,tl-wr941nd-v4,TL-WR741ND,ttyS0,115200,0x09410004,1,4M))
$(eval $(call SingleProfile,TPLINK,$(fs_64kraw),TLWR1043,tl-wr1043nd-v1,TL-WR1043ND,ttyS0,115200,0x10430001,1,8M))
 
+$(eval $(call SingleProfile,TPLINK-LZMA,$(fs_64kraw),TLMR10U,tl-mr10u-v1,TL-MR10U,ttyATH0,115200,0x00100101,1,4Mlzma))
$(eval $(call SingleProfile,TPLINK-LZMA,$(fs_64kraw),TLMR11UV1,tl-mr11u-v1,TL-MR11U,ttyATH0,115200,0x00110101,1,4Mlzma))
$(eval $(call SingleProfile,TPLINK-LZMA,$(fs_64kraw),TLMR11UV2,tl-mr11u-v2,TL-MR11U,ttyATH0,115200,0x00110102,1,4Mlzma))
$(eval $(call SingleProfile,TPLINK-LZMA,$(fs_64kraw),TLMR3020,tl-mr3020-v1,TL-MR3020,ttyATH0,115200,0x30200001,1,4Mlzma))
diff --git a/target/linux/ar71xx/patches-3.8/920-add_tl-mr10u_support.patch b/target/linux/ar71xx/patches-3.8/920-add_tl-mr10u_support.patch
new file mode 100644
index 0000000..26e8a00
--- /dev/null
+++ b/target/linux/ar71xx/patches-3.8/920-add_tl-mr10u_support.patch
@@ -0,0 +1,39 @@
+--- a/arch/mips/ath79/Kconfig
++++ b/arch/mips/ath79/Kconfig
+@@ -495,6 +495,16 @@ config ATH79_MACH_EAP7660D
+       select ATH79_DEV_LEDS_GPIO
+       select ATH79_DEV_M25P80
+
++config ATH79_MACH_TL_MR10U
++      bool "TP-LINK TL-MR10U support"
++      select SOC_AR933X
++      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_MR11U
+       bool "TP-LINK TL-MR11U/TL-MR3040 support"
+       select SOC_AR933X
+--- a/arch/mips/ath79/Makefile
++++ b/arch/mips/ath79/Makefile
+@@ -77,6 +77,7 @@ obj-$(CONFIG_ATH79_MACH_RW2458N)     += mach
+ obj-$(CONFIG_ATH79_MACH_TEW_632BRP)   += mach-tew-632brp.o
+ obj-$(CONFIG_ATH79_MACH_TEW_673GRU)   += mach-tew-673gru.o
+ obj-$(CONFIG_ATH79_MACH_TEW_712BR)    += mach-tew-712br.o
++obj-$(CONFIG_ATH79_MACH_TL_MR10U)     += mach-tl-mr10u.o
+ obj-$(CONFIG_ATH79_MACH_TL_MR11U)     += mach-tl-mr11u.o
+ obj-$(CONFIG_ATH79_MACH_TL_MR3020)    += mach-tl-mr3020.o
+ obj-$(CONFIG_ATH79_MACH_TL_MR3X20)    += mach-tl-mr3x20.o
+--- a/arch/mips/ath79/machtypes.h
++++ b/arch/mips/ath79/machtypes.h
+@@ -78,6 +78,7 @@ enum ath79_mach_type {
+       ATH79_MACH_TEW_632BRP,          /* TRENDnet TEW-632BRP */
+       ATH79_MACH_TEW_673GRU,          /* TRENDnet TEW-673GRU */
+       ATH79_MACH_TEW_712BR,           /* TRENDnet TEW-712BR */
++      ATH79_MACH_TL_MR10U,            /* TP-LINK TL-MR10U */
+       ATH79_MACH_TL_MR11U,            /* TP-LINK TL-MR11U */
+       ATH79_MACH_TL_MR3020,           /* TP-LINK TL-MR3020 */
+       ATH79_MACH_TL_MR3040,           /* TP-LINK TL-MR3040 */
diff --git a/tools/firmware-utils/src/mktplinkfw.c b/tools/firmware-utils/src/mktplinkfw.c
index 74a55fd..7596e03 100644
--- a/tools/firmware-utils/src/mktplinkfw.c
+++ b/tools/firmware-utils/src/mktplinkfw.c
@@ -43,6 +43,7 @@
#define HWID_TL_WA901ND_V1     0x09010001
#define HWID_TL_WA901ND_V2     0x09010002
#define HWID_TL_WDR4900_V1     0x49000001
+#define HWID_TL_MR10U_V1       0x00100101
#define HWID_TL_WR703N_V1      0x07030101
#define HWID_TL_WR720N_V3      0x07200103
#define HWID_TL_WR741ND_V1     0x07410001
@@ -338,6 +339,11 @@ static struct board_info boards[] = {
.hw_rev         = 1,
.layout_id      = "4Mlzma",
}, {
+               .id             = "TL-MR10Uv1",
+               .hw_id          = HWID_TL_MR10U_V1,
+--- a/arch/mips/ath79/machtypes.h
++++ b/arch/mips/ath79/machtypes.h
+@@ -78,6 +78,7 @@ enum ath79_mach_type {
+       ATH79_MACH_TEW_632BRP,          /* TRENDnet TEW-632BRP */
+       ATH79_MACH_TEW_673GRU,          /* TRENDnet TEW-673GRU */
+       ATH79_MACH_TEW_712BR,           /* TRENDnet TEW-712BR */
++      ATH79_MACH_TL_MR10U,            /* TP-LINK TL-MR10U */
+       ATH79_MACH_TL_MR11U,            /* TP-LINK TL-MR11U */
+       ATH79_MACH_TL_MR3020,           /* TP-LINK TL-MR3020 */
+       ATH79_MACH_TL_MR3040,           /* TP-LINK TL-MR3040 */
diff --git a/tools/firmware-utils/src/mktplinkfw.c b/tools/firmware-utils/src/mktplinkfw.c
index 74a55fd..7596e03 100644
--- a/tools/firmware-utils/src/mktplinkfw.c
+++ b/tools/firmware-utils/src/mktplinkfw.c
@@ -43,6 +43,7 @@
#define HWID_TL_WA901ND_V1     0x09010001
#define HWID_TL_WA901ND_V2     0x09010002
#define HWID_TL_WDR4900_V1     0x49000001
+#define HWID_TL_MR10U_V1       0x00100101
#define HWID_TL_WR703N_V1      0x07030101
#define HWID_TL_WR720N_V3      0x07200103
#define HWID_TL_WR741ND_V1     0x07410001
@@ -338,6 +339,11 @@ static struct board_info boards[] = {
.hw_rev         = 1,
.layout_id      = "4Mlzma",
}, {
+               .id             = "TL-MR10Uv1",
+               .hw_id          = HWID_TL_MR10U_V1,
+               .hw_rev         = 1,
+               .layout_id      = "4Mlzma",
+       }, {
.id             = "TL-WR720Nv3",
.hw_id          = HWID_TL_WR720N_V3,
.hw_rev         = 1,

参考文献

  • OpenWrt: Working with patches http://wiki.openwrt.org/doc/devel/patches
  • Patchwork [OpenWrt-Devel] ar71xx: add TP-LINK TL-MR10U http://patchwork.openwrt.org/patch/3656/
  • 恩山无线配件网: 自己动手,为OpenWrt加入720N的支持 http://www.right.com.cn/forum/thread-100342-1-1.html

修改记录

20130523 去掉了 mach-tl-mr10u.c 中的 MISP_MACHINE 定义中的 v1, 保证各个脚本工作正常.