如何将USB驱动程序分配给设备


30

这个问题有两个方面:

首先,如何手动从USB设备上拆下驱动程序并连接其他驱动程序?例如,我有一个设备,在连接后会自动使用USB存储驱动程序。

usbview输出

Vendor Id: xxxx
Product Id: xxxx
...
    Number of Interfaces: 2
    Interface Number: 0
        Name: usb-storage
        Number of Endpoints: 2
        ...
    Interface Number: 1
        Name: (none)
        Number of Endpoints: 2
        ...

我不想使用usb-storage驱动程序,因此在我的应用程序中,我使用libusb库来分离usb-storage驱动程序,然后声明接口。然后,我可以与USB设备和主机Linux系统上运行的应用程序之间来回发送数据。

如何在应用程序外部手动分离驱动程序?


其次,如何自动分配驱动程序以附加在设备插件上?我目前有一个udev规则设置来自动设置设备权限:

SUBSYSTEM=="usb", ATTR{idVendor}=="xxxx", MODE="0666"

我可以使用udev规则将驱动程序分配给USB设备上的特定接口吗?例如,如果我希望在接口0而不是usb-storage上自动使用usbnet模块,是否可以在udev中使用?


1
如果问题的一部分是加载正确的模块,请参阅Angström上的网络摄像头
别再邪恶了

1
您是否需要USB存储模块?因为如果没有,您可以将其放入黑名单,并且根本不会加载。
Hanan N.

@Gilles,我可以成功加载LKM。我的问题是如何手动将其自动附加到设备上?
linsek 2011年

@Hanan,目前我没有使用usb-storage模块。我可能最终需要将其列入黑名单以自动附加正确的模块,但是首先我需要知道如何附加usbnet模块。
linsek 2011年

1
@njozwiak模块usbnet不会自动加载,因为它没有有关可以使用它的硬件的信息。尝试找到合适的驱动程序并使用,例如 modinfo kalmia。在各alias行中,您将看到供应商ID xxxx和产品ID yyyy usb:vxxxxpyyyy。或者,您可以编辑文件/lib/modules/kernel_version/modules.usbmap,并为您的硬件删除行,这对于您的硬件模块usb-storage或使用适当的网络驱动程序更改usbstorage。但是depmod -a这种变化将消失……
Jan Marek

Answers:


20

对于问题的第一部分,我已经找到并且没有找到比使用libusb更好的方法来分离USB驱动程序。

至于问题的第二部分,udev可以驱动程序加载做出反应,但不能强制将特定的驱动程序分配给设备。

Linux内核中的每个驱动程序都负责一个或多个设备。驱动程序本身会选择支持的设备。它以编程方式执行此操作,即通过检查设备的供应商和产品ID,或者如果不可用(例如,旧设备),则执行一些自动检测试探法和健全性检查。一旦驾驶员确信找到了支持的设备,它便会自动与其连接。简而言之,您通常不能强迫特定的驱动程序使用特定的设备。但是,有时设备驱动程序会慷慨地接受它,而设备却可以运行它不知道的东西。您的里程会有所不同!过去,我不得不手动将怪异的PCI设备/供应商ID添加到应该支持它们的驱动程序中,但取得了成功,但同时也出现了一些有趣的内核崩溃。

现在,对于模块,还有一个额外的步骤。的模块加载器是由内核检测到新的设备时唤醒。它传递了一个'modalias'字符串,该字符串标识设备并对于USB设备如下所示:

usb:v046DpC221d0170dc00dsc00dp00ic03isc00ip00

此字符串包含设备类别(usb)和特定于类别的信息(供应商/设备/序列号,设备类别等)。每个内核驱动程序包含一行,例如:

MODULE_ALIAS("usb:...")

必须与usbalias匹配(通配符用于匹配多个设备)。如果modalias匹配驱动程序支持的驱动程序,则会加载该驱动程序(或通知新设备,如果已经存在)。

您可以通过以下方式查看受支持的设备(按modalias)及其关联的模块

less /lib/modules/`uname -r`/modules.alias

如果您使用grep表示usb-storage设备驱动程序,则会看到该设备具有按供应商和设备ID支持的某些特定设备,并且还将尝试支持具有正确(存储)类的任何设备,无论供应商/设备如何。

您可以使用操作系统/etc/modprobe.d/上的用户空间机制(在Debian和好友上)来影响这一点。您可以将模块列入黑名单,也可以指定要由modalias加载的模块,就像modules.alias文件一样(并使用相同的语法)。depmod -a然后将重新生成模块加载器的模式。

但是,即使您可以将这匹特定的马带到水里,也不能让他喝水。如果驱动程序不支持您的设备,则应忽略它。

这是一般情况下的理论。

实际上,在使用USB的情况下,我看到您的设备似乎具有两个接口,其中一个存储接口。内核将附加到整个设备的存储接口。如果另一个接口具有正确的类,则usbnet驱动程序可以附加到该接口。是的,您可以将多个驱动程序连接到同一物理设备,因为USB设备导出多个接口(例如,我的Logitech G15键盘导出两个接口,因为它具有键盘设备和LCD屏幕,每个都由单独的驱动程序处理) 。

未检测到USB设备的第二个接口这一事实表明内核中缺少支持。无论如何,您都可以使用来列出设备接口/端点的详细信息lsusb -v | less,然后向下滚动到您的特定设备(如果愿意,可以按device:vendor ID或USB path限制输出)。

请注意:关于USB设备的逻辑结构,我在这里简化了一点。责怪USB联盟。:)


4
static struct usb_device_id id_table [] = { { USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, { }, }; MODULE_DEVICE_TABLE (usb, id_table);代码中已经有,modalias是否多余?
托马斯

在我的情况下,这些行是由驱动程序内任何地方的一些Makefile魔术自动生成的。这就是为什么我为MODULE_ALIAS添加了三倍的行,但从未列出。无论如何,感谢lsusb -v。这样我就可以检查它并找到我想法中的缺陷。然后,我将已知标识符的来源grep起来,并找到包含必须操纵的条目的数组。
JackGrinningCat
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.