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

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

我正在尝试解决一个问题: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
...

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

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

答案1

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

此处,xhci_hcd和均xhci_pci配置为可用作模块。如果这些行改为显示...=y,则 USB 3 支持将被编译到主内核中。

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

您可以在以下位置查找 PCI ID:PCI ID 存储库

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

alias pci:v0000<vendor ID>:d0000<product ID>sv... <module name>

该信息来自/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*

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

modprobe pci:v00001022d000043b9sv1b21sd1142bc0Csc03i30

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

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

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

答案2

如果该模块未内置到内核中(在 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

我们可以在该文件中看到“v”endor ID和“d”设备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)

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

 v     (vendor)
 d     (device)
 sv    (subvendor)
 sd    (subdevice)
 bc    (bus class)
 sc    (bus subclass)
 i     (interface)

相关内容