lin*_*sek 34 drivers kernel usb udev kernel-modules
这个问题有两个方面:
首先,您如何手动从 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
...
Run Code Online (Sandbox Code Playgroud)
我不想使用 USB 存储驱动程序,因此在我的应用程序中,我使用该libusb库来分离 USB 存储驱动程序,然后声明该接口。然后,我可以在我的 USB 设备和我的主机 Linux 系统上运行的应用程序之间发送数据。
如何在应用程序之外手动分离驱动程序?
其次,如何自动分配驱动程序以附加到设备插件上?我目前有一个 udev 规则设置来自动设置设备权限:
SUBSYSTEM=="usb", ATTR{idVendor}=="xxxx", MODE="0666"
Run Code Online (Sandbox Code Playgroud)
我可以使用 udev 规则为 USB 设备上的特定接口分配驱动程序吗?例如,如果我希望在接口 0 上自动使用 usbnet 模块而不是 usb-storage,这在 udev 中可能吗?
Ale*_*ios 21
对于问题的第一部分,我已经查看并找不到比您已经使用 libusb 更好的分离 USB 驱动程序的方法。
至于问题的第二部分,udev 可以对驱动程序加载做出反应,但不会强制将特定驱动程序分配给设备。
Linux 内核中的每个驱动程序都负责一个或多个设备。驱动程序本身选择它支持的设备。它以编程方式执行此操作,即通过检查设备的供应商和产品 ID,或者,如果这些不可用(例如旧设备),则执行一些自动检测启发式和健全性检查。一旦驱动程序确信它找到了它支持的设备,它就会将自己连接到它。简而言之,您通常无法强制特定驱动程序使用特定设备。然而,有时设备驱动程序对它所接受的东西很慷慨,而设备可以在它不知道的情况下工作。你的里程会有所不同!过去,我不得不手动将奇怪的 PCI 设备/供应商 ID 添加到应该支持它们的驱动程序中,结果喜忧参半,并且发生了一些有趣的内核崩溃。
现在,对于模块,还有一个额外的步骤。的模块加载器是由内核检测到新的设备时唤醒。它传递了一个“modalias”字符串,它标识设备,对于 USB 设备看起来像这样:
usb:v046DpC221d0170dc00dsc00dp00ic03isc00ip00
Run Code Online (Sandbox Code Playgroud)
此字符串包含设备类 ( usb) 和特定于类的信息(供应商/设备/序列号、设备类等)。每个内核驱动程序都包含一行,例如:
MODULE_ALIAS("usb:...")
Run Code Online (Sandbox Code Playgroud)
其中必须匹配usbalias(通配符用于匹配多个设备)。如果modalias与驱动程序支持的匹配,则加载此驱动程序(或通知新设备,如果它已经存在)。
您可以使用以下命令查看支持的设备(通过 modalias)及其相关模块
less /lib/modules/`uname -r`/modules.alias
Run Code Online (Sandbox Code Playgroud)
如果您搜索 usb 存储设备驱动程序,您会看到它有一些由供应商和设备 ID 支持的特定设备,并且还将尝试支持具有正确(存储)类的任何设备,无论供应商/设备如何.
您可以使用操作系统/etc/modprobe.d/上的用户空间机制来影响这一点(在 Debian 和朋友上)。您可以将模块列入黑名单,也可以指定要由 modalias 加载的模块,就像modules.alias文件一样(并使用相同的语法)。depmod -a然后将重新生成模块加载器的模式。
然而,即使你可以把这匹马带到水里,但你不能让他喝水。如果驱动程序不支持您的设备,则应忽略它。
这是一般情况下的理论。
在实践中,在 USB 的情况下,我看到您的设备似乎有两个接口,其中存储是一个。内核将附加到整个设备的存储接口。如果另一个接口具有正确的类,usbnet驱动程序可以附加到它。是的,您可以将多个驱动程序附加到同一个物理设备上,因为一个 USB 设备导出多个接口(例如我的罗技 G15 键盘导出两个,因为它有一个键盘设备和一个 LCD 屏幕,每个都由一个单独的驱动程序处理) .
未检测到 USB 设备的第二个接口的事实表明内核缺乏支持。无论如何,您都可以使用 列出设备接口/端点的详细信息lsusb -v | less,然后向下滚动到您的特定设备(如果您愿意,可以通过设备:供应商 ID 或 USB 路径限制输出)。
请注意:关于 USB 设备的逻辑结构,我在这里过于简化了一点。归咎于 USB 联盟。:)