11 KiB
LEDE 5G 固件构建与分析记录
日期:2026-08-21 仓库:https://github.com/Atieei/lede(fork 自 coolsnowwolf/lede) 提交:
a09ade8add 5G modem support (RM520N-GL MBIM) with luci management and CI build 目标:飞牛OS (fnOS) KVM 虚拟机 + PCIe 直通 RM520N-GL,编译带自写管理界面的精简稳定版 LEDE 固件
一、实测经验核心结论(固件设计依据)
以下结论来自 RM520N-GL 在 fnOS KVM + PCIe 直通环境下的实测,是整个固件方案的基石:
| 结论 | 详情 |
|---|---|
| MBIM 是唯一可行模式 | RM520N-GL 在 PCIe/MHI 下 QMI 通道不可用,驱动必须以 mhi_mbim_enabled=1 加载 |
| 拨号命令禁用 -i 参数 | MBIM 模式下 quectel-CM -s <APN> 即可,传 -i rmnet_mhi0 会导致异常 |
| 驱动版本 | pcie_mhi V1.3.8(源码来自 Siriling/5G-Modem-Support 的 quectel_MHI) |
| 拨号工具 | quectel-CM V1.6.8(QConnectManager,MBIM 路径实测通过) |
| AT 通道与拨号并存 | /dev/mhi_DUN(sms_tool AT)与 /dev/mhi_MBIM 拨号可同时使用 |
| SYS_ERR 故障 | 模块失联时 VM 内 reboot 无法恢复(不切断 PCIe 供电),需阶梯式自愈或宿主机断电 |
| 数据接口 | 拨号成功后 IP 出现在 rmnet_mhi0.1 |
二、固件包结构(package/5g-modem/)
package/5g-modem/
├── pcie-mhi/ # 内核驱动 kmod-pcie-mhi (V1.3.8)
│ ├── Makefile # 外部内核模块编译 (kbuild, 产出 pcie_mhi.ko)
│ ├── src/ # 驱动源码 (core/controllers/devices)
│ └── files/etc/modules.d/90-pcie_mhi # 开机自动加载: pcie_mhi mhi_mbim_enabled=1
├── quectel-cm/ # 拨号工具 quectel-cm (V1.6.8)
│ ├── Makefile # musl-gcc 单命令编译 (与实测通过的编译命令一致)
│ └── src/ # QConnectManager 源码
├── sms-tool/ # AT 命令工具 (obsy/sms_tool + 中文编码修正补丁)
└── luci-app-5gmodem/ # 自写 LuCI 管理应用
├── luasrc/controller/5gmodem.lua # 菜单 + API (status/dial/at)
├── luasrc/model/cbi/5gmodem/settings.lua # 设置页 (APN/认证/PIN/守护开关)
├── luasrc/view/5gmodem/status.htm # 状态页 (轮询+控制+AT控制台)
└── root/
├── etc/config/5gmodem # UCI 默认配置
├── etc/init.d/5gmodem # procd 拨号服务 (START=95)
├── usr/bin/5gmodem-guard # SYS_ERR 自愈守护
└── usr/libexec/5gmodem-status.sh # 状态采集 (JSON 输出)
依赖声明:luci-app-5gmodem → +kmod-pcie-mhi +quectel-cm +sms-tool +luci-compat
三、LuCI 管理界面功能
菜单:网络 → 5G 拨号(状态 / 拨号设置)
状态页(10 秒轮询)
- 服务与驱动:quectel-CM 运行状态/PID、守护状态、pcie_mhi 加载、MBIM/DUN 通道就绪、PCI 设备地址
- 连接信息:
rmnet_mhi0.1的 IP、上下行流量(自动格式化 B/KB/MB/GB) - 模块信息:型号/制造商/固件/IMEI/IMSI/SIM 状态/运营商(PLMN 数字映射中文名)/网络模式/频段信道
- 信号质量:RSRP/SINR/RSRQ/RSSI,带优/中/差彩色分级标签
- 拨号控制:启动/停止/重启(POST + token,防 CSRF)
- AT 控制台:自由输入 + 15 条常用命令快捷下拉(QCSQ/QNWINFO/QENG="servingcell"/QTEMP 等),输出区滚动显示
- 拨号日志:/tmp/quectel_cm.log 尾部 12 行实时展示
设置页
- 开机自动拨号、APN(默认 wonet)、PAP/CHAP 用户名密码(明文显示便于调试)、认证方式、PIN 码、AT 串口路径、自愈守护开关
API(控制器)
api_status:GET 状态 JSONapi_dial:POST start/stop/restart/reload(白名单校验)api_at:POST AT 命令,正则白名单校验(^AT开头,允许字母数字空格+ " = % ? , . : / # * ( ) -,禁单引号保证 shell 拼接安全),串口路径二次校验 + 存在性检查
四、SYS_ERR 自愈守护(5gmodem-guard)
基于实测故障经验设计,procd 托管、每 15 秒巡检,恢复阶梯:
- 阶段 1:
echo <bdf> > /sys/bus/pci/drivers/mhi_q/bind(实测有效的手动唤醒法,每 30s 重试) - 阶段 2:PCI remove + rescan,重走 BHI 固件下载(故障 120s 后,每 60s 一次)
- 阶段 3:rmmod pcie_mhi + 重加载 MBIM 模式(故障 300s 后,每 90s 一次)
- 阶段 4:日志提示需宿主机断电(故障 600s 后,每 300s 提示;VM 内无法切断 PCIe 供电属物理限制)
附加:设备在但 quectel-CM 进程死亡超过 60s 时自动 restart 拨号服务。日志写入 /tmp/5gmodem_guard.log(超 200 行自动截半)。
设备识别:扫描 /sys/bus/pci/devices/*/vendor 匹配移远 0x17cb/0x1eac。
五、兼容性验证记录(关键分析)
5.1 LuCI 分支兼容性(openwrt-25.12)
feeds.conf.default 使用 coolsnowwolf/luci;openwrt-25.12 分支,该分支 ucode dispatcher 为新架构。逐项读源码实证:
- Lua controller 支持:
modules/luci-base/ucode/dispatcher.uc中glob('/usr/lib/lua/luci/controller/*.lua')扫描并通过runtime.call('luci.dispatcher', 'process_lua_controller', file)桥接处理 → 旧式 controller 完全可用 - 依赖链完整:
luci-compat(Makefile:LUCI_DEPENDS:=+luci-lua-runtime) →luci-lua-runtime模块存在(含 dispatcher.lua/template.lua 等),luci-base 依赖ucode-mod-*全套 - 模板桥接:
luci-lua-runtime/luasrc/template.lua的include()在 Lua 视图目录找不到时回退L.include(name)(ucode 主题模板),因此<%+header%>/<%+footer%>正确渲染主题框架;bootstrap 主题提供ucode/template/themes/bootstrap/header.ut|footer.ut - 同模式先例:该分支有 68 个 luasrc/controller 文件、150 个 CBI 文件(docker/diskman/lucky/nfs 等应用均为旧式 Lua 写法)
- CBI Flag 类:
luci-compat/luasrc/cbi.luaFlag 构造器初始化enabled="1"/disabled="0",设置页默认值逻辑正确
5.2 内核驱动 6.12/6.18 兼容性
- pcie_mhi 源码版本守护完善:42 处
LINUX_VERSION_CODE条件编译 - 关键破坏点
class_create已适配:mhi_uci.c:954与mhi_init.c:2678均有>= 6.4.0单参数版本分支 mhi_netdev_quectel.c有 6.1 分界适配(netdev/dm/timer API)
5.3 重要发现与修正:virtio 配置冗余
原计划在 target/linux/x86/config-6.12 base 配置添加 KVM guest 支持。复查发现 target/linux/x86/64/config-6.12(6.18 同)子目标配置已内建全套支持(HYPERVISOR_GUEST/KVM_GUEST/PARAVIRT/PARAVIRT_CLOCK/VIRTIO/VIRTIO_PCI/VIRTIO_NET/VIRTIO_BLK/VIRTIO_BALLOON/SCSI_VIRTIO/HW_RANDOM_VIRTIO/DRM_VIRTIO_GPU 等全为 y,且子目标配置覆盖合并 base)。
处置:回退 base config 修改。fork 相对上游 diff 仅剩纯新增的 3 个目录(.github/workflows/、configs/、package/5g-modem/),后续同步上游零冲突。
5.4 内核竞争配置检查
确认内核主线 MHI 相关配置(CONFIG_MHI_BUS 等)未启用,与外部 pcie_mhi 驱动无符号竞争。
六、本地校验记录(提交前)
| 项目 | 方法 | 结果 |
|---|---|---|
| 4 个 shell 脚本 | Git Bash sh -n(status.sh / guard / init.d / modules.d) |
全部通过 |
| status.htm 内嵌 JS(145 行) | Node new Function() 语法检查(LuCI 模板占位符替换后) |
通过 |
| 2 个 Lua 文件 | 自写块结构平衡检查器(剥离注释/字符串后统计 function/if/do/end 配对) | 通过 |
| 行尾检查 | 逐文件统计 CRLF | 仅 sms-tool/Makefile 为 CRLF,已规范化为 LF |
| 执行位 | git update-index --add --chmod=+x 三个脚本 |
索引中 100755 确认 |
| 行尾入库保障 | package/5g-modem/.gitattributes(.sh/.lua/*.htm/Makefile 强制 LF) |
已设置 |
七、Git 提交与推送
- 克隆采用
--depth=1 --filter=blob:none+ sparse-checkout(仅 target/linux/x86 等),提交前将新目录加入 sparse 规则 - 提交
a09ade8:80 个文件,45600 行插入 - 已推送
master→origin/master(81636b7..a09ade8) - 三个可执行脚本(init.d/5gmodem、5gmodem-guard、5gmodem-status.sh)以 100755 模式入库(Linux 上 procd 直接执行必需)
八、新镜像构建与产物
构建方法(手动触发)
- 打开 https://github.com/Atieei/lede/actions
- 左侧选 Build 5G-Modem LEDE (x86_64)
- Run workflow → 直接 Run(首编约 2-3 小时)
- 可选输入:勾选"忽略缓存全量重编"(首次构建或缓存异常时使用)
工作流特性
- 运行环境 ubuntu-22.04,lede 官方 CI 同款依赖安装 + jlumbroso/free-disk-space 磁盘清理
- toolchain/dl 缓存(key 含 feeds.conf.default 与种子配置哈希),重编大幅提速
.config由configs/x86_64-5gmodem.config种子 +make defconfig生成,并强校验 5G 五个包必须被选中(否则立即失败)- 编译失败自动重试
make -j1 V=s并产出日志 artifact
产物(3 个 artifact)
| Artifact | 内容 |
|---|---|
| lede-5gmodem-firmware-x86_64 | 固件镜像(BIOS+EFI 双启动 squashfs+gzip,位于 bin/targets/x86/64/) |
| lede-5gmodem-packages | 全部 .ipk(可装进现有系统调试,无需重刷固件) |
| lede-5gmodem-buildinfo | *.buildinfo / *.manifest(精确还原配置) |
精简配置说明(configs/x86_64-5gmodem.config)
- 关闭:CPU 微码、声卡全套、物理显卡(amdgpu/i915)、物理网卡(igb/i40e/mlx5/r8125 等 17 种)、USB 网卡、f2fs/mmc/传感器/自动挂载
- 保留:e100/e1000/e1000e(KVM 常见网卡)+ virtio(内核内建)+ PCIe 直通 + LuCI 中文界面 + 5G 全套包
九、部署指南
- 下载固件 artifact,解压取
*-x86-64-generic-squashfs-combined-efi.img.gz(fnOS KVM 用 EFI) gunzip后作为磁盘导入 KVM 虚拟机,vCPU/内存按需,PCIe 直通 RM520N-GL- 首次启动后 LAN 口(默认 192.168.1.1)访问 LuCI → 网络 → 5G 拨号
- 设置页填 APN(联通 wonet)保存即自动拨号;或状态页手动"启动拨号"
- 多 WAN 需手动配置(固件按需求不预置策略路由)
十、故障排查速查
| 现象 | 排查 |
|---|---|
| 状态页全灰 | `lsmod |
| 拨号无 IP | cat /tmp/quectel_cm.log(完整日志)、AT 控制台发 AT+CPIN? 查 SIM |
| 自愈不成功 | 看守护日志阶段提示;600s 仍未恢复需宿主机断电(物理限制) |
| AT 控制台无响应 | 确认 /dev/mhi_DUN 存在;串口路径在设置页可改 |
| ipk 调试 | artifacts 的 packages 里直接 opkg install 对应 ipk 到现有系统 |