Kernel module (简体中文) - ArchWiki

Jump to content

# Kernel module (简体中文)

From ArchWiki

相关文章

- Boot Debugging
- Kernels (简体中文)
- Kernel parameters (简体中文)

翻译状态：本文是 Kernel_modules 的翻译。上次翻译日期：2018-05-09。如果英文版本有所更改，则您可以帮助同步翻译。

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

要创建内核模块，请阅读此指南。模块可以设置成内置或者动态加载，要编译成可动态加载，需要在内核配置时将模块配置为 `M` (模块)。

## 获取信息

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

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

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

    $ lsmod

显示模块信息：

    $ modinfo module_name

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

    $ modprobe -c | less

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

    $ modprobe -c | grep module_name

显示一个装入模块使用的选项：

    $ systool -v -m module_name

显示模块的依赖关系：

    $ modprobe --show-depends module_name

## 使用systemd自动加载模块

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

内核模块可以在`/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

按文件名加载模块:

    # insmod filename [args]

注意： 如果升级了内核但是没有重启，路径 `/usr/lib/modules/$(uname -r)/` 已经不存在。modprobe 会返回错误 1，没有额外的错误信息。如果出现 modprobe 加载失败，请检查模块路径以确认是否是这个问题导致。

如果要移除一个模块：

    # modprobe -r module_name

或者:

    # rmmod module_name

## 配置模块参数

### 手动加载时设置

传递参数的基本方式是使用 modprobe 选项，格式是 `key=value`：

    # modprobe module_name parameter_name=parameter_value

### 使用 /etc/modprobe.d/中的文件

要通过配置文件传递参数，在 `/etc/modprobe.d/` 中放入任意名称 `.conf` 文件，加入:

    /etc/modprobe.d/myfilename.conf

    options modname parametername=parametercontents

例如

    /etc/modprobe.d/thinkfan.conf

    # On thinkpads, this lets the thinkfan daemon control fan speed
    options thinkpad_acpi fan_control=1

注意： 如果要在启动时就修改内核参数(从 init ramdisk 开始)，需要将相应的`.conf`-文件加入 mkinitcpio.conf 的 FILES 参数中。

### 使用内核命令行

如果模块直接编译进内核，也可以通过启动管理器(GRUB, LILO 或 Syslinux)的内核行加入参数：

    modname.parametername=parametercontents

例如:

    thinkpad_acpi.fan_control=1

## 别名

    /etc/modprobe.d/myalias.conf

    # Lets you use 'mymod' in MODULES, instead of 'really_long_module_name'
    alias mymod really_long_module_name

有些模块具有别名，以方便其它程序自动装入模块。禁用这些别名可以阻止自动装入，但是仍然可以手动装入。

    /etc/modprobe.d/modprobe.conf

    # Prevent autoload of bluetooth
    alias net-pf-31 off

    # Prevent autoload of ipv6
    alias net-pf-10 off

## 黑名单

### 禁用内核模块

对内核模块来说，黑名单是指禁止某个模块装入的机制。当对应的硬件不存在或者装入某个模块会导致问题时很有用。

有些模块作为 initramfs 的一部分装入。

`mkinitcpio -M` 会显示所有自动检测到到模块：要阻止 initramfs 装入某些模块，可以在 `/etc/modprobe.d`中将它们加入黑名单。并应在映像生成过程中通过`modconf`挂钩将其添加。

运行 `mkinitcpio -v` 会显示各种钩子(例如 filesystem 钩子, SCSI 钩子等)装入的模块。如果您的`HOOKS` 数组中没有 `modconf` 钩子（例如，和默认配置不同）则请将该".conf"文件添加到`/etc/mkinitcpio.conf`中的FILES数组中。一旦您将其列入黑名单，请重新生成 initramfs，然后重新启动。

### 使用 /etc/modprobe.d/ 中的文件

在 `/etc/modprobe.d/` 中创建 `.conf` 文件，使用 `blacklist` 关键字屏蔽不需要的模块，例如如果不想装入 `pcspkr` 模块：

    /etc/modprobe.d/nobeep.conf

    # Do not load the pcspkr module on boot
    blacklist pcspkr

注意： `blacklist` 命令将屏蔽一个模板，所以不会自动装入，但是如果其它非屏蔽模块需要这个模块，系统依然会装入它。

要避免这个行为，可以让 modprobe 使用自定义的 `install` 命令，而不是像往常一样将模块插入内核，因此您可以通过以下方式强制模块始终无法加载：

    /etc/modprobe.d/blacklist.conf

    ...
    install MODULE /bin/true
    ...

这样就可以 "屏蔽" 模块及所有依赖它的模块。

### 使用内核命令行

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

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

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

注意： 将多个模块列入黑名单时，请注意，它们之间仅用逗号分隔。 空格或其他内容可能会破坏语法。

## 问题处理

### 模块未加载

如果出现模块在启动时未加载，而且启动日志中(`journalctl -b`) 显示模块被屏蔽，但是 `/etc/modprobe.d/` 中未找到屏蔽设置，请检查 `/usr/lib/modprobe.d/` 目录。

"vermagic" 字符串与内核不一致的模块不会被加载，如果确认模块与当前内核兼容，可以用 `modprobe --force-vermagic` 参数加载，跳过检查。

警告： 忽略模块检查，可能因为不兼容导致系统崩溃或不可预知行为，请谨慎使用 `--force-vermagic`。

## 参见

- modprobe.d(5)
- 禁用 IPv6
- 禁用 PC喇叭

Categories:

- Kernel (简体中文)
- Hardware detection and troubleshooting (简体中文)