Linux之USB串口option驱动简介
Linux之USB串口option驱动简介
概述
在Linux内核中,option 驱动(源码位于 drivers/usb/serial/option.c)是最重要、最常用的USB串口驱动之一。它最初是为了支持GSM/CDMA调制解调器(Modem)而开发的,但现在广泛用于支持各种 3G/4G/5G 蜂窝网络模块(如移远、广和通、华为、中兴、SIMCom等)以及部分工业USB转串口设备,它是 Linux 移动宽带生态的基石。
一、 option 驱动的核心作用
option 驱动的主要任务是将USB蜂窝模块的串行通信接口映射为Linux系统中的字符设备(通常是 /dev/ttyUSBx 或 /dev/ttyACMx)。
通过这些串口,用户空间程序(如 pppd, ModemManager, minicom)可以:
- 发送 AT 指令控制模块(拨号、查询信号、发短信)。
- 进行 PPP 拨号上网(传统方式)。
- 抓取模块的底层 Debug 日志(DM/DIAG 口)。
- 读取 GPS NMEA 数据。
二、 核心匹配机制 (Device Matching)
option 驱动如何知道该接管哪个USB设备?它依赖以下三种机制:
1. 静态匹配 (VID/PID 白名单)
在内核源码的 option_ids[] 数组中,硬编码了大量已知模块的 Vendor ID (VID) 和 Product ID (PID)。当USB设备插入时,内核会比对VID/PID,如果命中则加载 option 驱动。
2. 动态匹配 (Dynamic ID)
如果你的模块是新产品,内核中没有它的VID/PID,可以通过 sysfs 动态添加,无需重新编译内核:
# 假设你的模块 VID 是 2c7c,PID 是 0125 (移远 EC20)
echo "2c7c 0125" > /sys/bus/usb-serial/drivers/option1/new_id
注:重启后失效,需写入 udev 规则实现持久化。
3. 接口类匹配 (Class/SubClass/Protocol)
某些模块不依赖具体的VID/PID,而是通过USB接口描述符中的 Class(通常为 0xFF Vendor Specific)、SubClass 和 Protocol 来匹配。
三、 多端口 (Multi-port) 与 接口过滤
现代4G/5G模块通常是 **USB复合设备 (Composite Device)**,包含多个USB接口(Interface)。一个模块可能同时暴露出 串口、网卡、存储(CD-ROM)等。
1. 端口功能区分
option 驱动接管串口后,通常会生成多个 /dev/ttyUSBx 节点。常见的端口功能如下(具体顺序因模块而异):
- **DM / DIAG (Diagnostic)**:用于高通 QXDM 等工具抓取底层 Log。
- GPS / NMEA:输出 GPS 定位数据。
- **AT (AT Command)**:用于发送 AT 指令,控制模块。
- Modem / PPP:用于传统的 PPP 数据拨号。
- ADB:Android 调试桥端口(针对运行 Android 系统的模块)。
2. 黑名单机制 (Blacklist)
这是 option 驱动中最关键的设计之一。
模块中的某些接口(如 QMI, MBIM, ECM, RNDIS 网络接口)绝对不能被 option 接管,否则会导致无法上网。option 驱动内部维护了一个 option_blacklist。在 probe 阶段,如果检测到当前接口是网络接口,option 会返回 -ENODEV,从而把该接口让给 qmi_wwan、cdc_mbim 或 cdc_ether 等网络驱动。
四、 实战操作与调试指南
1. 查看驱动是否加载及设备状态
# 查看 option 驱动是否加载
lsmod | grep option
# 查看内核日志,确认设备识别和端口分配
dmesg | grep -i option
dmesg | grep -i ttyUSB
典型的 dmesg 输出:
usb 1-1: new high-speed USB device number 4 using xhci_hcd
option 1-1:1.0: GSM modem (1-port) converter detected
usb 1-1:1.0: converter now attached to ttyUSB0
option 1-1:1.2: GSM modem (1-port) converter detected
usb 1-1:1.2: converter now attached to ttyUSB2
2. 区分哪个是 AT 口?
如果你面对 /dev/ttyUSB0, 1, 2 不知道哪个是 AT 口,可以使用以下方法:
# 依次向每个端口发送 AT 指令,有 "OK" 返回的就是 AT 口
echo -e "AT\r\n" > /dev/ttyUSB0 && cat /dev/ttyUSB0 &
# 或者使用 microcom / minicom 工具连接测试
microcom -s 115200 /dev/ttyUSB0
3. 查看蜂窝网络模组的各种接口及驱动状态
cat /sys/kernel/debug/usb/devices
五、 常见“坑”与解决方案
1. 设备识别为 CD-ROM (usb_modeswitch)
现象:插入模块后,lsusb 显示为 Mass Storage(U盘),没有生成 ttyUSB。
原因:很多模块默认启动为 “CD-ROM 模式”(里面装有 Windows 驱动),需要先发送特定的 USB 控制传输将其切换为 “Modem 模式”。
解决:安装并使用 usb-modeswitch。
sudo usb_modeswitch -W -v 2c7c -p 0125 -M '555343...' # 具体参数查阅模块手册或 modeswitch 数据库
2. 网络接口被 option 错误接管 (无法上网)
现象:模块识别出了很多 ttyUSB,但是 wwan0 或 usb0 网卡没有出现,导致 QMI/MBIM 拨号失败。
原因:内核版本较老,option 驱动的黑名单不全,把网络接口也当成串口接管了。
解决:
- 升级 Linux 内核(推荐 4.14 以上,最好 5.x)。
- 如果是特定接口被占用,可以通过 sysfs 强制解绑(不推荐,治标不治本):
# 假设 ttyUSB3 是网络口被错误接管 echo "1-1:1.4" > /sys/bus/usb-serial/drivers/option1/unbind
六、 option 与其他 USB 驱动的区别
在 Linux 中,处理 USB 串口/网络的驱动有很多,需根据场景选择:
| 驱动名称 | 适用场景 | 说明 |
|---|---|---|
option |
3G/4G/5G 蜂窝模块的串口 (AT/DM/PPP) | 最核心的 Modem 串口驱动,支持多端口和复杂接口过滤。 |
ch341 / cp210x / ftdi_sio |
特定的 USB 转串口芯片 | 针对 CH340, CP2102, FT232 等桥接芯片的专用驱动。 |
cdc_acm |
标准 CDC-ACM 设备 (如 Arduino, 普通 USB 转串口) | 遵循 USB-IF 标准协议的设备。如果模块配置为标准 ACM,会被此驱动接管。 |
qmi_wwan |
4G/5G 模块的 QMI 网络接口 | 配合 option 使用,option 管串口,qmi_wwan 管上网(生成 wwan0)。 |
cdc_mbim / cdc_ncm |
4G/5G 模块的 MBIM/NCM 网络接口 | 用于较新的 4G/5G 模块的高速网络接口。 |






