内核模块

来自 Arch Linux 中文维基
(重定向自Kernel modules

内核模块是可以按需加载或卸载的内核代码,可以不重启系统就扩充内核的功能。

要创建内核模块,请阅读此指南。模块可以设置成内置或者可加载,要动态加载或删除模块,必须在内核配置中将其配置为可加载模块(因此与模块相关的行将显示字母 M)。

如果您想在新内核安装后自动重建模块,参见 Dynamic Kernel Module Support(DKMS)。

获取信息[编辑 | 编辑源代码]

模块保存在 /lib/modules/kernel_release (使用 uname -r 命令显示当前内核版本)。

注意: 模块名通常使用 (_) 或 - 连接,但是这些符号在 modprobe 命令和 /etc/modprobe.d/ 配置文件中都是可以相互替换的。

显示当前装入的内核模块:

$ lsmod

显示模块信息:

$ modinfo module_name

显示所有模块的配置信息:

$ modprobe -c | less

显示某个模块的配置信息:

$ modprobe -c | grep module_name

显示一个装入模块使用的选项,可以使用sysfsutils中的systool(1)

$ systool -v -m module_name

显示模块的依赖关系:

$ modprobe --show-depends module_name

自动加载模块[编辑 | 编辑源代码]

目前,所有必要模块的加载均由 udev 自动完成。所以,如果不需要使用任何额外的模块,就没有必要在任何配置文件中添加启动时加载的模块。但是,有些情况下可能需要在系统启动时加载某个额外的模块,或者将某个模块列入黑名单以便使系统正常运行。

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)

早期模块加载[编辑 | 编辑源代码]

initramfs 映像可能不包含 /etc/modules-load.d/ 中要求的内核模块,它也可能缺少在该文件夹中设置的文件。早期模块加载取决于使用的 initramfs 生成器:

手动加载模块[编辑 | 编辑源代码]

内核模块由 kmod 包提供的工具处理。您可以手动使用这些工具。

注意: 如果你已经升级了你的内核但还没有重新启动,modprobe 将失败并且没有错误消息并以代码 1 退出,因为路径 /usr/lib/modules/$(uname -r)/ 不再存在。当 modprobe 无法确定是否存在这种情况时,请手动检查此路径是否存在。

要手动装入模块的话,执行:

# modprobe module_name

按文件名加载模块:

# insmod filename [args]

如果要移除一个模块:

# modprobe -r module_name

或者:

# rmmod module_name

配置模块参数[编辑 | 编辑源代码]

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

手动加载时设置[编辑 | 编辑源代码]

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

# modprobe module_name parameter_name=parameter_value

使用 /etc/modprobe.d/中的文件[编辑 | 编辑源代码]

/etc/modprobe.d/ 目录中的文件可用于将模块设置传递给 udev,它将使用 modprobe 管理系统启动期间的模块加载.此目录中的配置文件可以具有任何名称,只要它们以 .conf 扩展名结尾。语法是:

/etc/modprobe.d/myfilename.conf
options module_name parameter_name=parameter_value

多个模块参数用空格分隔,而一个参数可以接收一个值列表,列表用逗号分隔:

/etc/modprobe.d/myfilename.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 加载的,那么您需要将适当的 .conf 文件添加到 mkinitcpio.conf 中的 FILES 或使用modconf hook,然后 重新生成 initramfs 以包含“.conf”文件。要查看默认 initramfs 的内容,请使用 lsinitcpio

使用内核命令行[编辑 | 编辑源代码]

还可以使用内核命令行向模块传递选项。这也是向内核内置模块传递选项的唯一途径。对于所有常见的引导加载程序,以下语法是正确的:

modname.parametername=parametercontents

例如:

thinkpad_acpi.fan_control=1

只需将其添加到引导加载程序的内核行,如内核参数中所述。

别名[编辑 | 编辑源代码]

别名是模块的替代名称。例如:alias my-mod real_long_modulename 表示您可以使用 modprobe my-mod 代替 modprobe real_long_modulename。您也可以使用 shell 风格的通配符,所以 alias my-mod* really_long_modulename 意味着 modprobe my-modmodprobe my-mod-something 有相同的效果。创建别名:

/etc/modprobe.d/myalias.conf
alias mymod really_long_module_name

一些模块具有别名,用于在应用程序需要它们时自动加载它们。禁用这些别名可以防止自动加载,但仍允许手动加载模块。

/etc/modprobe.d/modprobe.conf
# Prevent Bluetooth autoload
alias net-pf-31 off

黑名单[编辑 | 编辑源代码]

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

一些模块作为 initramfs 的一部分加载。 mkinitcpio -M 将打印出所有自动检测到的模块:为了防止 initramfs 加载其中一些模块,请将它们列入黑名单中的 /etc/modprobe.d 下的 .conf 文件 并且它应该在图像生成期间由 modconf 挂钩添加。运行 mkinitcpio -v 将列出由各种挂钩(例如 filesystems 挂钩、block 挂钩等)拉入的所有模块。如果您的文件中没有 modconf 挂钩,请记住将该 .conf 文件添加到 /etc/mkinitcpio.conf 中的 FILES 列表中HOOKS 列表(比如您改变了默认配置),将模块列入黑名单 regenerate the initramfs,然后重新启动。

使用 /etc/modprobe.d/ 中的文件[编辑 | 编辑源代码]

/etc/modprobe.d/ 中创建一个 .conf 文件,并使用 blacklist 关键字为要列入黑名单的每个模块附加一行。例如,如果您想阻止 pcspkr 模块加载以避免通过 PC 扬声器发出声音:

/etc/modprobe.d/nobeep.conf
# Do not load the 'pcspkr' module on boot.
blacklist pcspkr
注意: blacklist 命令将一个模块列入黑名单,这样它就不会自动加载,但如果另一个未列入黑名单的模块依赖于它或者它是手动加载的,则该模块可能会被加载。

但是,对于该情况有一个解决方法; install 命令指示 modprobe 运行自定义命令,而不是像往常一样将模块插入内核,因此您可以强制使模块加载失败:

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

这将有效地将该模块和任何其他依赖于它的模块列入黑名单。

使用内核命令行[编辑 | 编辑源代码]

提示:如果模块损坏导致无法引导系统,这将非常有用。

您也可以从引导加载程序中将模块列入黑名单。

Kernel参数.中所述,只需将module_blacklist=modname1,modname2,modname3 添加到引导加载程序的内核行中即可。

注意:
  • 将多个模块列入黑名单时,请注意,它们之间仅用逗号分隔。 空格或其他内容可能会破坏语法。
  • module_blacklist 会让内核完全拒绝加载模块。如果只想阻止隐式加载,可能会在稍后手动加载模块,那么正确的参数是 modprobe.blacklist=modname1,modname2,modname3。这并不能阻止启动过程中的显式加载,例如通过 systemd 或其他模块。

问题处理[编辑 | 编辑源代码]

模块未加载[编辑 | 编辑源代码]

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

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

警告: 忽略内核模块的版本检查可能会导致内核崩溃或系统由于不兼容而表现出未定义的错误。请谨慎使用 --force-vermagic

参见[编辑 | 编辑源代码]