Chinaunix首页 | 论坛 | 博客
  • 博客访问: 813190
  • 博文数量: 296
  • 博客积分: 5376
  • 博客等级: 大校
  • 技术积分: 2298
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-14 19:02
文章分类

全部博文(296)

文章存档

2023年(2)

2020年(2)

2018年(2)

2017年(26)

2016年(4)

2015年(19)

2014年(12)

2013年(26)

2012年(84)

2011年(50)

2010年(41)

2009年(28)

分类: LINUX

2012-07-28 15:05:45

这篇文章,通过修改usbserial的驱动程序,使usbserial同时支持多个特定的vendor和product。

在使用LC6311或者SIM4100类似的通讯modem的时候,我们经常使用usbserial驱动来在linux环境下访问模块。但是,每次,我们插入特定模块到usb端口后,都需要手动加载usbserial模块,如:

  1. # load LC6311 module driver
  2. sudo modprobe usbserial vendor=0x1ab7 product=0x6000 
  3. # load SIM4100 module driver
  4. sudo modprobe usbserial vendor=0x0456 product=0x6532

并输入特定的vendor和product参数,十分麻烦。最近在实践的过程中,碰到了更麻烦的问题:基本的usbserial不能直接支持多个不 同参数的modem同时使用。比如,当使用上面的第一个命令加载了LC6311的模块以后,第二个命令将没有效果(因为,modprobe发现 usbserial已经加载,便放弃了第二次的加载)。下面是通过对usbserial驱动的一些修改,来实现静态支持模块SIM4100和 LC6311。

首先,我们需要自己运行的linux系统对应的内核代码。这里,我将不叙述对于和内核不同版本的模块,如何加载的问题。假设我们已经下载好了对应版本的源代码,并解压缩放到了对应目录下。我们首先设定内核代码的根目录为:

  1. export KERNEL_SOURCE_DIR=/usr/src/linux-source-2.6.31
1.修改$KERNEL_SOURCE_DIR/drivers/usb/serial/generic.c文件

这里主要是修改$KERNEL_SOURCE_DIR/drivers/usb/serial/generic.c文件中的usb_serial_generic_register()函数。
我们平时使用modprobe加载usbserial驱动时输入的vendor和product参数是传给usbserial_generic这个模块 的。这里的调用过程是usb_serial_init()->usb_serial_general_register()。在这个函数中,在这里 传入的参数:

  1. generic_device_ids[0].idVendor = vendor
  2. generic_device_ids[0].idProduct = product
  3. generic_device_ids[0].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; 

我们这里需要加入我们自己设备的vendor和product,因此在这行下面,我们需要加入:

  1. // added by xzpeter, try to support both sim4100 and lc6311 
  2. // for sim4100 
  3. generic_device_ids[1].idVendor = 0x0456
  4. generic_device_ids[1].idProduct = 0x6532
  5. generic_device_ids[1].match_flags = 
  6.     USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; 
  7. // for lc6311 
  8. generic_device_ids[2].idVendor = 0x1AB7
  9. generic_device_ids[2].idProduct = 0x6000
  10. generic_device_ids[2].match_flags = 
  11.     USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; 
  12. // end here 
2.编译模块

之后,回到内核的根目录,首先要按照原先的config配置编译内核,主要是为了得到Module.symvers文件(以及modpost等。如果直接编译模块,就算编译成功,也可能无法加载):

  1. make menuconfig 
  2. make 

这里,如何配置内核将不详细说明,主要是要保证配置要加入"device drivers"->"usb support"->"usb serial convertor support"中的对应项。

{注:如果之前已经编译过内核,可以直接编译模块。使用如下方式编译:}

  1. make -C $KERNEL_SOURCE_DIR M=drivers/usb/serial modules 

编译完成后,即可在对应目录下得到新的usbserial.ko驱动程序。

3.替换系统原有usbserial驱动

如果是在2.6.x内核中,则需要将这个文件复制到对应目录,并加载:

  1. cd /lib/modules/`uname -r`/kernel/drivers/usb/serial 
  2. # 备份原有驱动
  3. sudo mv usbserial.ko usbserial.ko.bak 
  4. # 放入新的驱动
  5. sudo cp $KERNEL_SOURCE_DIR/drivers/usb/serial/usbserial.ko ./
  6. sudo rmmod usbserial 
  7. # 加载新的驱动,这里就不用加vendor和product参数了,已经加入静态的id_table了
  8. sudo modprobe usbserial 

这样,以后在插入SIM4100或者LC6311模块的时候,就不用输入任何vendor和product参数了,这两个模块也可以同时使用了。可以用:

  1. ls /dev/ttyUSB* 

查看一下,是不是两个模块的设备文件都有了。


http://blog.csdn.net/zuosifengli/article/details/7275163

阅读(1040) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~