我是靠谱客的博主 迷你摩托,最近开发中收集的这篇文章主要介绍linux添加ec20,Linux下对接EC20,EC25,4G模组驱动安装,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Linux 下安装 移远4G模块驱动,并调试

安装环境

ubuntu 18.04

内核linux-Kernel-4.15.0

对接移远的 EC25的 4G 模组.

注意事项

如果碰到 AT命令 一组命令都正常. 但是用PPP或者 gobinet +QconnectManager 都拨号不成功的话,得思考一下相关桌面系统有没有安装其他的网络或者4G拨号工具.比如我使用的ubuntu 安装了modemmanager,得把它卸载掉apt-get remove modemmanager.

安装前准备

下载内核源码

sudo apt install linux-source-4.15.0

或者 到https://mirrors.edge.kernel.org/pub/linux/kernel/下载源码

有些系统被设置了 禁止apt

# 在终端输入下面命令强制解锁

sudo rm /var/cache/apt/archives/lock

sudo rm /var/lib/dpkg/lock

sudo rm /var/lib/dpkg/lock-frontend

复制代码编译内核需要一些图形化处理的库

sudo apt-get install libncurses5-dev libssl-dev

sudo apt-get install build-essential openssl

sudo apt-get install zlibc minizip

sudo apt-get install libidn11-dev libidn11

复制代码

如果报错:某某 依赖没有被安装,去pkgs.org 该网站下载 例如: libncurses5-dev_6.1-1ubuntu1.18.04_amd64.deb

下载好后 dpkg -i 路径/

特别注意modemmanager

这是个坑,因为modemmanager 也是拨号上网的程序,只要把它卸载了才能拨号成功.

apt-get remove modemmanager

更改内核源码

添加USB 相关的内核源码

add VID 和 PID

/drivers/usb/serial/option.c

static const struct usb_device_id option_ids[] = {

#if 1 //Added by Quectel

{ USB_DEVICE(0x2C7C, 0x0125) }, /* Quectel EC25 */

#endif

}

复制代码/drivers/usb/serial/qcserial.c

# 删除这行

{USB_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */

复制代码/drivers/net/usb/qmi_wwan.c

# 删除这行

{QMI_GOBI_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */

复制代码添加USB数据包传输机制

/drivers/usb/serial/usb_wwan.c

static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,

int endpoint,

int dir, void *ctx, char *buf, int len,

void (*callback) (struct urb *))

{

struct usb_serial *serial = port->serial;

struct urb *urb;

urb = usb_alloc_urb(0, GFP_KERNEL);/* No ISO */

if (!urb)

return NULL;

usb_fill_bulk_urb(urb, serial->dev,

usb_sndbulkpipe(serial->dev, endpoint) | dir,

buf, len, callback, ctx);

#if 1 //Added by Quectel for zero packet

if (dir == USB_DIR_OUT) {

struct usb_device_descriptor *desc = &serial->dev->descriptor;

if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9090))

urb->transfer_flags |= URB_ZERO_PACKET;

if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9003))

urb->transfer_flags |= URB_ZERO_PACKET;

if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9215))

urb->transfer_flags |= URB_ZERO_PACKET;

if (desc->idVendor == cpu_to_le16(0x2C7C))

urb->transfer_flags |= URB_ZERO_PACKET;

}

#endif

return urb;

}

复制代码添加系统的重启 和设备重启的机制

/drivers/usb/serial/option.c

static struct usb_serial_driver option_1port_device = {

.read_int_callback = option_instat_callback,

#ifdef CONFIG_PM

.suspend = usb_wwan_suspend,

.resume = usb_wwan_resume,

#if 1 //Added by Quectel

.reset_resume = usb_wwan_resume,

#endif

#endif

};

复制代码Use GobiNet or QMI WWAN 使用 GobiNet 拨号

/drivers/usb/serial/option.c

static int option_probe(struct usb_serial *serial,

const struct usb_device_id *id){

/*

* Allow matching on bNumEndpoints for devices whose interface numbers

* can change (e.g. Quectel EP06).

*/

if (device_flags & NUMEP2 && iface_desc->bNumEndpoints != 2)

return -ENODEV;

#if 1 //Added by Quectel

//Quectel UC20's interface 4 can be used as USB network device

if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&

serial->dev->descriptor.idProduct == cpu_to_le16(0x9003)

&& serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)

return -ENODEV;

//Quectel EC20's interface 4 can be used as USB network device

if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&

serial->dev->descriptor.idProduct == cpu_to_le16(0x9215)

&& serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)

return -ENODEV;

//Quectel EC25&EC21&EG91&EG95&EG06&EP06&EM06&BG96/AG35's interface 4 can be used as

if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)

&& serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)

return -ENODEV;

#endif

#if 1 //Added by Quectel

//For USB Auto Suspend

if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&

serial->dev->descriptor.idProduct == cpu_to_le16(0x9090)) {

pm_runtime_set_autosuspend_delay(&serial->dev->dev, 3000);

usb_enable_autosuspend(serial->dev);

}

if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&

serial->dev->descriptor.idProduct == cpu_to_le16(0x9003)) {

pm_runtime_set_autosuspend_delay(&serial->dev->dev, 3000);

usb_enable_autosuspend(serial->dev);

}

if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&

serial->dev->descriptor.idProduct == cpu_to_le16(0x9215)) {

pm_runtime_set_autosuspend_delay(&serial->dev->dev, 3000);

usb_enable_autosuspend(serial->dev);

}

if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {

pm_runtime_set_autosuspend_delay(&serial->dev->dev, 3000);

usb_enable_autosuspend(serial->dev);

}

#endif

#if 1 //Added by Quectel

//For USB Remote Wakeup

if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&

serial->dev->descriptor.idProduct == cpu_to_le16(0x9090)) {

device_init_wakeup(&serial->dev->dev, 1); //usb remote wakeup

}

if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&

serial->dev->descriptor.idProduct == cpu_to_le16(0x9003)) {

device_init_wakeup(&serial->dev->dev, 1); //usb remote wakeup

}

if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) &&

serial->dev->descriptor.idProduct == cpu_to_le16(0x9215)) {

device_init_wakeup(&serial->dev->dev, 1); //usb remote wakeup

}

if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {

device_init_wakeup(&serial->dev->dev, 1); //usb remote wakeup

}

#endif

/* Store the device flags so we can use them during attach. */

usb_set_serial_data(serial, (void *)device_flags);

return 0;

}

复制代码

添加 GobiNet Driver 拨号内核源码

添加QMI WWAN Driver 内核源码

添加VID and PID

/drivers/net/usb/qmi_wwan.c

static const struct usb_device_id products[] = {

#if 1 //Added by Quectel

#ifndef QMI_FIXED_INTF

/* map QMI/wwan function by a fixed interface number */

#define QMI_FIXED_INTF(vend, prod, num) /

.match_flags = USB_DEVICE_ID_MATCH_DEVICE |

USB_DEVICE_ID_MATCH_INT_INFO, /

.idVendor = vend, /

.idProduct = prod, /

.bInterfaceClass = 0xff, /

.bInterfaceSubClass = 0xff, /

.bInterfaceProtocol = 0xff, /

.driver_info = (unsigned long)&qmi_wwan_force_int##num,

#endif

{ QMI_FIXED_INTF(0x2C7C, 0x0125, 4) }, /* Quectel EC25 */

#endif

}

复制代码/drivers/usb/serial/qcserial.c

# 删除这行

{USB_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */

复制代码/drivers/net/usb/qmi_wwan.c

# 删除这行

{QMI_GOBI_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */

复制代码Add Support for Raw IP Mode

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#if 1 //Added by Quectel

#include

struct sk_buff *qmi_wwan_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags){

if (dev->udev->descriptor.idVendor != cpu_to_le16(0x2C7C))

return skb;

// Skip Ethernet header from message

if (skb_pull(skb, ETH_HLEN)) {

return skb;

} else {

dev_err(&dev->intf->dev, "Packet Dropped ");

}

// Filter the packet out, release it

dev_kfree_skb_any(skb);

return NULL;

}

#include

#if (LINUX_VERSION_CODE < KERNEL_VERSION( 3,9,1 ))

static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb){

__be16 proto;

if (dev->udev->descriptor.idVendor != cpu_to_le16(0x2C7C))

return 1;

/* This check is no longer done by usbnet */

if (skb->len < dev->net->hard_header_len)

return 0;

switch (skb->data[0] & 0xf0) {

case 0x40:

proto = htons(ETH_P_IP);

break;

case 0x60:

proto = htons(ETH_P_IPV6);

break;

case 0x00:

if (is_multicast_ether_addr(skb->data))

return 1;

/* possibly bogus destination - rewrite just in case */

skb_reset_mac_header(skb);

goto fix_dest;

default:

/* pass along other packets without modifications */

return 1;

}

if (skb_headroom(skb) < ETH_HLEN)

return 0;

skb_push(skb, ETH_HLEN);

skb_reset_mac_header(skb);

eth_hdr(skb)->h_proto = proto;

memset(eth_hdr(skb)->h_source, 0, ETH_ALEN);

fix_dest:

memcpy(eth_hdr(skb)->h_dest, dev->net->dev_addr, ETH_ALEN);

return 1;

}

/* very simplistic detection of IPv4 or IPv6 headers */

static bool possibly_iphdr(const char *data){

return (data[0] & 0xd0) == 0x40;

}

#endif

#endif

static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf){

#if 1 //Added by Quectel

if (dev->udev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {

dev_info(&intf->dev, "Quectel EC25&EC21&EG91&EG95&EG06&EP06&EM06&BG96&AG35 work on RawIP moden");

dev->net->flags |= IFF_NOARP;

#if (LINUX_VERSION_CODE < KERNEL_VERSION( 3,9,1 ))

/* make MAC addr easily distinguishable from an IP header */

if (possibly_iphdr(dev->net->dev_addr)) {

dev->net->dev_addr[0] |= 0x02; /* set local assignment bit */

dev->net->dev_addr[0] &= 0xbf; /* clear "IP" bit */

}

#endif

usb_control_msg(

interface_to_usbdev(intf),

usb_sndctrlpipe(interface_to_usbdev(intf), 0),

0x22, //USB_CDC_REQ_SET_CONTROL_LINE_STATE

0x21, //USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE

1, //active CDC DTR

intf->cur_altsetting->desc.bInterfaceNumber,

NULL, 0, 100);

}

#endif

err:

return status;

}

static const struct driver_infoqmi_wwan_info = {

.description= "WWAN/QMI device",

.flags= FLAG_WWAN | FLAG_SEND_ZLP,

.bind= qmi_wwan_bind,

.unbind= qmi_wwan_unbind,

.manage_power= qmi_wwan_manage_power,

.rx_fixup = qmi_wwan_rx_fixup,

#if 1 //Added by Quectel

.tx_fixup = qmi_wwan_tx_fixup,

.rx_fixup = qmi_wwan_rx_fixup,

#endif

};

/* if follow struct exist, modify it as below 如果源码有就改,没有就省略*/

static const struct driver_info qmi_wwan_force_int4 = {

……

#if 1 //Added by Quectel

.tx_fixup = qmi_wwan_tx_fixup,

.rx_fixup = qmi_wwan_rx_fixup,

#endif

};

/* if follow struct exist, modify it as below 如果源码有就改,没有就省略*/

static const struct driver_info qmi_wwan_shared = {

……

#if 1 //Added by Quectel

.tx_fixup = qmi_wwan_tx_fixup,

.rx_fixup = qmi_wwan_rx_fixup,

#endif

复制代码

配置make menuconfig

空 代表无 * 代表 M 代表只编译,加入后才有效

[*] Device Drivers →

[*] USB Support →

[*] USB Serial Converter support →

[*] USB driver for GSM and CDMA modems

[*] Device Drivers →

[*] Network device support →

[*] PPP (point-to-point protocol) support

[*] Device Drivers →

-*- Network device support →

USB Network Adapters →

{*} Multi-purpose USB Networking Framework

QMI WWAN driver for Qualcomm MSM based 3G and LTE modems

复制代码单独编译某些内核源码

# 编译USB方面的

sudo make -C /lib/modules/`uname -r`/build M=`pwd`/drivers/usb/serial obj-m=option.o modules

sudo make -C /lib/modules/`uname -r`/build M=`pwd`/drivers/usb/serial obj-m=usb_wwan.o

modules

sudo make -C /lib/modules/`uname -r`/build M=`pwd`/drivers/usb/serial obj-m=qcserial.o modules

sudo cp drivers/usb/serial/option.ko /lib/modules/`uname -r`/kernel/drivers/usb/serial

sudo cp drivers/usb/serial/usb_wwan.ko /lib/modules/`uname -r`/kernel/drivers/usb/serial

sudo cp drivers/usb/serial/qcserial.ko /lib/modules/`uname -r`/kernel/drivers/usb/serial

sudo depmod

sudo reboot

# 编译 GobiNet Driver

sudo make -C /lib/modules/`uname -r`/build M=`pwd`/drivers/net/usb obj-m=GobiNet.o modules

# 这个是重复的模块,上面编译了下面就可以不加

sudo make -C /lib/modules/`uname -r`/build M=`pwd`/drivers/usb/serial obj-m=qcserial.o modules

sudo cp drivers/net/usb/GobiNet.ko /lib/modules/`uname -r`/kernel/drivers/net/usb

sudo cp drivers/usb/serial/qcserial.ko /lib/modules/`uname -r`/kernel/drivers/usb/serial

sudo depmod

sudo reboot

# 编译 QMI WWAN Driver

sudo make -C /lib/modules/`uname -r`/build M=`pwd`/drivers/net/usb obj-m=qmi_wwan.o modules

# 这个是重复的模块,上面编译了下面就可以不加

sudo make -C /lib/modules/`uname -r`/build M=`pwd`/drivers/usb/serial obj-m=qcserial.o modules

sudo cp drivers/net/usb/qmi_wwan.ko /lib/modules/`uname -r`/kernel/drivers/net/usb

sudo cp drivers/usb/serial/qcserial.ko /lib/modules/`uname -r`/kernel/drivers/usb/serial

sudo depmod

sudo reboot

复制代码

配置 netplan 双网卡和路由信息

/etc/netplan/01-netcfg.yaml

# Let NetworkManager manage all devices on this system

# renderer: NetworkManager enp0s20f0u4i4

network:

ethernets:

enp4s0:

dhcp4: false

addresses: [192.168.3.100/24]

routes:

- to: 0.0.0.0/0

最后

以上就是迷你摩托为你收集整理的linux添加ec20,Linux下对接EC20,EC25,4G模组驱动安装的全部内容,希望文章能够帮你解决linux添加ec20,Linux下对接EC20,EC25,4G模组驱动安装所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部