如何为设备分配 USB 驱动程序

如何为设备分配 USB 驱动程序

这个问题有两个方面:

首先,如何手动从 USB 设备分离驱动程序并连接另一个驱动程序?例如,我有一个设备,在连接时会自动使用 USB 存储驱动程序。

USB视图输出

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 存储驱动程序,因此在我的应用程序中,我使用该libusb库来分离 USB 存储驱动程序,然后声明该接口。然后,我可以向 USB 设备和主机 Linux 系统上运行的应用程序发送数据。

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


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

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

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

答案1

对于问题的第一部分,我已经查看过,但找不到比您已经使用 libusb 所做的更好的方法来分离 USB 驱动程序。

至于问题的第二部分,udev 可以反应驱动程序加载,但不是力量要分配给设备的特定驱动程序。

Linux 内核中的每个驱动程序负责一个或多个设备。驱动程序本身选择它支持的设备。它以编程方式执行此操作,即通过检查设备的供应商和产品 ID,或者,如果这些不可用(例如旧设备),则执行一些自动检测启发式和健全性检查。一旦驱动程序确信它找到了它支持的设备,它就会将自己附加到该设备上。简而言之,您通常无法强制特定驱动程序使用特定设备。然而,有时,设备驱动程序会慷慨地接受它所接受的内容,并且设备它不知道的工作。您的里程将会有所不同!过去,我必须手动将奇怪的 PCI 设备/供应商 ID 添加到应该支持它们的驱动程序中,结果有好有坏,也有一些有趣的内核崩溃。

现在,对于模块来说,还有一个额外的步骤。这模块加载器当检测到新设备时被内核唤醒。它传递了一个“modalias”字符串,该字符串标识设备,对于 USB 设备来说类似于以下内容:

usb:v046DpC221d0170dc00dsc00dp00ic03isc00ip00

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

MODULE_ALIAS("usb:...")

其中必须与 usbalias 匹配(通配符用于匹配多个设备)。如果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,然后向下滚动到您的特定设备(如果您愿意,您可以通过设备:供应商 ID 或 USB 路径来限制输出)。

请注意:我在这里对 USB 设备的逻辑结构过于简单化了。归咎于USB联盟。 :)

相关内容