内核模块
内核模块 是可以按需加载和卸载到内核中的代码片段。它们扩展了内核的功能,而无需重启系统。
要创建内核模块,您可以阅读 Linux 内核模块编程指南。模块可以配置为内置或可加载。要动态加载或移除模块,它必须在内核配置中配置为可加载模块(因此,与模块相关的行将显示字母 M
)。
要在安装新内核时自动重建内核模块,请参阅 动态内核模块支持 (DKMS)。
获取信息
通常,模块依赖于内核版本,并存储在 /usr/lib/modules/kernel_release/
目录中。
uname -r
(或 uname --kernel-release
)以获取您当前的内核版本。_
) 或破折号 (-
);但是,当使用 modprobe 命令和 /etc/modprobe.d/
中的配置文件时,这些符号可以互换(会自动转换为下划线,请参阅 modprobe(8) § DESCRIPTION 和 modprobe.d(5) § DESCRIPTION)。显示当前加载的内核模块
$ lsmod
显示有关模块的信息
$ modinfo module_name
要列出为已加载模块设置的选项,请使用 systool(1),它来自 sysfsutils
$ systool -v -m module_name
显示所有模块的完整配置
$ modprobe -c | less
显示特定模块的配置
$ modprobe -c | grep module_name
列出模块(或别名)的依赖项,包括模块本身
$ modprobe --show-depends module_name
自动模块加载
如今,所有必要的模块加载都由 udev 自动处理,因此,如果您不需要使用任何树外内核模块,则无需将应在启动时加载的模块放在任何配置文件中。但是,在某些情况下,您可能希望在启动过程中加载额外的模块,或者将另一个模块列入黑名单,以使您的计算机正常运行。
早期模块加载
早期模块加载取决于所使用的 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
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,后者将使用 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
FILES
中,或使用 modconf
hook,然后 重新生成 initramfs 以包含 .conf 文件。要查看默认 initramfs 的内容,请使用 lsinitcpio。使用内核命令行
您还可以使用内核命令行将选项传递给模块。这是内置于内核的模块唯一可行的选项。对于所有常见的 引导加载程序,以下语法是正确的
module_name.parameter_name=parameter_value
例如
thinkpad_acpi.fan_control=1
只需将其添加到引导加载程序配置文件中的相应行,如 内核参数#引导加载程序配置 中所述。
别名
别名是模块的备用名称。例如: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.conf
中的 FILES
数组,并且一旦您将模块列入黑名单,请 重新生成 initramfs,然后在之后重启。
使用 modprobe.d
alias
通过覆盖禁用 别名。例如,要防止蓝牙模块自动加载,使用名为 off
的模块(不存在)。
/etc/modprobe.d/modprobe.conf
alias net-pf-31 off
blacklist
要禁用给定模块的所有内部别名,请使用 blacklist
关键字。例如,要防止 pcspkr
模块在启动时加载,以避免通过 PC 扬声器 发出声音
/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
添加到您的内核命令行,如 内核参数#引导加载程序配置 中所述。
- 当您将多个模块列入黑名单时,请注意它们仅由逗号分隔。空格或任何其他内容可能会破坏语法。
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
。参见
- 禁用 PC 扬声器蜂鸣声
- 编写 WMI 驱动程序 - LWM 简介