AX86U官方固件添加5G模块RM500Q的支持

1. 安装所需依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 因为后面的交叉编译工具链是32位的,所以需要开启32位程序支持
sudo dpkg --add-architecture i386
sudo dpkg-reconfigure dash # 在提示中选NO把默认dash切换为bash
sudo apt update

sudo apt install tar bzip2 unzip python perl flex make pkg-config \
gcc-multilib g++-multilib g++ cmake autoconf automake bison patch \
autopoint autogen automake-1.15 build-essential intltool xsltproc \
subversion git cvs m4 uuid-dev groff-base gettext gperf file gawk \
sed shtool texinfo gconf-editor diffutils libslang2 gtk-doc-tools \
gitk xutils-dev zlib1g zlib1g-dev libxml-parser-perl libproxy-dev \
libncurses5 libncurses5-dev autoconf-archive libxml2-dev mtd-utils \
libexpat1-dev libvorbis-dev libglib2.0-dev libssl-dev liblzo2-dev \
libtool-bin libtool lib32z1-dev lib32stdc++6 libelf1:i386

2. 配置环境变量

1
2
3
4
5
6
7
8
9
10
11
# 获取编译要用的工具链并配置到环境变量,这里用的是来自梅林的工具链
git clone https://github.com/RMerl/am-toolchains ~/

sudo ln -s ~/am-toolchains/brcm-arm-hnd /opt/toolchains
echo "export TOOLCHAIN_BASE=/opt/toolchains" >> ~/.profile

echo "PATH=\$PATH:/opt/toolchains/crosstools-arm-gcc-5.5-linux-4.1-glibc-2.26-binutils-2.28.1/usr/bin" >> ~/.profile
echo "PATH=\$PATH:/opt/toolchains/crosstools-aarch64-gcc-5.5-linux-4.1-glibc-2.26-binutils-2.28.1/usr/bin" >> ~/.profile
echo "export LD_LIBRARY_PATH=\$LD_LIBRARY:/opt/toolchains/crosstools-arm-gcc-5.5-linux-4.1-glibc-2.26-binutils-2.28.1/usr/lib" >> ~/.profile

source ~/.profile

3. 获取官方源码

1
2
3
4
5
6
7
# 获取编译要用的工具链和最新的官方源码
# ASUS官网 -> 支持 -> 下载中心 -> 输入型号AX86U搜索 -> 驱动程序和工具软件 -> 请选择操作系统 -> 其他 -> Source Code -> ASUS RT-AX86U 程序源代码搭配固件版本3.0.0.4.386.46061
https://www.asus.com.cn/Networking/RT-AX86U/HelpDesk_Download/

wget https://dlsvr04.asus.com.cn/pub/ASUS/wireless/RT-AX86U/GPL_RT_AX86U_300438646061.zip -P ~/
unzip -d ~/ GPL_RT_AX86U_300438646061.zip && rm ~/GPL_RT_AX86U_300438646061.zip
tar -xzvf ~/GPL_RT-AX86U_3.0.0.4.386.46061-g9a06866.tgz -C ~/

4. 开始编译系统

1
2
3
4
5
6
7
8
9
10
# I9 9700K配16G内存及SSD在40分钟左右可以编译完成
cd ~/asuswrt/release/src-rt-5.02p1axhnd.675x
make rt-ax86u

# 如果编译成功的话,在下面路径中将生成适用于AX86U的梅林固件
~/asuswrt/release/src-rt-5.02p1axhnd.675x/targets/962118GW/
RT-AX86U_3.0.0.4_386_46061-g9a06866_cferom_pureubi.w

# 官方固件就是这个RT-AX86U_3.0.0.4_386_46061-g9a06866_cferom_pureubi.w
https://dlsvr04.asus.com.cn/pub/ASUS/wireless/RT-AX86U/FW_RT_AX86U_300438646061.zip

5. 添加模块支持

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
cd ~/asuswrt/release/src-rt-5.02p1axhnd.675x/kernel/linux-4.1/
patch -p1 < ~/prebuilt/0001-Add-Quectel-RM500Q-USB-Serial-Driver-Support.patch

#### 补丁文件:~/0001-Add-Quectel-RM500Q-USB-Serial-Driver-Support.patch ####
diff -Nur a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
--- a/drivers/usb/serial/option.c 2021-10-08 15:15:51.000000000 +0800
+++ b/drivers/usb/serial/option.c 2022-10-13 17:43:07.439162300 +0800
@@ -687,6 +687,7 @@
};

static const struct usb_device_id option_ids[] = {
+ { USB_DEVICE(0x2C7C, 0x0800) }, /* Quectel RG500Q/RM500Q/RG510Q/RM510Q */
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) },
@@ -2086,6 +2087,7 @@
#ifdef CONFIG_PM
.suspend = usb_wwan_suspend,
.resume = usb_wwan_resume,
+ .reset_resume = usb_wwan_resume, // Added by Quectel
#endif
};

@@ -2129,6 +2131,18 @@
iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA)
return -ENODEV;

+ //Quectel modules’s interface 4 can be used as USB network device
+ if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {
+ //some interfaces can be used as USB Network device (ecm, rndis, mbim)
+ if (serial->interface->cur_altsetting->desc.bInterfaceClass != 0xFF) {
+ return -ENODEV;
+ }
+ //interface 4 can be used as USB Network device (qmi)
+ else if (serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4) {
+ return -ENODEV;
+ }
+ }
+
/* Store the blacklist info so we can use it during attach. */
usb_set_serial_data(serial, (void *)blacklist);

diff -Nur a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
--- a/drivers/usb/serial/usb_wwan.c 2021-10-08 15:15:51.000000000 +0800
+++ b/drivers/usb/serial/usb_wwan.c 2022-10-13 17:39:20.299150400 +0800
@@ -471,6 +471,14 @@
usb_sndbulkpipe(serial->dev, endpoint) | dir,
buf, len, callback, ctx);

+ // Added by Quectel for zero packet
+ if (dir == USB_DIR_OUT) {
+ struct usb_device_descriptor *desc = &serial->dev->descriptor;
+
+ if (desc->idVendor == cpu_to_le16(0x2C7C))
+ urb->transfer_flags |= URB_ZERO_PACKET;
+ }
+
return urb;
}

6. 添加串口工具

1
2
3
4
5
# 为BUSYBOX添加MICROCOM支持:CONFIG_MICROCOM=y
vi ~/asuswrt/release/src/router/busybox-1.24.1/busybox-1.24.1/config_base

# 使用microcom操作模块,Ctrl + Z 退出
microcom -s 115200 /dev/ttyUSB2

7. 设置ECM 上网

优先推荐ECM模式,不需要重新编译内核来驱动,官方固件就能正常上网,网速快PPP一大节。但获取到的是局域网IP,得不到公网IP

1
2
3
4
5
6
7
# 模块通过ECM模式上网
echo -e "AT+QCFG=\"usbnet\",1\r\n" > /dev/ttyUSB3 # 切换模块到ECM模式
busybox udhcpc -i usb0 # 如果有usb0网卡却没有获取到IP那么可以执行这个

路由器WEB管理里面设置:USB Modem / USB 网络共享 -> 基本设置
开启 USB 模式 ON
选择 USB 设备 安卓手机

8. 设置PPP 上网

不建议通过PPP拨号上网,不仅需要重新编译内核来驱动,PPP拨号速度还慢(检测发现模块在USB2.0上运行)。但可获取到公网IP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# PPP拨号是通过向ttyUSB*节点发送AT指令实现的,所以option.ko模块一定要开机就已经加载
# 通过设置MBIM模式是上不了网的,但会开机自动加载option模块生成/dev/ttyUSB*节点
# 切换模块到MBIM模式,有了/dev/cdc-wdm0和接口wwan0。或者 AT+QCFG="usbnet",0 也可以
echo -e "AT+QCFG=\"usbnet\",2\r\n" > /dev/ttyUSB3

# 接下来就可以设置AX86U让它自动PPP拨号了,我用的是电信卡
# 设置完成后重启,AX86U就自动使用预设PPP拨号上网了,网卡接口为ppp0
路由器WEB管理里面:USB Modem / USB 网络共享 -> 基本设置
开启 USB 模式 ON
选择 USB 设备 USB Modem
APN 设置 手动设置
所在位置 China
ISP China Telecom
电信标准 CDMA2000 (EVDO) // 自动选择的
APN 服务名称(选填) ctlte
连线号码 *99#
后面默认即可

# 如果需要PPP拨号获取IPv6,那么在 /tmp/ppp/peers/3g 中添加 +ipv6 即可
killall pppd
echo "+ipv6" >> /tmp/ppp/peers/3g
/usr/sbin/pppd call 3g

# 如果能获取到IPv4但获取不到IPv6,那么去模块看是否APN设置了仅IPv4或者运营商没有提供IPv6
AT+CGDCONT?
AT+CGDCONT=1,"IPV4V6","ctlte"

PPP拨号启用IPv6可以添加+ipv6至 /tmp/ppp/peers/3g 。若打算默认启用IPv6可以如下修改源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 在~\asuswrt\release\src\router\rc\usb_devices.c 2482行添加:fprintf(fp, "+ipv6\n");
......
fprintf(fp, "linkname wan%d\n", wan_unit);
fprintf(fp, "modem\n");
fprintf(fp, "crtscts\n");
fprintf(fp, "noauth\n");
fprintf(fp, "noipdefault\n");
fprintf(fp, "usepeerdns\n");
fprintf(fp, "defaultroute\n");
fprintf(fp, "nopcomp\n");
fprintf(fp, "noaccomp\n");
fprintf(fp, "novj\n");
fprintf(fp, "nobsdcomp\n");
fprintf(fp, "nodeflate\n");
fprintf(fp, "+ipv6\n"); // 添加这行来将+ipv6在运行时写入/tmp/ppp/peers/3g
if(!strcmp(nvram_safe_get("modem_demand"), "1")){
fprintf(fp, "demand\n");
fprintf(fp, "idle %d\n", nvram_get_int("modem_idletime")?:30);
}
fprintf(fp, "persist\n");
fprintf(fp, "holdoff %s\n", nvram_invmatch(strcat_r(prefix, "pppoe_holdoff", tmp), "")?nvram_safe_get(tmp):"10");
......

9. 官方工具上网

1
2
3
4
5
6
7
8
9
10
11
12
# 移远官方提供了拨号上网工具 quectel-CM ,支持QMI,Gobinet,MBIM模式
# 目前因为暂时没有添加QMI,Gobinet驱动支持,只能使用MBIM模式来联网
echo -e "AT+QCFG=\"usbnet\",2\r\n" > /dev/ttyUSB3

# 例如:获取ipv4,ipv6,指定APN。拨号完毕应该可以获取到ipv4/ipv6地址
quectel-CM -4 -6 -s ctnet &

# 现在路由内部应该能联网了,如果不能则添加路由试试
route add -net 0.0.0.0 netmask 0.0.0.0 dev ppp0

# 最后将所有本地流量转发到wwan0接口上
iptables -t nat -A POSTROUTING -s 192.168.50.0/24 -o wwan0 -j MASQUERADE

10. 节点设备位置解析

1
2
3
4
5
6
7
8
9
# 设备位置解析
/dev/qcqmi0 QMI设备
/dev/cdc-wdm0 MBIM设备

# RM500Q有两个AT接口,可以一个执行AT指令一个PPP拨号
/dev/ttyUSB0 USBDM
/dev/ttyUSB1 used for GPS NMEA message outpu
/dev/ttyUSB2 used for AT command communication
/dev/ttyUSB3 used for PPP connection or AT command communication