Ubuntu 22.04 下移远 RM520N-GL 5G 模块从接线到开机自启全攻略
2026/9/24 12:05:00 网站建设 项目流程

前段时间给手头一台 Ubuntu 22.04 主机接移远 RM520N-GL 5G 模块,本以为插上 USB、装好 SIM 卡就能直接出网,结果从硬件接线到驱动识别,从拨号到开机自启,前前后后折腾了大半天,踩了一堆doc里查不到的坑。现在把这条完整链路整理出来:硬件怎么接、系统怎么认、拨号怎么配、开机自启怎么弄,最后附上我实际遇到的问题和解决办法。不管你是拿它做 5G CPE、边缘网关,还是给工控机加一条蜂窝备用链路,这套流程都能直接抄作业。

1. 硬件接线:别急着上电,先理清这几根线

1.1 需要准备的物料和选型说明

RM520N-GL 是 M.2 Key-B 封装的模组,不是随便插个转接板就能跑的裸设备。要把它在 Ubuntu 上顺利用起来,至少需要这几样东西:

  • RM520N-GL 模组本身。注意型号尾缀,GL 是全球版,支持的频段更全,国内 5G 频段也覆盖到了。
  • M.2 转接板。市面上常见两种:M.2 转 USB 3.0 和 M.2 转 PCIe x1。我强烈建议优先选 USB 3.0 转接板,因为 Ubuntu 下走 qmi_wwan 或 cdc_mbim 非常顺,不用额外处理 PCIe 驱动的兼容性问题。
  • 天线。RM520N-GL 支持 4x4 MIMO,套件里一般带 4 根棒状天线。就算只是测试,至少也要接 2 根,不然信号强度和速率都会很难看。
  • nano SIM 卡。注意是 nano 卡,别拿 micro SIM 卡套凑合,很多转接板的卡托根本塞不进去。
  • 供电线。很多转接板上有独立 DC 电源口,需要 12V/3A 左右。USB 口那点 5V 供电在模组注册 5G 网络的时候非常容易掉,尤其你还接了延长线的时候。
  • 散热片。这个真不是可选项,RM520N-GL 长时间跑 5G 发热很大,后面我会单独说。

选转接板时有一个关键点:最好选择带独立 USB 数据口和独立电源口的板子,而不是完全靠 USB 供电。我试过几块便宜的转接板,只靠 USB 取电时,dmesg里模组会反复枚举、断开,开 5G 后十分钟内必断一次。后来换成 12V 外部供电,才彻底稳定下来。

1.2 接线顺序和上电检查

接线没有太高技术含量,但顺序错了容易出怪问题。我的操作习惯是:

  1. 先把 4 根天线接到模组上的 MHF4 座上。天线末端接口非常小,别用蛮力,最好配一把镊子或撬棒,对准后垂直压下去,"咔"一声就到位了。
  2. 把模组以 30 度左右角度插入 M.2 卡槽,压平后拧上固定螺丝。这里最容易出错,后面我会讲我踩过的一次接触不良。
  3. 装 SIM 卡。金属触点朝下,推进去直到听到"咔嗒"声。
  4. 先接转接板供电,等待 3 到 5 秒,再插 USB 数据线到 Ubuntu 主机。
  5. 开机后检查dmesg | tail -30lsusb

如果lsusb里能看到类似2c7c:08002c7c:0801的设备,就说明模组 USB 枚举成功了。2c7c是移远的厂商 ID,PID 会随工作模式不同而变化,有的固件在 QMI 模式下显示 0800,MBIM 模式显示 0801。这个不影响后续流程,只要 VID 是 2c7c 就行。

还有一个细节:天线别贴着金属机箱,也别放在强电磁干扰源旁边。5G 高频信号对遮挡和干扰非常敏感。我第一次调试时把天线直接压在铁皮机箱上,RSRP 一度掉到 -100dBm 以下,后来用延长线把天线拉出来竖起来,信号直接改善了十几个 dB。这一步看着不起眼,但直接决定你后面测速的心情。

2. 系统识别:让 Ubuntu 22.04 认出 RM520N-GL

2.1 上电后的第一眼:lsusb 与 dmesg

USB 线插上后,先执行:

lsusb dmesg | tail -50

正常情况下,lsusb会输出类似下面这样一行:

Bus 002 Device 003: ID 2c7c:0800 Quectel Wireless Solutions Co., Ltd. RM520N-GL

内核日志里也会出现qmi_wwancdc_mbim相关的绑定信息。同时/dev/下面会多出几个设备节点,典型映射大致是:

  • /dev/ttyUSB0/dev/ttyUSB1:DM 口和 AT 口,用来发 AT 指令;
  • /dev/cdc-wdm0:QMI 通道,libqmiqmicli都走这个节点;
  • wwan0网络接口:实际上网流量的出口。

如果/dev/cdc-wdm0没有出现,先别急着往下走,大概率是驱动没有绑定,看下一节。

2.2 驱动绑定:内核认识不代表驱动认

Ubuntu 22.04 默认内核是 5.15,已经自带了qmi_wwancdc_mbim等驱动,但这里有个很尴尬的坑:部分 RM520N-GL 固件上报的 USB PID 不在驱动的 ID 表里,导致驱动不会自动绑定。典型表现是lsusb能看到设备,但/dev/cdc-wdm0不出现,mmcli也查不到模组。

这种情况可以临时手动绑定:

sudo modprobe qmi_wwan sudo sh -c 'echo "2c7c 0801" > /sys/bus/usb/drivers/qmi_wwan/new_id'

如果之后/dev/cdc-wdm0wwan0出现了,就说明是新 PID 没在驱动 ID 表里的问题。要永久生效,写一条 udev 规则,比如/etc/udev/rules.d/90-rm520n.rules

ACTION=="add", ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0801", RUN+="/bin/sh -c 'echo 2c7c 0801 > /sys/bus/usb/drivers/qmi_wwan/new_id'"

写好后重载规则或者重新插拔 USB:

sudo udevadm control --reload-rules sudo udevadm trigger

如果你的固件 PID 已经被内核默认识别,这步直接跳过,别没事乱加规则,反而会绑错网络接口。判断方法是先看dmesg里有没有驱动绑定成功的日志。

之后安装基础工具:

sudo apt update sudo apt install -y modemmanager network-manager libqmi-utils curl jq

Ubuntu 22.04 的apt update如果慢,就先把软件源换成国内镜像,方法网上一大把,这里不展开。装完后把两个关键服务拉起来:

sudo systemctl enable --now ModemManager sudo systemctl enable --now NetworkManager

只要 ModemManager 在跑,后续大部分拨号工作都可以交给它。

3. 拨号上网:ModemManager 一条龙 vs 手动 qmicli

3.1 推荐路线:ModemManager + NetworkManager

ModemManager 启动后,先确认模组被发现:

mmcli -L

正常输出大致是:

/org/freedesktop/ModemManager1/Modem/0 [Quectel] RM520N-GL

然后查看详细状态:

mmcli -m 0

重点关注几项:Status里的state是不是disabledSIM项有没有读到卡号;3GPP里的registration state是不是registeredroaming。如果state是 disabled,先启用:

mmcli -m 0 --enable

确认注册网络之后,直接用 ModemManager 建承载并连接。以国内最常见的公用 APN 为例:

mmcli -m 0 --command='AT+CGDCONT=1,"IP","cmnet"' mmcli -m 0 --create-bearer="apn=cmnet,ip-type=ipv4" mmcli -m 0 --connect-bearer=1

这里的apn=cmnet只是示例,实际要换成运营商分配的 APN。移动常见的是cmnet,联通是3gnetwonet,电信场景则要看你的资费套餐,别照抄。

连接成功后检查网络接口:

ip addr show wwan0

正常情况下wwan0已经拿到一个 IPv4 地址,并且内核会自动配上默认路由。如果地址没出现,可以先试试 DHCP 兜底:

sudo dhclient wwan0

能起来说明大概率是 raw-ip 数据格式没协商好,后面写自启脚本的时候我会加一层防护逻辑。

如果你不想跟 MM 手动命令打交道,还有一条更省事的路线:让 NetworkManager 管理这条连接。

nmcli connection add type gsm ifname wwan0 con-name rm5g apn cmnet ipv4.method auto autoconnect yes nmcli connection up rm5g

NetworkManager 本身会调用 ModemManager 完成拨号、IP、DNS 配置,autoconnect yes也给了它开机自连的能力。不过这里我要泼一盆冷水:5G 模组这种 USB 设备上,光靠autoconnect经常不稳定,原因我在下一章专门讲。

3.2 手动路线:qmicli 直连

如果你的系统不想跑 ModemManager,或者 ModemManager 和 NetworkManager 打架,也可以全程用qmicli手动拨号。这个思路适合嵌入式老手,也能帮你理解 QMI 协议在底层干了什么。

先检查数据格式,避免 raw-ip 问题:

qmicli -d /dev/cdc-wdm0 --wda-get-data-format

如果返回的是raw-ip,而内核网络接口还用的是 802.3 模式,就需要手动切:

sudo ip link set wwan0 down echo 'Y' > /sys/class/net/wwan0/qmi/raw_ip sudo ip link set wwan0 up

然后启动网络:

sudo qmicli -p -d /dev/cdc-wdm0 --device-open-net='net-raw-ip|net-no-qos-header' --wds-start-network="apn=cmnet,ip-type=ipv4" --client-no-release-cid

上面这个命令加上--client-no-release-cid,会把 QMI 会话保持住,方便后续查询和断线重连。启动成功后会返回 packet data handle。然后加默认路由:

sudo ip route add default dev wwan0

手动路线的优点是完全可控,坏处是断线重连、开机恢复都得自己写逻辑。生产环境不建议从头造轮子,Ubuntu 上让 ModemManager 管理模组生命周期,比裸 qmicli 稳太多。

3.3 实在不行就 ECM:模块直接变"USB 网卡"

QMI 和 MBIM 都试过还是搞不定时,还有一条万金油退路:把模组切成 ECM 模式。ECM 会把拨号过程简化成一张标准 USB 网卡,宿主侧只需要 DHCP 就能拿 IP。

先用 AT 指令切换,设备节点一般是/dev/ttyUSB2/dev/ttyUSB3

sudo screen /dev/ttyUSB2 115200

然后在 AT 终端里发送:

AT+QCFG="usbnet",0 AT+CFUN=1,1

AT+CFUN=1,1是重启模组,让新参数生效。重启后lsusb的 PID 可能会变,网络接口变成usb0enx*,然后直接用 NetworkManager 新建一个 ethernet 连接,或者dhclient usb0就能上网。

ECM 模式简单,但稳定性和效率不如原生 QMI/MBIM,个别固件在高负载下会出兼容问题。我建议把它当排障手段,而不是长期方案。

4. 开机自启:用 systemd 把 5G 网络"焊"死

4.1 为什么 autoconnect 靠不住

先说结论:USB 挂载的 5G 模块,开机自启最大的敌人是时序。

开机时内核枚举 USB 设备需要时间,模组固件初始化需要时间,ModemManager 扫描发现模组也需要时间。NetworkManager 如果在这个窗口期尝试连接rm5g,很可能撞上模组还没就绪的情况,连接失败。更烦人的是,NM 一旦标记失败,后续重试策略并不是你想的那么勤快,有时候必须手动nmcli connection up rm5g才能恢复。

这类问题的本质,和 Linux 下 CIFS 开机没自动挂载是同一个坑:你以为写进了配置就完事,但系统执行时网络或设备还没就绪,于是直接失败。正确做法是把"等设备、等网络"这些动作交给 systemd 按依赖顺序执行。这也是为什么我最终选择写脚本而不是只靠 NetworkManager 的 autoconnect。

4.2 自启脚本:带重试的 ModemManager 流程

我写了一个启动脚本,放到/usr/local/bin/rm5g-up.sh。逻辑很直白:等 ModemManager 找到模组,启用模组,创建 bearer,连接 bearer,再兜底配置默认路由。

#!/bin/bash LOG_TAG=rm5g logger -t "$LOG_TAG" "waiting ModemManager to enumerate modem..." MM_INDEX="" for i in $(seq 1 30); do MM_INDEX=$(mmcli -L 2>/dev/null | grep -oE 'modem/[0-9]+' | head -1 | cut -d/ -f2) if [ -n "$MM_INDEX" ]; then break fi sleep 2 done if [ -z "$MM_INDEX" ]; then logger -t "$LOG_TAG" "modem not found after 60s, exit" exit 1 fi logger -t "$LOG_TAG" "modem index: $MM_INDEX" mmcli -m "$MM_INDEX" --enable 2>/dev/null || true sleep 2 BEARER_ID=$(mmcli -m "$MM_INDEX" --list-bearers 2>/dev/null | grep -oE 'bearer/[0-9]+' | head -1 | cut -d/ -f2) if [ -z "$BEARER_ID" ]; then OUT=$(mmcli -m "$MM_INDEX" --create-bearer="apn=cmnet,ip-type=ipv4" 2>&1) BEARER_ID=$(echo "$OUT" | grep -oE "bearer '[0-9]+'" | grep -oE '[0-9]+') fi if [ -z "$BEARER_ID" ]; then logger -t "$LOG_TAG" "create bearer failed: $OUT" exit 1 fi mmcli -m "$MM_INDEX" --connect-bearer="$BEARER_ID" 2>/dev/null || true sleep 3 ip link set wwan0 up 2>/dev/null || true if ! ip route show default 2>/dev/null | grep -q "wwan0"; then ip route add default dev wwan0 2>/dev/null || true fi logger -t "$LOG_TAG" "5G link is up"

脚本里的mmcli --create-bearer参数,apn一定要改成你自己的。如果运营商要求ip-type=ipv4v6或者指定user/password,直接在这个命令后面追加即可。给脚本加上执行权限:

sudo chmod +x /usr/local/bin/rm5g-up.sh

4.3 systemd 单元与启用

再创建一个 systemd 服务文件/etc/systemd/system/rm5g-up.service

[Unit] Description=Bring up RM520N-GL 5G link After=network-pre.target ModemManager.service Wants=ModemManager.service Before=network.target [Service] Type=oneshot ExecStart=/usr/local/bin/rm5g-up.sh RemainAfterExit=yes Restart=on-failure RestartSec=10 [Install] WantedBy=multi-user.target

然后启用:

sudo systemctl daemon-reload sudo systemctl enable --now rm5g-up.service

重启验证之前,先手动执行一次,确认在当前环境能跑通:

sudo systemctl restart rm5g-up.service journalctl -u rm5g-up -b

看到5G link is up的日志,说明脚本本身没问题。然后sudo reboot,开机后等十几秒,检查ip addr show wwan0ip route show default

4.4 顺带解决 USB 自动挂起

这个坑很有迷惑性:模组拨号正常,跑着跑着网断了,翻日志发现 USB 设备进入了 autosuspend。这是内核 USB 电源管理和模组交互时序冲突导致的。可以用一条 udev 规则根治:

ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="2c7c", ATTR{power/autosuspend}="-1"

写好后:

sudo udevadm control --reload-rules sudo udevadm trigger

如果已经处于挂起状态,手动恢复:

echo 'on' | sudo tee /sys/bus/usb/devices/*/power/control

这里的*建议精确到具体总线地址,别一股脑全改,否则影响其他 USB 设备。

4.5 和 Windows 习惯对比一下

从 Windows 转过来的朋友,平时可能习惯用 PowerShell 开机脚本处理"开机后要干的事"。Windows 的做法是塞进计划任务或者启动文件夹,Linux 这边对应的就是 systemd 服务。两者本质一样:把"开机后必须执行的动作"变成系统托管任务,并且能查日志、能自动重试。

我见过不少人把 Windows 上的启动脚本思路直接照搬过来,却不看系统日志,结果脚本报错也不知道问题在哪。到了 systemd 这边,先把journalctl用熟,排障效率能高一个量级。尤其是Restart=on-failureRestartSec=10的组合,在模组初始化慢的环境下非常管用。

5. 常见问题与排查实录

5.1 问题速查表

现象排查方向解决方法
lsusb看不到设备供电、接线、USB 口检查 12V 供电,重新插拔模组,换 USB 直连口
lsusb有设备但mmcli -L驱动未绑定检查 dmesg,用new_id绑定 qmi_wwan,写 udev 规则固化
mmcli -m 0显示 disabled模组处于 disabled 状态mmcli -m 0 --enable,或者 AT+CFUN=1
SIM 卡读不到SIM 接触、PIN 码、卡槽断电插 SIM,查 AT+CPIN?,关掉 PIN 码
拨号成功但 wwan0 无 IPraw-ip 格式没对上用 qmicli 检查 WDA 数据格式,手动切 raw-ip,或 dhclient 兜底
无法 ping 外网默认路由、DNSip route检查默认路由,加default dev wwan0,检查 /etc/resolv.conf
开机后没自启时序、服务依赖看 journalctl,等模组枚举,调 RestartSec
跑一会儿断流USB autosuspend关掉 auto 挂起,检查散热

5.2 典型排查记录:模组完全不枚举

我遇到最典型的问题是:转接板供电接上后,lsusb里什么都看不到,dmesg 也没有任何 USB 插入事件。排查过程是这样:

  • 先排除数据线,换了一根带屏蔽的 USB 3.0 线,无效;
  • 再排除 USB 口,插到主板直出的 Type-A 口,还是无效;
  • 最后把转接板拆下来,发现 M.2 卡槽里的模组没有完全压平,一侧翘起来了,金手指接触不良。重新插入、压平、锁螺丝后,上电立刻枚举成功。

这个案例提醒我,M.2 模组安装时"压平"这一步看着简单,实际非常容易出错。如果你遇到完全无响应的情况,第一步永远是重新检查物理连接,而不是改软件。

5.3 典型排查记录:拨号成功但上不了外网

除了wwan0没 IP,还有一个常见伴生问题:IP 有了,但 ping 外网不通。这时候先看路由:

ip route show

如果默认路由还在有线网卡上,5G 的包就会走错出口。手工加一条优先级路由:

sudo ip route add default dev wwan0 metric 100

metric 设高一点,可以让有线网卡优先作为默认路由,5G 当备份链路。如果你需要 5G 作为主链路,把这个 metric 调低即可。

另一个隐蔽问题是:IPv4 地址拿到了,但 DNS 还是内网服务器,导致域名解析失败。用nmcli device show wwan0查看,或者直接编辑/etc/resolv.conf,把公共 DNS 加进去。

5.4 典型排查记录:信号看着正常但速率拉胯

你可以用这条命令查看服务小区信息:

mmcli -m 0 --command='AT+QENG="servingcell"'

重点关注 RSRP 和 SINR。如果 RSRP 在 -85dBm 以内、SINR 在 10dB 以上,速率还是上不去,多半是天线没接满,或者模组被限制在 4G 模式。检查注册模式:

mmcli -m 0 --command='AT+COPS?' mmcli -m 0 --command='AT+QNWPREFCFG="mode_pref",NR5G_SA'

部分运营商的 5G 卡默认不注册 SA,需要把模组的模式偏好改成 SA 或 NSA。注意不是所有固件都支持这条指令,具体以移远官方 AT 手册为准。

5.5 一种被我放弃的方案:纯 NetworkManager 自连

早期调试时,我试过只依赖 NetworkManager 的开机自连:

nmcli connection modify rm5g connection.autoconnect yes

单独看配置没有任何问题,但实测开机 10 次里有 2 到 3 次连不上。一旦失败,NM 要等较长时间才重试,中间完全无网。后面改成 systemd 服务,等模组稳定再拨号,连续重启十几次都能过。所以如果你也遇到 autoconnect 偶尔失灵,别死磕 NM,直接上脚本最省心。

写在最后的一点经验

整套流程跑通之后,真正让我省心的不是某一条神奇命令,而是一块散热片。RM520N-GL 跑起来发热相当明显,尤其是连续上下行测试时,模组表面温度能到七八十度,高到一定程度就开始掉速。我后来在模块背面贴了一块 30x30 毫米的铝散热片,再配合转接板的通风孔,长时间 ping 和跑脚本都没掉过包。这个硬件层面的小改动,比我在软件上折腾半天都管用。

如果你也要长时间跑 5G,建议第一件事就把散热做好,再去纠结参数。等软件方案稳定后,这套东西还能扩展成 4G/5G 自动切换的备份链路,或者加上健康检查脚本实现断线自动重拨。那又是另一个话题了,等后面有空再单独写一篇。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询