乐于分享
好东西不私藏

移动通信(五)软件抽象:Modem 如何蜕变为一张标准网卡

移动通信(五)软件抽象:Modem 如何蜕变为一张标准网卡

本文是无线通信系列第五篇,前序文章从移动通信物理信道入手,拆解空口协议,介绍 AP 控制器通过 AT 指令操控 Modem 完成入网,同时梳理了基于高速承载协议的数据传输原理。

依托前文内容,移动通道已从硬件、协议两大底层维度完成理论框架搭建。底层原理落地后,本篇向上切入软件抽象环节:立足 Linux 系统分层架构,逐层解析 Modem 的驱动开发、系统网络管理适配流程,详解 Modem 在软件封装抽象的过程中,我们看看是如何基于AT 指令和高速数据承载协议,最终抽象成系统标准网卡,最终对接 TCP/IP 协议栈实现网络管理和数据通信。

本文,我们从两个角度去理解modem在系统软件封装:控制面和数据面。

  1. 1. 从控制面来看,通用AT指令和QMI / MBIM / CCCI专用的指令是如何协作一起完成整体的网络信号管理和PDN建立以及ip获取等功能;
  2. 2. 从数据面来说,看看各个modem如果通过usb/pci等网卡协议完成标准网卡建立和通信管理

一、架构总览:三个平面的分工

在 Linux 系统里,一个现代 Modem 的软件栈可以清晰地划分为三层:

  • • 内核驱动层:负责识别硬件、暴露控制通道(串口、QMI/MBIM/CCCI 字符设备)和数据通道(网络接口)。驱动不关心 AT 命令的内容,只负责搬运。
  • • 用户空间管理守护进程(如 ModemManager、oFono、ConnMan):这是控制面的核心大脑。它通过控制通道与 Modem 对话,下发 AT/QMI/MBIM 指令,解析响应,并将 IP、DNS、路由等信息配置到内核网络接口上。
  • • TCP/IP 协议栈与数据面驱动:负责实际的 IP 包收发。一旦网络接口被管理面“激活”,数据包就纯粹由内核协议栈和硬件驱动透传,不再需要用户态介入。

这种拆分正是“控制面/数据面分离”思想的落地:控制面负责决策与配置(信号好不好?要建立哪个 APN 的 PDN?IP 是什么?),数据面负责高速搬运(IP 包透传)。两者通过不同类型的硬件端点(Endpoint)和不同的内核接口实现物理隔离。

二、控制面:Modem的“指挥系统”

控制面,是系统用来“指挥”Modem的一系列指令和协议的总和,负责网络的注册、PDN(分组数据网)上下文的建立、IP地址的获取等关键任务。

2.1 核心力量与指挥链路

在Modem的控制管理中,这套“指挥系统”主要由以下几股力量协同完成。

  • • 最高指挥官 (ModemManager):ModemManager是一个运行在用户空间的守护进程。它屏蔽了不同厂商、不同协议Modem的底层硬件差异,为上层应用(如NetworkManager)提供了一个统一的、基于D-Bus接口的管理界面。当用户点击连接网络时,这个指令就是由ModemManager翻译并传达给内核驱动的。
  • • 传令兵 (AT指令集):你可以把AT指令集理解为指挥官的“通用口令”。它简单、基于文本,主要用于发送通用命令或初始化连接。AT 指令是移动通信的“普通话”。上电后,无论面对的是高通、联发科还是展锐平台,系统做的第一件事往往就是通过 USB 串口(/dev/ttyUSB0 之类)发送几条最基础的 AT 命令:
    AT+CPIN?        # 检查 SIM 状态AT+CFUN=1# 开启射频AT+COPS?        # 查询当前注册的网络AT+CREG?        # 查看 CS/PS 域注册状态AT+CGDCONT=1,"IP","cmnet"# 定义 PDP 上下文(APN)
    这些命令完成了 SIM 初始化、网络注册、APN 预设等前置工作。AT 接口通常表现为一个传统的串行终端,可读可写,脚本和程序都能轻易控制。至今它仍然是所有 Modem 管理工具兜底的“万能接口”。然而 AT 有先天局限:它是单工问答式文本协议,每次操作一个命令,交互效率低;对信号质量、邻区信息等复杂结构数据的支持很粗糙;更重要的是,它难以安全高效地同时管理多个 PDN 连接和多个数据流。当智能手机或车载网关需要同时建立 IPv4/IPv6 双栈承载,或者要并发访问企业专网和公网时,AT 的串行化控制就捉襟见肘了。为此,高通、微软、联发科分别推出了自己的专用控制协议。
  • • 特种部队 (QMI / MBIM协议):随着4G/5G时代,Modem功能日益复杂,通用AT指令已无法胜任所有复杂管理任务,于是出现了专用的、二进制编码的协议。它们被形象地称为“特种部队”。
  • • 底层协议与通信总线:无论是指挥官(ModemManager)还是特种部队(QMI/MBIM),它们下达的命令最终都需要通过底层的物理总线(如USB或PCIe)传递给Modem。这些总线也拥有自己的通信协议:
    • • USB: 通常是cdc_mbimcdc_ncm,其中USB CDC-ECM子类能将设备模拟成标准以太网卡,是Modem虚拟成网卡的经典实现。
    • • PCIe: 现代5G Modem的标配。MHI协议(Modem-Host Interface) 是高通等厂商在PCIe总线上的上层协议,它就像数据搬运的“交通规则”,负责高效、灵活地传输控制命令和IP数据包。例如,联发科的t7xx驱动和Intel的iosm驱动都基于MHI协议架构。

2.2 实战:一次典型的控制面建网流程

理解了指挥官、特种部队和底层协议的角色,我们再来看它们是如何协同工作,完成一次典型的“建网”流程的。一次典型的PDN连接建立流程如下:

  1. 1. 硬件枚举:Modem通电,通过PCIe/USB总线被Linux内核识别,加载相应驱动。
  2. 2. 创建通信信道:驱动创建设备文件。例如,t7xx驱动会创建/dev/wwan0mbim0(MBIM信道)和/dev/wwan0at0(AT信道)。
  3. 3. 用户空间接管:ModemManager检测到新设备,打开相应的设备文件。
  4. 4. 协议握手:ModemManager通过信道发起控制协议(如QMI/MBIM)的初始化,与Modem完成版本协商和服务发现。
  5. 5. 配置PDP上下文:ModemManager调用协议接口(如QMI的WDS服务或MBIM的MBIM_CID_CONNECT)配置接入点(APN)。
  6. 6. 激活上下文并获取IP:发送激活命令,Modem与网络侧交互成功后,会将分配的IP地址返回给ModemManager
  7. 7. 配置网络接口:ModemManager将获取到的IP地址配置到对应的网络接口(如wwan0)上,此时网卡正式就绪。

三、数据面:高速管道如何变身标准网卡

控制面把 IP 地址配好了,但是真实的网页浏览、视频流这些数据包,是如何通过 USB 或 PCIe 物理线缆,准确地流入 Linux 网络栈的?这就是数据面抽象的功夫。

3.1 USB 数据通道的多种“化身”

当 Modem 插入 USB 口时,它会向主机枚举为一个复合设备(Composite Device),包含多个接口(Interface):

  • • AT 命令接口(USB ACM 串口)
  • • QMI/MBIM 控制接口(CDC 类接口)
  • • 数据接口:这就是我们“网卡”的前身。

现代 Modem 的数据接口通常以以下几种形态出现:

其中,qmi_wwan + QMI 控制面和 cdc_mbim + MBIM 控制面是目前最主流的组合。当这些驱动匹配到 USB 接口时,会调用 register_netdev() 在内核中注册一个标准的 net_device 结构。由此,ifconfig -a 或 ip link 就会多出一张网卡。

3.2 QMI 数据面:从 Raw IP 到 wwan0

以高通平台为例,qmi_wwan 驱动在探测到 Modem 的数据接口后,创建一个名为 wwan0 的网络设备。这个数据接口在 USB 层面只是一个批量传输端点(Bulk Endpoint),物理上与控制面分离。

当 WDS 服务通过控制面完成 PDN 连接后,Modem 内部会将该 PDN 绑定到这个数据管道上。从 Linux 协议栈下行而来的 IP 包,进入 qmi_wwan 驱动的 ndo_start_xmit 函数,直接被包装成 Raw IP 或 QMAP 帧(在 IP 包前加极简的 1-2 字节头部用于流标识),写入 USB Bulk Out 端点。上行方向同理,驱动从 Bulk In 端点拿到帧,剥除头部后通过 netif_rx() 送入协议栈。

整个过程没有 PPP 封装,没有以太网头(Raw IP 模式干脆就去掉了 14 字节的 MAC 头)。这种“轻量化”的数据通道极大提升了吞吐效率,也正是本系列前文所述高速承载协议落地到主机侧的关键一公里。

3.3 MBIM 与 NCM 的数据封装

MBIM 的数据面与 MBIM 控制面在规范上可以共用接口,但数据流独立。MBIM 数据采用 NCM (Network Control Model) 格式,会在 IP 包外封装一个 NTB (Network Transfer Block) 头部,并支持将多个 IP 包聚合在一个 USB 传输中,以减少中断开销。对内核而言,cdc_mbim 驱动同样注册了一个标准网络设备,IP 栈感知不到封装细节。

3.4 PCIe 下的高速路径:MHI 与直接内存访问

在车载网关、CPE 或高数据率模组中,USB 的带宽和延迟已不够用,PCIe 通道成为首选。此时 Modem 与主机通过 PCIe 总线直连,运行 MHI(Modem Host Interface)协议。

MHI 将 PCIe 的 BAR 空间划分为多个通道(Channel),控制面通道用于 QMI/MBIM 消息传递,数据面通道则专门传送网络包。内核 mhi_net 驱动会为每个 MHI 数据通道创建一个 wwan0 或 mhi_hwip0 网络接口。IP 包在主机内存和 Modem 内存之间通过 DMA 直接搬移,CPU 开销极低,能够轻松支撑 5G NR 的数千兆速率。

无论底层是 USB Bulk、PCIe MHI 还是共享内存,它们的共同归宿都是 Linux 的 struct net_device。一旦这个抽象建立,TCP/IP 协议栈就完全不关心“网线”另一头是光口、电口还是射频空口。


四、融合:一次完整上网的软件交响曲

我们把控制面和数据面拼接起来,看一次典型的 LTE/5G 上网过程:

  1. 1. 硬件枚举 & 驱动绑定:Modem 上电,USB 枚举出 AT 串口(option 驱动)、QMI 控制口(qmi_wwan 或 usbnet 子驱动,创建设备 /dev/cdc-wdm0)和 QMI 数据口(qmi_wwan 网络接口 wwan0)。wwan0 以 DOWN 状态出现在系统中。
  2. 2. AT 初始化:用户空间 ModemManager 打开 /dev/ttyUSB2,发送 AT+CFUN=1AT+CGDCONT=1,"IP","cmnet" 等命令,确认 SIM 与网络注册状态。此时信号强度可用 AT+CSQ 初略判断,但后续会切换到 QMI NAS 信号上报获得精准数据。
  3. 3. 专用协议建立 PDN:ModemManager 打开 /dev/cdc-wdm0,通过 QMI WDS 服务的 Start Network 请求,携带 APN “cmnet” 和 IP 类型 “IPv4”。Modem 内部完成与核心网的承载建立,并返回 IPv4 Address: 10.123.45.6Gateway: 10.123.45.1DNS1: 211.136.20.203 等信息。
  4. 4. 网卡激活:ModemManager 调用 ioctl(SIOCSIFADDR) 和 netlink 消息,将 IP 和路由配置到 wwan0 接口,并将接口状态置为 UP。此时从 ip route 可以看到默认路由指向 wwan0
  5. 5. 数据面高速转发:浏览器发起一个 HTTP 请求,内核协议栈查路由,将 TCP/IP 包交给 wwan0qmi_wwan 驱动的 xmit 函数将 IP 包加上 QMAP 头部,提交到 USB Bulk Out 端点。Modem 接收后经 PDCP/RLC/MAC 直到空口发出。下行的响应数据经空口接收,通过 Bulk In 端点回到主机,剥离 QMAP 头部后经软中断送入 TCP/IP 栈,到达 socket,浏览器渲染出网页。

整个过程完美诠释了“硬件透明、协议隔离”:上层的 Android framework 或 Linux 应用程序,只知道拿到了一张名为 wwan0 的普通网卡,用 DHCP 或静态 IP 配置,然后通信。而实际上,这台网卡背后是一套蜂窝通信的庞大基础设施,但这一切复杂性都被控制面和数据面软件抽象彻底消化了。

五、结语

从 AT 指令的单行对话,到 QMI/MBIM 的二进制服务化交互;从 PPP 拨号的低效串行链路,到 Raw IP/QMAP 的零拷贝高速数据管道;从拼凑式脚本管理,到 ModemManager 与内核 netlink 的自动化融合——Modem 在 Linux 下的软件抽象史,就是一部不断追求“像网线一样简单”的历史。

相关学习资料