在进行驱动移植前,首先得下载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