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