跳转至内容

内核模块

来自 ArchWiki
(从Modinfo重定向而来)

内核模块是可以在需要时加载和卸载到内核中的代码块。它们在无需重启系统的情况下扩展了内核的功能。

要创建内核模块,您可以阅读《Linux内核模块编程指南》。模块可以被配置为内置或可加载。要动态加载或移除模块,它必须在内核配置中被配置为可加载模块(与模块相关的行将显示字母M)。

要在安装新内核时自动重新构建内核模块,请参阅动态内核模块支持(DKMS)。

获取信息

通常模块依赖于内核版本,并存储在/usr/lib/modules/kernel_release/目录下。

提示 运行uname -r(或uname --kernel-release)来获取您当前的内核版本。
注意 模块名和别名名通常使用下划线(_)或短横线(-);然而,在使用modprobe命令和/etc/modprobe.d/下的配置文件时,这些符号是可互换的(会自动转换为下划线,请参阅modprobe(8) § DESCRIPTIONmodprobe.d(5) § DESCRIPTION)。

显示当前已加载的内核模块

$ lsmod

显示关于某个模块的信息

$ modinfo module_name

要列出已加载模块的已设置选项,请使用来自sysfsutils包的systool(1)

$ systool -v -m module_name

显示所有模块的详细配置

$ modprobe -c | less

显示特定模块的配置

$ modprobe -c | grep module_name

列出模块(或别名)的依赖关系,包括模块本身

$ modprobe --show-depends module_name

自动加载模块

如今,所有必要的模块加载都由udev自动处理,所以如果您不需要使用任何非官方内核模块,则无需将需要在启动时加载的模块放入任何配置文件中。但是,在某些情况下,您可能希望在启动过程中加载一个额外的模块,或者将另一个模块列入黑名单,以使您的计算机正常工作。

早期模块加载

早期模块加载取决于所使用的initramfs生成器。

注意 initramfs镜像可能不包含/etc/modules-load.d/中请求的内核模块,也可能缺少该文件夹中设置的文件(参见#systemd)。

systemd

内核模块可以显式列在/etc/modules-load.d/下的文件中,供systemd在启动时加载它们。每个配置文件都以/etc/modules-load.d/program.conf的格式命名。配置文件只需包含要加载的内核模块名称列表,用换行符分隔。空行和第一非空白字符为#;的行将被忽略。

/etc/modules-load.d/virtio-net.conf
# Load virtio_net.ko at boot
virtio_net

有关更多详细信息,请参阅modules-load.d(5)

手动处理模块

内核模块由kmod包提供的工具处理,该包作为内核包的依赖项安装。您可以手动使用这些工具。要加载一个模块

# modprobe module_name
注意 如果您升级了内核但尚未重启,modprobe将无错误消息地失败并以退出码1退出,因为/usr/lib/modules/kernel_release/路径已不存在。当modprobe失败时,请手动检查此路径是否存在,以确定是否是这种情况。

要通过文件名加载模块—即那些未安装在/usr/lib/modules/kernel_release/目录中的模块—请使用以下任一命令:

# insmod file_name module_options
# modprobe file_name

要卸载—移除—一个模块,请使用以下任一命令:

# rmmod module_name
# modprobe -r module_name
# modprobe --remove module_name

设置模块选项

要向内核模块传递参数,您可以手动使用modprobe传递,或者通过modprobe配置文件或使用内核命令行来确保某些参数始终被应用。如果模块已内置到内核中,则必须使用内核命令行,其他方法将不起作用。

使用 modprobe

传递参数给模块的基本方法是使用modprobe命令。参数在命令行上使用简单的key=value赋值指定

# modprobe module_name parameter_name=parameter_value

使用 modprobe.d

/etc/modprobe.d/目录下的配置文件可用于将模块设置传递给udev,udev将使用modprobe在系统启动时管理模块的加载。该目录下的文件可以有任何名称,只要它们以.conf扩展名结尾。文件名很重要,请参阅modprobe.d(5) § CONFIGURATION DIRECTORIES AND PRECEDENCE。要显示有效配置

$ systemd-analyze cat-config modprobe.d

语法是

/etc/modprobe.d/file_name.conf
options module_name parameter_name=parameter_value
注意 给定模块的所有选项必须定义在同一行上。具有相同模块名称的新options行将替换之前的行。

多个模块参数由空格分隔,反过来,一个参数可以接收一个由逗号分隔的值列表

/etc/modprobe.d/file_name.conf
options module_name param1=value1 param2=value2a,value2b …

例如:

/etc/modprobe.d/thinkfan.conf
# On ThinkPads, this lets the 'thinkfan' daemon control fan speed
options thinkpad_acpi fan_control=1
注意 如果受影响的模块是从initramfs加载的,那么您需要在mkinitcpio.confFILES中添加相应的.conf文件,或者使用modconf hook,然后重新生成initramfs以包含.conf文件。要查看默认initramfs的内容,请使用lsinitcpio

使用内核命令行

您也可以通过内核命令行向模块传递选项。这是内置到内核中的模块唯一有效的方法。对于所有常见的引导加载程序,以下语法是正确的:

module_name.parameter_name=parameter_value

例如:

thinkpad_acpi.fan_control=1

只需将其添加到引导加载程序配置的相应行中,如Kernel parameters#Boot loader configuration中所述。

别名

别名是模块的替代名称。例如:alias my-mod really_long_modulename意味着您可以使用modprobe my-mod而不是modprobe really_long_modulename。您还可以使用shell风格的通配符,因此alias my-mod* really_long_modulename意味着modprobe my-mod-something具有相同的效果。创建别名:

/etc/modprobe.d/myalias.conf
alias my-mod really_long_module_name

别名可以是内部的—包含在模块本身中。内部别名通常用于#自动加载模块,当应用程序需要它时,例如内核检测到新设备时。要查看模块的内部别名:

$ modinfo --field=alias module_name

查看已配置和内部别名:

$ modprobe --showconfig | grep '\<module_name$'

黑名单

在内核模块的上下文中,黑名单是一种阻止内核模块加载的机制。这可能很有用,例如,如果不需要相关硬件,或者加载该模块会导致问题:例如,可能有两个内核模块试图控制同一硬件,而同时加载它们会导致冲突。

提示 不要将黑名单作为一个通用术语与使用blacklist关键字作为特定情况的黑名单混淆。

有些模块是作为initramfs的一部分加载的。mkinitcpio -M将打印出所有自动检测到的模块:要阻止initramfs加载其中一些模块,请将它们在/etc/modprobe.d下的.conf文件中列入黑名单,它将在生成镜像时由modconf hook添加。运行mkinitcpio -v将列出由各种hook(例如filesystems hook、block hook等)拉入的所有模块。如果您在HOOKS数组中没有modconf hook(例如,您偏离了默认配置),请记住将该.conf文件添加到/etc/mkinitcpio.confFILES数组中,一旦您将模块列入黑名单,就重新生成initramfs,然后重启。

使用 modprobe.d

alias

通过覆盖禁用别名。例如,要阻止蓝牙模块自动加载(假设名为off的模块不存在):

/etc/modprobe.d/modprobe.conf
alias net-pf-31 off
注意 别名覆盖可以阻止自动加载模块,但仍然允许模块通过另一个别名或模块名称被加载—无论是自动加载还是手动加载。

blacklist

要禁用给定模块的所有内部别名,请使用blacklist关键字。例如,要阻止pcspkr模块在启动时加载,以避免通过PC speaker发出声音:

/etc/modprobe.d/nobeep.conf
blacklist pcspkr
注意 blacklist配置命令—因为它处理别名—具有与alias命令相同的缺点:可以阻止自动加载,但模块仍可能被手动加载,或者如果另一个模块依赖它而被自动加载。

install

对于#alias#blacklist注释中描述的行为,存在一种解决方法。install配置命令指示modprobe运行一个自定义命令,而不是像平常一样将模块插入内核,所以您可以使用以下方式模拟模块成功加载:

/etc/modprobe.d/blacklist.conf
install module_name /bin/true

您可以使用/bin/false强制模块始终加载失败:这将有效地阻止该模块—以及任何依赖于它的模块—被加载,并可能产生日志错误消息。

使用内核命令行

提示 如果一个损坏的模块导致系统无法启动,这可能会非常有用。

您也可以从引导加载程序的引导条目配置中黑名单模块。

只需将module_blacklist=module_name_1,module_name_2,module_name_3添加到您的内核命令行中,如Kernel parameters#Boot loader configuration所述。

  • 当您黑名单多个模块时,请注意它们仅用逗号分隔。空格或其他字符可能会破坏语法。
  • module_blacklist将使内核完全拒绝加载该模块。
  • 如果您只想阻止隐式加载,但以后可能手动加载该模块,则正确的参数是modprobe.blacklist=module_name_1,module_name_2,module_name_3。但这不会阻止启动期间的显式加载,例如由systemd或其他模块进行加载。

命令行选项的另一个用例是禁用模块中特定于硬件的组件,而不禁用整个模块。例如,禁用麦克风但保留其他声音输出选项。有关一些示例,请参阅BBS#303475

故障排除

模块未加载

如果特定模块未加载,并且引导日志(可通过以root身份运行journalctl -b访问)显示该模块已被列入黑名单,但/etc/modprobe.d/目录中没有相应的条目,请检查/usr/lib/modprobe.d/下的另一个modprobe源目录是否有黑名单条目。

如果内核模块中包含的“vermagic”字符串与当前运行的内核的值不匹配,则该模块将不会被加载。如果已知该模块与当前运行的内核兼容,则可以使用modprobe --force-vermagic忽略“vermagic”检查。

警告 忽略内核模块的版本检查可能导致内核崩溃或系统出现因不兼容而导致的未定义行为。请务必谨慎使用--force-vermagic

参见