参考:

UBUNTU SERVER 18.04 中 EC20 驱动 移植 GOBINET 拨号

linux下如何实现开机自动加载驱动模块

linux内核模块相关命令:lsmod,depmod,modprobe,modinfo,insmod,rmmod 使用说明

需要安装的组件

几个重要路径

1
2
3
4
5
6
内核源码路径 $KSRC: /usr/src/linux-source-4.15.0/
模块安装路径 $KMOD: /lib/modules/`uname -r`/kernel/ 
				=> /lib/modules/4.15.0-45-generic/kernel/
编译临时路径 $KDIR: /lib/modules/`uname -r`/build
				=> /lib/modules/4.15.0-45-generic/build
开机加载模块配置文件: /etc/modules

option驱动

option驱动主要用于发送AT指令(例如重启5G设备,查询当前网络是4G还是5G等)。 使用insmod方法加载时已经错过了PCIE驱动加载,只能发送AT指令或短路引脚重启模块。

修改源码

打开内核源码文件 option.c(路径一般为 drivers/usb/serial/option.c)。在命令行状态下查找是否存在FIBOCOM vendor ID宏定义,如果不存在请参考如下代码定义宏:

1
#define FIBOCOM_VENDOR_ID 0x2CB7

在源码中找到 option_ids 数组,在数组中添加 FG150 模块的 VID 和 PID 信息(第二节列出内容),参考如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
static const struct usb_device_id option_ids[] = {
#if 1
{ USB_DEVICE(FIBOCOM_VENDOR_ID, 0x0104) },
{ USB_DEVICE(FIBOCOM_VENDOR_ID, 0x0105) },
{ USB_DEVICE(FIBOCOM_VENDOR_ID, 0x0107) },
{ USB_DEVICE(FIBOCOM_VENDOR_ID, 0x0108) },
{ USB_DEVICE(FIBOCOM_VENDOR_ID, 0x0109) },
{ USB_DEVICE(FIBOCOM_VENDOR_ID, 0x010A) },
{ USB_DEVICE(FIBOCOM_VENDOR_ID, 0x0110) },
{ USB_DEVICE(FIBOCOM_VENDOR_ID, 0x0111) },
#endif

在 USB 串口驱动中, 过滤 ADB 接口。请在 option_probe 函数添加如下代码内判断当前的 interface number 进行过滤, 具体如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#if 1
if(serial->dev->descriptor.idVendor == FIBOCOM_VENDOR_ID &&
	(((serial->dev->descriptor.idProduct == cpu_to_le16(0x0104) ||
	serial->dev->descriptor.idProduct == cpu_to_le16(0x0105)) &&
	serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)||
	((serial->dev->descriptor.idProduct == cpu_to_le16(0x0109) ||
	serial->dev->descriptor.idProduct == cpu_to_le16(0x010A)) &&
	serial->interface->cur_altsetting->desc.bInterfaceNumber >= 2)))
{
	printk(KERN_INFO "Discovery the interface for FIBOCOM .");
	return -ENODEV;
}

if(((serial->dev->descriptor.idProduct == cpu_to_le16(0x0110) ||
	serial->dev->descriptor.idProduct == cpu_to_le16(0x0111)) &&
	serial->interface->cur_altsetting->desc.bInterfaceNumber < 2))
{
	printk(KERN_INFO "Discovery the interface for FIBOCOM .");
	return -ENODEV;
}
#endif

编译安装

1
2
3
4
5
cd <option.c所在路径>
make -C /lib/modules/`uname -r`/build M=`pwd` obj-m=option.o modules
cp option.ko /lib/modules/`uname -r`/kernel/drivers/usb/serial
depmod
reboot

因为是直接替换了原来的option.ko,所以重启后即可生效。 验证:存在/dev/ttyUSB0~3 设备表示成功

设备名 作用 备注
ttyUSB0 DIAG 获取 modem log 端口
ttyUSB1 MODEM PPP 拨号端口
ttyUSB2 AT RIL 程序发送 AT 命令请求和接收命令响应的端口。

发送AT指令方式

注意:通过发送AT指令到 ttyUSB2 ,使用 cat 监听 ttyUSB2 反馈会报错:Resource temporarily unavailable,须使用 minicom

设置USB枚举模式

  • 用于M2的是使用RMNET拨号(QMI拨号自动识别),其usbmode为17/22/32
  • 用于USB转接卡的是使用ECM拨号的,其usbmode为18/23/33,实测默认值0也可用。
  • 使用at+gtusbmode=xx设置模式,使用at+gtusbmode?查询。设置完成后其PID会发生变化,如果设置为32/33,则可使用lsusb查询其PID/VID,如果PID是0104则是RMNET拨号,如果是0105则是EMC拨号。

image-20210331083242099

设置掉线自动重拨

自动重拨指令 AT+GTAUTOCONNECT=1 这样就能掉线后自动重拨了,否则断开连接需要重新拨号才行。设置后一直生效,掉电保存的。

QMI拨号

安装mhi驱动

安装模组后,执行lspci 可见:04:00.0 Unassigned class [ff00]: Qualcomm Device 0306

编译

将驱动 fibo_mhi文件夹 放到 /usr/src 下。进入执行 make。成功后当前目录下生成 fibo_mhi.ko 文件。

安装

  • 方法一:insmod /usr/src/fibo_mhi/fibo_mhi.ko
  • 方法二:将ko模块放到 /lib/module/$(uname -r)/ 下,执行depmod后:
    • 每次开机使用modprobe fibo_mhi手动安装,然后重启模组: echo -ne "at+cfun=15\r" > /dev/ttyUSB2
    • 【推荐】在/etc/modules中添加fibo_mhi,实现开机自动安装。无需重启模组

验证: 执行 ls /dev/mhi* 可见 /dev/mhi_BHI 表示安装驱动成功但未生效,可见如下更多设备表示生效:

序号 MHI 通道 功能
1 mhi_BHI 下载 firehose 文件端口
2 mhi_DUN AT 指令端口
3 mhi_LOOPBACK mhi 回环测试端口
4 mhi_DIAG 抓取 qxdm log 端口
5 mhi_QMI0 传输 QMI 消息
6 mhi_QMI1 Reserved
7 mhi_GNSS 上报 GPS NEMA 数据
8 mhi_EDL 升级端口(模块处于 edl 模式时枚举)

使用拨号程序手动拨号

  • 将拨号程序 fibo_dial文件夹 放到 /usr/src 下。

  • 执行命令拨号(实测bba中无需修改apn):

    1
    
    /usr/src/fibo_dial/fibocom-dial/src/fibocom-dial -s cunet -d /dev/mhi_QMI0 &
    

    命令详细参数参考:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    root@pi:/usr/src/fibo_dial/fibocom-dial/src# ./fibocom-dial -h
    [11-18_08:46:47:071] fibocom-dial_V1.0.7
    [11-18_08:46:47:071] pcie dial tool 7
    
    [11-18_08:46:47:071] Usage: ./fibocom-dial [options]
    [11-18_08:46:47:071] -s [apn [user password auth]]          Set apn/user/password/auth get from your network provider
    [11-18_08:46:47:071] -p pincode                             Verify sim card pin if sim card is locked
    [11-18_08:46:47:072] -f logfilename                         Save log message of this program to file
    [11-18_08:46:47:072] -i interface                           Specify network interface(default auto-detect)
    [11-18_08:46:47:072] -4                                     IPv4 protocol
    [11-18_08:46:47:072] -6                                     IPv6 protocol
    [11-18_08:46:47:072] -m muxID                               Specify muxid when set multi-pdn data connection.
    [11-18_08:46:47:072] -n channelID                           Specify channelID when set multi-pdn data connection(default 1).
    [11-18_08:46:47:072] -D                                     Using dynamic ip addr
    [11-18_08:46:47:072] -d qmiChannel                    Specify qmi channel
    [11-18_08:46:47:072] [Examples]
    [11-18_08:46:47:072] Example 1: ./fibocom-dial 
    [11-18_08:46:47:072] Example 2: ./fibocom-dial -s cmnet 
    [11-18_08:46:47:072] Example 3: ./fibocom-dial -s cmnet cnay 1234 0 -p 1234 -f dial_log.txt
    

    拨号过程如下:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
    [1] 3153
    root@pi:/usr/src/fibo_mhi# [11-10_09:50:09:896] fibocom-dial_V1.0.7
    [11-10_09:50:09:897] pcie dial tool 7
    
    [11-10_09:50:09:897] /usr/src/fibo_dial/fibocom-dial/src/fibocom-dial profile[1] = cunet///0, pincode = (null)
    [11-10_09:50:09:897] qmap_mode = 1, muxid = 0x81, qmap_netcard = pcie_mhi0
    [11-10_09:50:09:931] cdc_wdm_fd = 7
    [11-10_09:50:10:932] QmiThreadSendQMITimeout pthread_cond_timeout_np=110, errno: 2 (No such file or directory)
    [11-10_09:50:11:942] Get clientWDS = 15
    [11-10_09:50:11:946] Get clientDMS = 1
    [11-10_09:50:11:949] Get clientNAS = 2
    [11-10_09:50:11:955] Get clientUIM = 2
    [11-10_09:50:11:959] Get clientWDA = 1
    [11-10_09:50:11:962] requestBaseBandVersion 89602.1000.00.04.02.04
    [11-10_09:50:11:966] qmap_settings.rx_urb_size = 32768
    [11-10_09:50:11:982] requestGetSIMStatus SIMStatus: SIM_READY
    [11-10_09:50:11:982] requestSetProfile[1] cunet///0
    [11-10_09:50:11:994] requestGetProfile[1] cunet///0
    [11-10_09:50:11:998] requestRegistrationState2 MCC: 460, MNC: 1, PS: Attached, DataCap: LTE
    [11-10_09:50:12:002] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
    [11-10_09:50:12:014] requestRegistrationState2 MCC: 460, MNC: 1, PS: Attached, DataCap: LTE
    [11-10_09:50:12:035] requestSetupDataCall WdsConnectionIPv4Handle: 0x5cf3a0b0
    [11-10_09:50:12:055] requestQueryDataCall IPv4ConnectionStatus: CONNECTED
    [11-10_09:50:12:058] echo 1 > /sys/module/fibo_mhi/parameters/macaddr_check
    [11-10_09:50:12:060] ifconfig pcie_mhi0 up
    [11-10_09:50:12:066] ifconfig pcie_mhi0 10.122.67.27 netmask 255.255.255.248
    [11-10_09:50:12:072] route add default gw 10.122.67.28 dev pcie_mhi0
    
  • 使用 ping 测试网络连通。

自动拨号脚本

以下脚本可放到 rc.local 中,加执行权限,可实现自动拨号。

1
2
#!/bin/bash
nohup /usr/src/fibo_dial/fibocom-dial/src/fibocom-dial -s cunet -d /dev/mhi_QMI0 >> /usr/src/fibo_dial/dial.log &

ECM拨号

ECM(Ethernet Networking Control Model 以太网控制模型) 用于在设备和主机之间传输以太网数据 包。在操作系统看来, CDC ECM 设备就是一个虚拟以太网卡,包含标准网卡需要的 MAC 地址和 IP 地址。 CDC ECM 设备通常是一个以太网卡,用于连接 LAN 或者是 WLAN。当客户主机发起 ECM 拨号的请求时, 模块相当于一个路由器, 模块内部会调用相应的服务实现 WWAN 拨号。在拨号成功后,模块内部会启动 DHCP server 等功能。客户端应用系统 通过 DHCP client 服务, 获取模块 DHCP server 分配的 IP 。客户 主机调用 DHCP 等脚本实现把模块从网络侧获取到的 IP 和 DNS 配置到本机,实现上网。

查询虚拟网卡

Ubuntu14.04 ECM 网卡名为 usb0, ubuntu16.04 ECM 网卡名为 ens35u1i4, ubuntu18.04 不一样, 譬 如可能会取名 ens35u1i3。 具体名字看具体情况。 一般可以通过 dmesg | grep usb 获取如下信息:

1
2
3
4
5
6
7
8
9
[    8.875790] usbcore: registered new interface driver cdc_ether
[    8.889243] usbcore: registered new interface driver option
[    8.889258] usbserial: USB Serial support registered for GSM modem (1-port)
[    8.892961] usb 2-1: GSM modem (1-port) converter now attached to ttyUSB0
[    8.893136] usb 2-1: GSM modem (1-port) converter now attached to ttyUSB1
[    8.893266] usb 2-1: GSM modem (1-port) converter now attached to ttyUSB2
[    8.893376] usb 2-1: GSM modem (1-port) converter now attached to ttyUSB3
[    9.003920] usbcore: registered new interface driver btusb
[    9.164534] cdc_ether 2-1:1.4 enp0s21f0u1i4: renamed from usb0

网卡名为最后一行,确认网卡存在:

image-20210330102814269

使用AT指令拨号

以下是正常拨号流程,可直达红框部分,有问题需排查时再从头执行。

image-20210330101059503

激活网卡

udhcpc -i enp0s21f0u1i4

再次查询网卡 ip addr 可见网卡已有IP。

添加路由表

先确认路由表中不存在虚拟网卡的默认路由,然后添加,之后再次确认已添加,最后测试上网。

image-20210330103642140

查询网络、信号、APN和IP

查询注网 COPS

注册网络信息,最后一位7代表4G, 11和13应该分别代表SA和NSA

1
2
AT+COPS? 
+COPS: 0,0,"460 31",11

查询信号 CSQ/GTCCINFO

CSQ

响应格式:+CSQ: ,

1
2
3
4
5
6
7
8
9
<rssi>: integer type
0 -113 dBm or less
1 -111 dBm
2...30 -109... -53 dBm
31 -51 dBm or greater
99 not known or not detectable
<ber>: integer type; channel bit error rate (in percent)
0...7 as RXQUAL values in the table in 3GPP TS 45.008 subclause 8.2.4
99 not known or not detectable

如下响应为:-51 dBm or greater

1
2
at+csq?
+CSQ: 31,99

5G应使用GTCCINFO

倒数第三位含义如下:

image-20210331092919365

如下响应表示LTE,65, 对应信号强度 -44-(96-65)=-75dbm

1
2
3
4
5
6
7
8
at+gtccinfo?
+GTCCINFO:
LTE service cell:
1,4,460,01,ED0A,1081F04,672,1A1,103,100,50,65,65,34

LTE neighbor cell:

OK

信号格数与信号强度对应表

image-20201202104548638

查询APN和IP CGDCONT

PDP context

1
2
3
4
5
6
AT+CGDCONT?
+CGDCONT: 1,"IP","bmw","10.188.134.14",0,0,0,0,,,,,,,,,"",,,,0
+CGDCONT: 2,"IPV4V6","3GWAP","0.0.0.0,0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0",0,0,0,0,,,,,,,,,"",,,,0
+CGDCONT: 3,"IPV4V6","WONET","0.0.0.0,0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0",0,0,0,0,,,,,,,,,"",,,,0
+CGDCONT: 4,"IPV4V6","IMS","0.0.0.0,0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0",0,0,0,0,,,,,,,,,"",,,,0
+CGDCONT: 5,"IPV4V6","SOS","0.0.0.0,0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0",0,0,0,1,,,,,,,,,"",,,,0

APN为bmw, IP为10.188.134.14,物联网专用卡与IP是绑定的,拨号成功即可访问企业内网。

重启模块

AT+CFUN=15

网络测速

1
2
git clone https://github.com/sivel/speedtest-cli.git
./speedtest-cli/speedtest.py

固件版本

拨号日志可见固件版本:

1
2
[03-24_15:50:46:173] requestBaseBandVersion 89602.1000.00.04.05.12
[03-24_15:50:46:175] qmap_settings.rx_urb_size = 32768

或者使用at指令 ati8ati(显示更多):

1
2
过时:89602.1000.00.04.05.12
最新:89602.1000.00.04.07.20

草稿

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#查询信号扩展,倒数第三位信号质量,倒数第二位信号强度,均是0-126信号逐渐增加,255未知
AT+CESQ
#+CESQ: 99,99,255,255,255,255,65,79,113

AT+CGDCONT #设APN
AT$QCRMCALL=1,1,3 #QMI
AT+GTRNDIS=1,1
AT+GTRNDIS?

#################
ifconfig enp0s21f0u7i4 up
udhcpc -i enp0s21f0u7i4 或 dhclient -i enp0s21f0u7i4
insmod /usr/src/fibo_mhi/fibo_mhi.ko
#################
修改 qsdk/qca/src/linux-4.4/driver/Kconfig
source "drivers/fibo_mhi/Kconfig"

修改 qsdk/qca/src/linux-4.4/driver/Makefile
obj-$(CONFIG_PCIE_MHI) += fibo_mhi/

在 qsdk\target\linux\ipq\ipq807x\ config-default 中增加编译宏
CONFIG_PCIE_MHI=y
CONFIG_PCI_MSI=y

ping 10.196.100.33