Files
LFLede/README.md
T
2026-08-21 18:30:44 +08:00

191 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 <APN>` 即可,传 `-i rmnet_mhi0` 会导致异常 |
| 驱动版本 | pcie_mhi V1.3.8(源码来自 Siriling/5G-Modem-Support 的 quectel_MHI |
| 拨号工具 | quectel-CM V1.6.8QConnectManagerMBIM 路径实测通过) |
| 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 <bdf> > /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 内嵌 JS145 行) | 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.04lede 官方 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/e1000eKVM 常见网卡)+ 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 到现有系统 |