我有一个用于 Ubuntu 20.04.3 的 USB 设备。制造商提供了一个库和一个驱动程序。
我可以安装驱动程序并使设备正常工作,但每次内核更新时我都必须将驱动程序重新安装到新树中。我知道这是 dkms 的工作,我开始致力于解决这个问题,因为它看起来并不太困难,但退后一步,我想知道是否有一种更简单/更好的方法来让设备正常工作我认为他们的大部分用户群都是 Windows,所以没有太多的开发时间给予 Linux 方面的东西。不管怎样,我想更多地了解 linux 是如何做事的。
他们提供的驱动程序是经过稍微修改的 Exar 驱动程序。查看他们的版本和普通 Exar 驱动程序之间的差异,基本上他们所做的就是将供应商编号和产品 ID 号添加到代码中,以便他们的设备将被识别为与驱动程序兼容并运行适当的代码块(与当设备与其设备描述符匹配时,他们使用的特定 Exar 芯片。
基于这个非常有帮助的页面和互联网上的其他来源,我的理解是每个驱动程序都有一个 module.alias 文件,该文件本质上对其接受的设备类型有规则。然后,当设备插入时,系统从设备中提取信息,为该设备创建一个 modalias 文件。然后,将设备模式别名与 module.alias 文件中的规则相匹配的第一个、最具体的驱动程序是分配给设备的驱动程序。
因此,我想象我的设备有一个 Exar 芯片,并且如果驱动程序接受它并将其识别为本质上是 Exar 芯片,则可以使用 Exar 驱动程序使其工作。但由于制造商放置了自己的自定义设备描述符,modprobe 无法识别该设备与普通 Exar 驱动程序兼容。
有没有办法告诉系统该设备确实与普通 Exar 驱动程序兼容,或者有一个 Exar 设备隐藏在其中,而不是像他们那样复制驱动程序并稍微修改它以使系统尊重它。子设备?就 modprobe 而言,就像设备描述符的别名一样?
或者也许有一种方法可以为此设备编写不同的驱动程序,利用底层 exar 驱动程序并将所有内容传递给它,而不是复制代码?然后我就可以从芯片制造商那里获得更新的好处。
或者我应该继续使用 dkms,因为制造商的方式是最好的方式?
我看过有关如何使用 udev 规则将驱动程序绑定和取消绑定到设备的示例,但我认为如果驱动程序不匹配,它无论如何都不会被绑定?即使确实如此,那是“最好”的方式吗?
答案1
正如 @ReedGhost 在评论中如此有帮助的建议(谢谢!),这这正是我想做的。我找到了内置的 xr_serial 模块,并将我的设备供应商和产品 ID 回显到 newid 文件中。内置驱动程序将我的设备识别为兼容设备,并在我插入时加载。
然而,这并没有解决我的具体用例,因为内置的 exar 驱动程序是为具有不同产品 ID 的多个设备编写的。有一个 if-then-else 链指定要为每个特定产品 ID 运行的特定代码块。因此,某些功能仍然无法工作,因为我的设备 ID 导致它在应该运行其他部分之一时转到代码的 else 部分。
我现在意识到,我确实需要将设备的 id 欺骗或替换为所使用的特定芯片的 id,而不是仅仅添加一个新的以供驱动程序识别。
编辑:实际上,我可能会尝试为使用制造商提供的驱动程序的设备编写一个不同的驱动程序,因为这似乎是更正确的方法来做到这一点并获得更新的好处。这个问题和 这个问题对于任何发现此问题并遇到同样问题的人来说,这似乎是一个很好的起点。在此期间,我使用了dkms只需更新驱动程序即可。