# LEDE 5G 固件构建与分析记录 > 日期:2026-08-21 > 仓库:https://github.com/Atieei/lede :fork 自 coolsnowwolf/lede > 提交:`a09ade8` add 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 ` 即可,传 `-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 状态 JSON - `api_dial`:POST start/stop/restart/reload(白名单校验) - `api_at`:POST AT 命令,正则白名单校验(`^AT` 开头,允许字母数字空格 `+ " = % ? , . : / # * ( ) -`,禁单引号保证 shell 拼接安全),串口路径二次校验 + 存在性检查 --- ## 四、SYS_ERR 自愈守护(5gmodem-guard) 基于实测故障经验设计,procd 托管、每 15 秒巡检,恢复阶梯: 1. **阶段 1**:`echo > /sys/bus/pci/drivers/mhi_q/bind`(实测有效的手动唤醒法,每 30s 重试) 2. **阶段 2**:PCI remove + rescan,重走 BHI 固件下载(故障 120s 后,每 60s 一次) 3. **阶段 3**:rmmod pcie_mhi + 重加载 MBIM 模式(故障 300s 后,每 90s 一次) 4. **阶段 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 为新架构。逐项读源码实证: 1. **Lua controller 支持**:`modules/luci-base/ucode/dispatcher.uc` 中 `glob('/usr/lib/lua/luci/controller/*.lua')` 扫描并通过 `runtime.call('luci.dispatcher', 'process_lua_controller', file)` 桥接处理 → 旧式 controller 完全可用 2. **依赖链完整**:`luci-compat` (Makefile: `LUCI_DEPENDS:=+luci-lua-runtime`) → `luci-lua-runtime` 模块存在(含 dispatcher.lua/template.lua 等),luci-base 依赖 `ucode-mod-*` 全套 3. **模板桥接**:`luci-lua-runtime/luasrc/template.lua` 的 `include()` 在 Lua 视图目录找不到时回退 `L.include(name)`(ucode 主题模板),因此 `<%+header%>`/`<%+footer%>` 正确渲染主题框架;bootstrap 主题提供 `ucode/template/themes/bootstrap/header.ut|footer.ut` 4. **同模式先例**:该分支有 68 个 luasrc/controller 文件、150 个 CBI 文件(docker/diskman/lucky/nfs 等应用均为旧式 Lua 写法) 5. **CBI Flag 类**:`luci-compat/luasrc/cbi.lua` Flag 构造器初始化 `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 直接执行必需) --- ## 八、新镜像构建与产物 ### 构建方法(手动触发) 1. 打开 https://github.com/Atieei/lede/actions 2. 左侧选 **Build 5G-Modem LEDE (x86_64)** 3. **Run workflow** → 直接 Run(首编约 2-3 小时) 4. 可选输入:勾选"忽略缓存全量重编"(首次构建或缓存异常时使用) ### 工作流特性 - 运行环境 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 全套包 --- ## 九、部署指南 1. 下载固件 artifact,解压取 `*-x86-64-generic-squashfs-combined-efi.img.gz`(fnOS KVM 用 EFI) 2. `gunzip` 后作为磁盘导入 KVM 虚拟机,vCPU/内存按需,PCIe 直通 RM520N-GL 3. 首次启动后 LAN 口(默认 192.168.1.1)访问 LuCI → 网络 → 5G 拨号 4. 设置页填 APN(联通 wonet)保存即自动拨号;或状态页手动"启动拨号" 5. 多 WAN 需手动配置(固件按需求不预置策略路由) ## 十、故障排查速查 | 现象 | 排查 | |---|---| | 状态页全灰 | `lsmod | grep pcie_mhi`、`ls -l /dev/mhi_*`、`cat /tmp/5gmodem_guard.log` | | 拨号无 IP | `cat /tmp/quectel_cm.log`(完整日志)、AT 控制台发 `AT+CPIN?` 查 SIM | | 自愈不成功 | 看守护日志阶段提示;600s 仍未恢复需宿主机断电(物理限制) | | AT 控制台无响应 | 确认 `/dev/mhi_DUN` 存在;串口路径在设置页可改 | | ipk 调试 | artifacts 的 packages 里直接 `opkg install` 对应 ipk 到现有系统 |