如何找到给定设备的内核模块?

les*_*nik 5 usb kernel-modules

我正在尝试解决一个问题:USB 鼠标在新安装的 linux 上不起作用。

我怀疑问题在于我的 USB 硬件没有合适的内核模块/驱动程序。的确:

$ lspci -knn
...
01:00.0 USB controller [0c03]: Advanced Micro Devices, Inc. [AMD] Device [1022:43b9] (rev 02)
        Subsystem: ASMedia Technology Inc. Device [1b21:1142]
01:00.1 SATA controller [0106]: Advanced Micro Devices, Inc. [AMD] Device [1022:43b5] (rev 02)
        Subsystem: ASMedia Technology Inc. Device [1b21:1062]
        Kernel driver in use: ahci
...
Run Code Online (Sandbox Code Playgroud)

如您所见,没有为 USB 控制器设备报告内核驱动程序(我想应该以类似于为 SATA 控制器报告的驱动程序的方式报告)

因此,我需要使用适合我设备的模块重建内核。但是我怎样才能找出我应该构建什么模块呢?我有识别我的设备的信息:它是供应商 ID 和硬件 ID ([1b21:43b9])。给定这些信息,如何找出对应的内核模块名称?

tel*_*coM 11

PCI ID 1022:43b9 是 AMD X370 系列芯片组 USB 3.1 xHCI 控制器。PCI 子系统 ID 1b21:1142 表明它实际上可能是 ASMedia ASM1042A USB 3 控制器,可能集成到 AMD 芯片组中。

对于大多数 USB 3.x 控制器芯片,相应的驱动模块xhci_pci取决于 module xhci_hcd。这两个模块都是标准 Linux 内核的一部分,因此它们应该在所有现代 Linux 发行版中都可用。相应的内核配置选项是CONFIG_USB_XHCI_PCICONFIG_USB_XHCI_HCD

许多发行版都将内核配置文件包含为/boot/config-<kernel version number>. 所以,你可以运行这个命令:

$ grep XHCI /boot/config-$(uname -r)
CONFIG_USB_XHCI_HCD=m
CONFIG_USB_XHCI_PCI=m
# CONFIG_USB_XHCI_PLATFORM is not set
Run Code Online (Sandbox Code Playgroud)

在这里,xhci_hcdxhci_pci都配置为可用作模块。如果行...=y改为,USB 3 支持将被编译到主内核中。

PCI ID 1022:43b5,子系统 ID 1b21:1062 是一个 AHCI SATA(或 eSATA)控制器,它已经被 module 覆盖了ahci

您可以在PCI ID Repository 中查找PCI ID

如果驱动程序已由供应商/产品 ID 指定,您可以使用/sbin/modprobe -c | grep '<vendor ID>.*<product ID>'. 如果你返回这样的一行,你就找到了匹配项:

alias pci:v0000<vendor ID>:d0000<product ID>sv... <module name>
Run Code Online (Sandbox Code Playgroud)

这个信息来自/lib/modules/modules.alias[.bin],它是由depmod嵌入在内核模块本身(在源代码中用MODULE_DEVICE_TABLE宏定义)的设备支持信息的命令生成的。您还可以使用modinfo <module name> | grep alias查看特定模块声明的硬件支持。

但是,并非所有模块都由供应商/产品 ID 指定。一些驱动程序将涵盖一整 设备;例如,该xhci_pci模块声称支持 PCI 基类 0x0C、子类 0x03、接口 0x30...,它们分别映射到“串行总线控制器”、“USB 控制器”和“XHCI”。这表示为

alias:          pci:v*d*sv*sd*bc0Csc03i30*
Run Code Online (Sandbox Code Playgroud)

请注意,您通常不需要手动执行任何这些查找,除非您将某些模块列入黑名单或自动检测由于某种原因失败。例如,当 Linux 内核检测到原始发布者的 USB 3 控制器时,它会导致(相当于)执行以下命令:

modprobe pci:v00001022d000043b9sv1b21sd1142bc0Csc03i30
Run Code Online (Sandbox Code Playgroud)

其中包含可用于设备的所有硬件供应商/设备/类/子类/接口 ID。如果modprobe配置中记录的通配别名之一与此字符串匹配,则将自动加载相应的模块。

对于 USB 设备(实际上对于任何可自动探测的总线),有一个类似的模块别名系统和一个USB ID 存储库。

如果您的系统上没有编译适当的模块,最好的办法是使用 PCI ID 存储库来识别设备或其中使用的芯片。有时,存储库条目会标识将为其提供支持的 Linux 内核模块。如果该信息不存在,您可能需要使用设备/芯片模型进行谷歌搜索;这通常可以让您找到标准内核中尚未(尚未?)包含的任何替代/实验驱动程序模块。

  • 谢谢,你说得对。需要`xhci_hcd`模块。我刚刚发现它使用 live usb 和另一个版本的 linux。`lspci -k` 命令显示了模块名称。但这并不是解决类似问题的真正方法。问题仍然存在 - 给定硬件 ID 找出内核模块的一致方法是什么? (2认同)

Ste*_*ris 5

如果模块未内置到内核中(在 RedHat 7 和变体上,XHCI_HCD 不是作为模块加载的,而是基础映像的一部分),您可以查看modules.aliases内核的文件。

例如

% grep 1B21 /lib/modules/$(uname -r)/modules.alias
alias pci:v00001B21d00000612sv*sd*bc*sc*i* ahci
alias pci:v00001B21d00000611sv*sd*bc*sc*i* ahci
alias pci:v00001B21d00000602sv*sd*bc*sc*i* ahci
alias pci:v00001B21d00000601sv*sd*bc*sc*i* ahci
Run Code Online (Sandbox Code Playgroud)

我们可以在这个文件中看到“v”endor ID 和“d”evice ID 值,以及应该加载的相应模块(“ahci”)。

我们可以验证这个模块处理这些驱动程序:

% modinfo /usr/lib/modules/3.10.0-957.1.3.el7.x86_64/kernel/drivers/ata/ahci.ko.xz
filename:       /usr/lib/modules/3.10.0-957.1.3.el7.x86_64/kernel/drivers/ata/ahci.ko.xz
version:        3.0
license:        GPL
description:    AHCI SATA low-level driver
author:         Jeff Garzik
retpoline:      Y
rhelversion:    7.6
srcversion:     4BCC52C20C316AF69F3584A
....
alias:          pci:v00001B21d00000612sv*sd*bc*sc*i*
alias:          pci:v00001B21d00000611sv*sd*bc*sc*i*
alias:          pci:v00001B21d00000602sv*sd*bc*sc*i*
alias:          pci:v00001B21d00000601sv*sd*bc*sc*i*
...
depends:        libahci,libata
intree:         Y
vermagic:       3.10.0-957.1.3.el7.x86_64 SMP mod_unload modversions 
signer:         CentOS Linux kernel signing key
sig_key:        E7:CE:F3:61:3A:9B:8B:D0:12:FA:E7:49:82:72:15:9B:B1:87:9C:65
sig_hashalgo:   sha256
parm:           marvell_enable:Marvell SATA via AHCI (1 = enabled) (int)
Run Code Online (Sandbox Code Playgroud)

modules.alias文件中的值对应于:

 v     (vendor)
 d     (device)
 sv    (subvendor)
 sd    (subdevice)
 bc    (bus class)
 sc    (bus subclass)
 i     (interface)
Run Code Online (Sandbox Code Playgroud)