在进行驱动移植前,首先得下载linux内核源码
参考前一篇博客:https://blog.csdn.net/qq_42908042/article/details/97129502

一.增加PID&VID(对着两个不了解的,建议去找找资料来看看,这个的意思可以简单理解为这个设备的唯一标识)
到自己的linux内核文件下,执行命令

cd  /drivers/usb/serial/                  //到相应文件夹
sudo chmod a+w option.c    //该文件是只可读文件,给文件写的权限
sudo vim option.c

在这里插入图片描述
如果找不到相应的位置,在命令行输入**/关键字/**回车
插入如下代码:

 #if 1 //Added by Quectel
 { USB_DEVICE(0x05C6, 0x9090) }, /* Quectel UC15 */ 
 { USB_DEVICE(0x05C6, 0x9003) }, /* Quectel UC20 */ 
 { USB_DEVICE(0x2C7C, 0x0125) }, /* Quectel EC25 */
 { USB_DEVICE(0x2C7C, 0x0121) }, /* Quectel EC21 */ 
 { USB_DEVICE(0x05C6, 0x9215) }, /* Quectel EC20 */ 
 { USB_DEVICE(0x2C7C, 0x0191) }, /* Quectel EG91 */ 
 { USB_DEVICE(0x2C7C, 0x0195) }, /* Quectel EG95 */
 { USB_DEVICE(0x2C7C, 0x0306) }, /* Quectel EG06/EP06/EM06 */
 { USB_DEVICE(0x2C7C, 0x0296) }, /* Quectel BG96 */
 { USB_DEVICE(0x2C7C, 0x0435) }, /* Quectel AG35 */
 #endif

在这里插入图片描述退出保存

对于EC20模组,如果下面的文件和代码下存在 kernel源文件中,需要注释或者删除它们。否则它们将会和EC20 串口驱动冲突。
File: [KERNEL]/drivers/usb/serial/qcserial.c
在这里插入图片描述
File: [KERNEL]/drivers/net/usb/qmi_wwan.c
在这里插入图片描述
注意这里貌似只有EC20的冲突了。

退出保存
二.添加零包处理(这个和usb 协议中的批量传输有关)

执行命令vim usb_wwan.c

   usb_fill_bulk_urb(urb, serial->dev,      usb_sndbulkpipe(serial->dev, endpoint) | dir,      buf, len, callback, ctx);
    #if 1 //Added by Sky 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 
--------------------- 

在这里插入图片描述
退出保存

三.增加休眠后唤醒接口
执行命令 vim option.c
添加代码:

#if 1  //Added by Sky  
.reset_resume   = usb_wwan_resume, 
#endif

在这里插入图片描述
四.如果要使用 GobiNet or QMI WWAN,需要阻止第四个接口注册为串口。
执行命令 vim option.c
添加代码:

    static int option_probe(struct usb_serial *serial,
                const struct usb_device_id *id)
    {
        struct usb_interface_descriptor *iface_desc =
                    &serial->interface->cur_altsetting->desc;
        struct usb_device_descriptor *dev_desc = &serial->dev->descriptor;
    
        /* Never bind to the CD-Rom emulation interface */
        if (iface_desc->bInterfaceClass == 0x08)
            return -ENODEV;
    
        /*
         * Don't bind reserved interfaces (like network ones) which often have
         * the same class/subclass/protocol as the serial interfaces.  Look at
         * the Windows driver .INF files for reserved interface numbers.
         */
        if (is_blacklisted(
            iface_desc->bInterfaceNumber,
            OPTION_BLACKLIST_RESERVED_IF,
            (const struct option_blacklist_info *) id->driver_info))
            return -ENODEV;
        /*
         * Don't bind network interface on Samsung GT-B3730, it is handled by
         * a separate module.
         */
        if (dev_desc->idVendor == cpu_to_le16(SAMSUNG_VENDOR_ID) &&
            dev_desc->idProduct == cpu_to_le16(SAMSUNG_PRODUCT_GT_B3730) &&
            iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA)
            return -ENODEV;
    
    
            #if 1  //Added by Sky 
            //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->des

c.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 EC21&EC25&EC20 R2.0's interface 4 can be used as USB Network device  
        if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)   \
            && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)   
            return -ENODEV; 
        #endif 


    /* Store device id so we can use it during attach. */
    usb_set_serial_data(serial, (void *)id);

    return 0;
}
--------------------- 

在这里插入图片描述
保存退出

五.修改内核配置,并编译内核,刷入新内核
1.切换到内核目录
cd <你的内核目录>
在这里插入图片描述
2.编译内核
执行命令 sudo make menuconfig
此时可能报错
错误:

*** Unable to find the ncurses libraries or the
*** required header files.
*** ‘make menuconfig’ requires the ncurses libraries.
***
*** Install ncurses (ncurses-devel) and try again.

根据错误报告是缺少Ncurses库,需要安装该库(Ncurses 提供字符终端处理库,包括面板和菜单)

详见ncures_百度百科

解决办法如下:
CentOS:
yum install -y ncurses-devel

Ubuntu:
sudo apt-get install ncurses-dev

3.添加USB 串口 GSM 和 CDMA 驱动选项
在这里插入图片描述
在这里插入图片描述
保存配置

4.启用USB网络支持
在这里插入图片描述
5.添加驱动代码
[KERNEL]/drivers/net/usb/Makefile"

obj-y += GobiNet.o 
GobiNet-objs := GobiUSBNet.o QMIDevice.o QMI.o 

六.建立下载驱动作为Linux主机的内核

1.切换到内核目录
cd <你的内核目录>
2.构建驱动

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

3.下载驱动并且重启

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
Logo

更多推荐