内核模块
内核模块是可以在需要时加载和卸载到内核中的代码块。它们在无需重启系统的情况下扩展了内核的功能。
要创建内核模块,您可以阅读《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
要列出已加载模块的已设置选项,请使用来自sysfsutils包的systool(1)
$ 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,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中添加相应的.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.conf的FILES数组中,一旦您将模块列入黑名单,就重新生成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。参见
- 禁用PC扬声器蜂鸣声
- 编写WMI驱动程序 - LWM入门