Difference between revisions of "Kernel modules (简体中文)"

From ArchWiki
Jump to: navigation, search
(simplification and beautification of wikilinks, fixing whitespace, capitalization and section fragments (https://github.com/lahwaacz/wiki-scripts/blob/master/link-checker.py (interactive)))
 
(18 intermediate revisions by 5 users not shown)
Line 1: Line 1:
[[Category:简体中文]]
 
 
[[Category:Kernel (简体中文)]]
 
[[Category:Kernel (简体中文)]]
 
[[Category:Hardware detection and troubleshooting (简体中文)]]
 
[[Category:Hardware detection and troubleshooting (简体中文)]]
[[Category:Boot process (简体中文)]]
 
 
[[en:Kernel modules]]
 
[[en:Kernel modules]]
 
[[es:Kernel modules]]
 
[[es:Kernel modules]]
 +
[[fr:Kernel modules]]
 
[[it:Kernel modules]]
 
[[it:Kernel modules]]
本文包含了操作 [[Wikipedia:Loadable_kernel_module|内核模块]] 的不同方法。
+
[[ja:カーネルモジュール]]
 +
[[ru:Kernel modules]]
 +
{{Related articles start (简体中文)}}
 +
{{Related|Boot Debugging}}
 +
{{Related|Kernels (简体中文)}}
 +
{{Related|Kernel parameters (简体中文)}}
 +
{{Related articles end}}
 +
{{TranslationStatus (简体中文)|Kernel_modules|2013-07-06|264846}}
 +
[[Wikipedia:Loadable_kernel_module|内核模块]]是可以按需加载或卸载的内核代码,可以不重启系统就扩充内核的功能。
  
 
== 概览 ==
 
== 概览 ==
  
要让内核认识模块,需要在内核配置时将模块配置为 {{ic|M}} (模块)。
+
要创建内核模块,请阅读[http://tldp.org/LDP/lkmpg/2.6/html/index.html 此指南]。模块可以设置成内置或者动态加载,要编译成可动态加载,需要在内核配置时将模块配置为 {{ic|M}} (模块)。
  
 
模块保存在 {{ic|/lib/modules/''kernel_release''}} (使用 {{ic|uname -r}} 命令显示当前内核版本)。
 
模块保存在 {{ic|/lib/modules/''kernel_release''}} (使用 {{ic|uname -r}} 命令显示当前内核版本)。
 
{{ic|/sbin/modprobe}} 命令负责内核模块的加入和移除。
 
 
{{ic|/etc/modprobe.d/}} 目录可以将模块设置传递给 [[udev]], udev 使用 {{ic|modprobe}} 在系统启动时管理内核模块的装入。可以使用任意配置文件名,只要是以 {{ic|.conf}} 结尾即可。
 
  
 
{{注意|模块名通常使用 ({{ic|_}}) 或 {{ic|-}} 连接,但是这些符号在 {{ic|modprobe}} 命令和 {{ic|/etc/modprobe.d/}} 配置文件中都是可以相互替换的。}}
 
{{注意|模块名通常使用 ({{ic|_}}) 或 {{ic|-}} 连接,但是这些符号在 {{ic|modprobe}} 命令和 {{ic|/etc/modprobe.d/}} 配置文件中都是可以相互替换的。}}
Line 22: Line 25:
 
== 获取信息 ==
 
== 获取信息 ==
  
* 显示当前装入的内核模块:
+
显示当前装入的内核模块:
 
  $ lsmod
 
  $ lsmod
  
* 使用 {{ic|modinfo}} 显示模块信息:
+
显示模块信息:
 
  $ modinfo ''module_name''
 
  $ modinfo ''module_name''
 
* 使用 {{ic|modprobe}} 显示模块的依赖关系:
 
$ modprobe --show-depends ''module_name''
 
 
* 使用 {{ic|systool}} 显示一个装入模块使用的选项:
 
$ systool -v -m ''module_name''
 
 
===配置===
 
  
 
显示所有模块的配置信息:
 
显示所有模块的配置信息:
 
 
  $ modprobe -c | less
 
  $ modprobe -c | less
  
 
显示某个模块的配置信息:
 
显示某个模块的配置信息:
 
 
  $ modprobe -c | grep ''module_name''
 
  $ modprobe -c | grep ''module_name''
  
===Parameters===
+
显示一个装入模块使用的选项:
 +
$ systool -v -m ''module_name''
  
下面的 bash 脚本可以显示当前装入模块、模块参数及当前参数的数值。它使用 {{ic|/proc/modules}} 获取当前装入模块的列表,然后用 modinfo 获取模块的描述和模块的参数,最后访问 sysfs 文件系统获得当前模块名和参数值。
+
显示模块的依赖关系:
 +
$ modprobe --show-depends ''module_name''
  
{{bc|<nowiki>function aa_mod_parameters ()
+
== 手动加载卸载 ==
{
+
    N=/dev/null;
+
    C=`tput op` O=$(echo -en "\n`tput setaf 2`>>> `tput op`");
+
    for mod in $(cat /proc/modules|cut -d" " -f1);
+
    do
+
        md=/sys/module/$mod/parameters;
+
        [[ ! -d $md ]] && continue;
+
        m=$mod;
+
        d=`modinfo -d $m 2>$N | tr "\n" "\t"`;
+
        echo -en "$O$m$C";
+
        [[ ${#d} -gt 0 ]] && echo -n " - $d";
+
        echo;
+
        for mc in $(cd $md; echo *);
+
        do
+
            de=`modinfo -p $mod 2>$N | grep ^$mc 2>$N|sed "s/^$mc=//" 2>$N`;
+
            echo -en "\t$mc=`cat $md/$mc 2>$N`";
+
            [[ ${#de} -gt 1 ]] && echo -en " - $de";
+
            echo;
+
        done;
+
    done
+
}</nowiki>}}
+
  
示例输出:
+
控制内核模块载入/移除的命令是{{Pkg|kmod}} 软件包提供的, 要手动装入模块的话,执行:
 
+
{{hc|# aa_mod_parameters|<nowiki>>>> ehci_hcd - USB 2.0 'Enhanced' Host Controller (EHCI) Driver
+
        hird=0 - hird:host initiated resume duration, +1 for each 75us (int)
+
        ignore_oc=N - ignore_oc:ignore bogus hardware overcurrent indications (bool)
+
        log2_irq_thresh=0 - log2_irq_thresh:log2 IRQ latency, 1-64 microframes (int)
+
        park=0 - park:park setting; 1-3 back-to-back async packets (uint)
+
 
+
>>> processor - ACPI Processor Driver
+
        ignore_ppc=-1 - ignore_ppc:If the frequency of your machine gets wronglylimited by BIOS, this should help (int)
+
        ignore_tpc=0 - ignore_tpc:Disable broken BIOS _TPC throttling support (int)
+
        latency_factor=2 - latency_factor: (uint)
+
 
+
>>> usb_storage - USB Mass Storage driver for Linux
+
        delay_use=1 - delay_use:seconds to delay before using a new device (uint)
+
        option_zero_cd=1 - option_zero_cd:ZeroCD mode (1=Force Modem (default), 2=Allow CD-Rom (uint)
+
        quirks= - quirks:supplemental list of device IDs and their quirks (string)
+
        swi_tru_install=1 - swi_tru_install:TRU-Install mode (1=Full Logic (def), 2=Force CD-Rom, 3=Force Modem) (uint)
+
 
+
>>> video - ACPI Video Driver
+
        allow_duplicates=N - allow_duplicates: (bool)
+
        brightness_switch_enabled=Y - brightness_switch_enabled: (bool)
+
        use_bios_initial_backlight=Y - use_bios_initial_backlight: (bool)</nowiki>}}
+
 
+
==装入==
+
要手动装入模块,运行:
+
  
 
  # modprobe ''module_name''
 
  # modprobe ''module_name''
  
要在系统启动时自动装入模块,请参考 [[rc.conf#Hardware|rc.conf]]。
 
 
==移除==
 
 
如果要移除一个模块:
 
如果要移除一个模块:
 
  # modprobe -r ''module_name''
 
  # modprobe -r ''module_name''
Line 110: Line 56:
 
  # rmmod ''module_name''
 
  # rmmod ''module_name''
  
==选项==
+
==配置==
可以用 modprobe 配置文件或内核命令行传入模块配置信息。
+
 
 +
目前,所有必要模块的加载均由 [[udev]] 自动完成。所以,如果不需要使用任何额外的模块,就没有必要在任何配置文件中添加启动时加载的模块。但是,有些情况下可能需要在系统启动时加载某个额外的模块,或者将某个模块列入黑名单以便使系统正常运行。
 +
 
 +
=== 开机加载 ===
 +
systemd 读取 {{ic|/etc/modules-load.d/}} 中的配置加载额外的内核模块。配置文件名称通常为 {{ic|/etc/modules-load.d/<program>.conf}}。格式很简单,一行一个要读取的模块名,而空行以及第一个非空格字符为{{ic|#}}或{{ic|;}}的行会被忽略,如:
 +
{{hc|/etc/modules-load.d/virtio-net.conf|<nowiki>
 +
# Load virtio-net.ko at boot
 +
virtio-net</nowiki>}}
 +
 
 +
另见{{ic|man 5 modules-load.d}}。
 +
 
 +
=== 配置内核模块参数 ===
  
===使用 /etc/modprobe.d/中的文件===
+
=== 使用 /etc/modprobe.d/中的文件===
 
要通过配置文件传递参数,在 {{ic|/etc/modprobe.d/}} 中放入任意名称 {{ic|.conf}} 文件,加入:
 
要通过配置文件传递参数,在 {{ic|/etc/modprobe.d/}} 中放入任意名称 {{ic|.conf}} 文件,加入:
 
{{hc|/etc/modprobe.d/myfilename.conf|2=options modname parametername=parametercontents}}
 
{{hc|/etc/modprobe.d/myfilename.conf|2=options modname parametername=parametercontents}}
Line 119: Line 76:
 
{{hc|/etc/modprobe.d/thinkfan.conf|2=# On thinkpads, this lets the thinkfan daemon control fan speed
 
{{hc|/etc/modprobe.d/thinkfan.conf|2=# On thinkpads, this lets the thinkfan daemon control fan speed
 
options thinkpad_acpi fan_control=1}}
 
options thinkpad_acpi fan_control=1}}
 +
 +
{{注意|如果要在启动时就修改内核参数(从 init ramdisk 开始),需要将相应的{{ic|.conf}}-文件加入 [[mkinitcpio.conf]] 的 FILES 参数中。}}
  
 
===使用内核命令行===
 
===使用内核命令行===
Line 139: Line 98:
  
 
==黑名单==
 
==黑名单==
 +
 +
=== 禁用内核模块 ===
 +
 
对内核模块来说,黑名单是指禁止某个模块装入的机制。当对应的硬件不存在或者装入某个模块会导致问题时很有用。
 
对内核模块来说,黑名单是指禁止某个模块装入的机制。当对应的硬件不存在或者装入某个模块会导致问题时很有用。
  
Line 145: Line 107:
 
{{ic|mkinitcpio -M}} 会显示所有自动检测到到模块:要阻止 initramfs 装入某些模块,可以在 {{ic|/etc/modprobe.d/modprobe.conf}} 中将它们加入黑名单。
 
{{ic|mkinitcpio -M}} 会显示所有自动检测到到模块:要阻止 initramfs 装入某些模块,可以在 {{ic|/etc/modprobe.d/modprobe.conf}} 中将它们加入黑名单。
  
运行 {{ic|mkinitcpio -v}} 会显示各种钩子(例如 filesystem 钩子, SCSI 钩子等)装入的模块。如果要禁用这些模块,记得在配置完成后重新生成 initramfs。
+
运行 {{ic|mkinitcpio -v}} 会显示各种钩子(例如 filesystem 钩子, SCSI 钩子等)装入的模块。如果要禁用这些模块,记得在配置完成后,将{{ic|.conf}}文件加入{{ic|/etc/mkinitcpio.conf}} 的 FILES 部分,然后重新生成 initramfs。
  
 
===使用 /etc/modprobe.d/ 中的文件===
 
===使用 /etc/modprobe.d/ 中的文件===
Line 154: Line 116:
 
blacklist pcspkr</nowiki>}}
 
blacklist pcspkr</nowiki>}}
  
{{注意|{{ic|blacklist}} 命令将屏蔽一个模板,所有不会自动装入,但是如果其它非屏蔽模块需要这个模块,系统依然会装入它。}}
+
{{注意|{{ic|blacklist}} 命令将屏蔽一个模板,所以不会自动装入,但是如果其它非屏蔽模块需要这个模块,系统依然会装入它。}}
  
 
要避免这个行为,可以让 modprobe 使用自定义的 {{ic|install}} 命令,直接返回导入失败:
 
要避免这个行为,可以让 modprobe 使用自定义的 {{ic|install}} 命令,直接返回导入失败:
Line 171: Line 133:
 
当某个模块导致系统无法启动时,可以使用此方法禁用模块。
 
当某个模块导致系统无法启动时,可以使用此方法禁用模块。
  
====使用 GRUB 的示例====
+
参阅[[Kernel parameters]].
  
{{hc|/boot/grub/menu.lst|<nowiki>...
+
== 技巧 ==
kernel /vmlinuz-linux root=/dev/sda1 modprobe.blacklist=pcspkr,ipv6 ro
+
...</nowiki>}}
+
  
{{hc|/boot/grub/menu.lst|<nowiki>...
+
=== 显示所有内核参数的脚本===
kernel /vmlinuz-linux root=/dev/sda1 pcspkr.disable=1 ipv6.disable=1 ro
+
下面的 bash 脚本可以显示当前装入模块、模块参数及当前参数的数值。它使用 {{ic|/proc/modules}} 获取当前装入模块的列表,然后用 modinfo 获取模块的描述和模块的参数,最后访问 sysfs 文件系统获得当前模块名和参数值。
...</nowiki>}}
+
 
 +
{{bc|<nowiki>function aa_mod_parameters ()
 +
{
 +
    N=/dev/null;
 +
    C=`tput op` O=$(echo -en "\n`tput setaf 2`>>> `tput op`");
 +
    for mod in $(cat /proc/modules|cut -d" " -f1);
 +
    do
 +
        md=/sys/module/$mod/parameters;
 +
        [[ ! -d $md ]] && continue;
 +
        m=$mod;
 +
        d=`modinfo -d $m 2>$N | tr "\n" "\t"`;
 +
        echo -en "$O$m$C";
 +
        [[ ${#d} -gt 0 ]] && echo -n " - $d";
 +
        echo;
 +
        for mc in $(cd $md; echo *);
 +
        do
 +
            de=`modinfo -p $mod 2>$N | grep ^$mc 2>$N|sed "s/^$mc=//" 2>$N`;
 +
            echo -en "\t$mc=`cat $md/$mc 2>$N`";
 +
            [[ ${#de} -gt 1 ]] && echo -en " - $de";
 +
            echo;
 +
        done;
 +
    done
 +
}</nowiki>}}
 +
 
 +
示例输出:
 +
 
 +
{{hc|# aa_mod_parameters|<nowiki>>>> ehci_hcd - USB 2.0 'Enhanced' Host Controller (EHCI) Driver
 +
        hird=0 - hird:host initiated resume duration, +1 for each 75us (int)
 +
        ignore_oc=N - ignore_oc:ignore bogus hardware overcurrent indications (bool)
 +
        log2_irq_thresh=0 - log2_irq_thresh:log2 IRQ latency, 1-64 microframes (int)
 +
        park=0 - park:park setting; 1-3 back-to-back async packets (uint)
 +
 
 +
>>> processor - ACPI Processor Driver
 +
        ignore_ppc=-1 - ignore_ppc:If the frequency of your machine gets wronglylimited by BIOS, this should help (int)
 +
        ignore_tpc=0 - ignore_tpc:Disable broken BIOS _TPC throttling support (int)
 +
        latency_factor=2 - latency_factor: (uint)
 +
 
 +
>>> usb_storage - USB Mass Storage driver for Linux
 +
        delay_use=1 - delay_use:seconds to delay before using a new device (uint)
 +
        option_zero_cd=1 - option_zero_cd:ZeroCD mode (1=Force Modem (default), 2=Allow CD-Rom (uint)
 +
        quirks= - quirks:supplemental list of device IDs and their quirks (string)
 +
        swi_tru_install=1 - swi_tru_install:TRU-Install mode (1=Full Logic (def), 2=Force CD-Rom, 3=Force Modem) (uint)
 +
 
 +
>>> video - ACPI Video Driver
 +
        allow_duplicates=N - allow_duplicates: (bool)
 +
        brightness_switch_enabled=Y - brightness_switch_enabled: (bool)
 +
        use_bios_initial_backlight=Y - use_bios_initial_backlight: (bool)</nowiki>}}
  
 
==参见==
 
==参见==
Line 185: Line 191:
 
*http://linuxmanpages.com/man5/modprobe.conf.5.php
 
*http://linuxmanpages.com/man5/modprobe.conf.5.php
 
*[[Disabling IPv6 (简体中文)|禁用 IPv6]]
 
*[[Disabling IPv6 (简体中文)|禁用 IPv6]]
*[[Disable PC Speaker Beep (简体中文)|禁用 PC喇叭]]
+
*[[Disable PC speaker beep (简体中文)|禁用 PC喇叭]]

Latest revision as of 15:56, 9 April 2016

翻译状态: 本文是英文页面 Kernel_modules翻译,最后翻译时间:2013-07-06,点击这里可以查看翻译后英文页面的改动。

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

概览

要创建内核模块,请阅读此指南。模块可以设置成内置或者动态加载,要编译成可动态加载,需要在内核配置时将模块配置为 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

手动加载卸载

控制内核模块载入/移除的命令是kmod 软件包提供的, 要手动装入模块的话,执行:

# modprobe module_name

如果要移除一个模块:

# modprobe -r module_name

或者:

# rmmod module_name

配置

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

开机加载

systemd 读取 /etc/modules-load.d/ 中的配置加载额外的内核模块。配置文件名称通常为 /etc/modules-load.d/<program>.conf。格式很简单,一行一个要读取的模块名,而空行以及第一个非空格字符为#;的行会被忽略,如:

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

另见man 5 modules-load.d

配置内核模块参数

使用 /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, LILOSyslinux)的内核行加入参数:

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/modprobe.conf 中将它们加入黑名单。

运行 mkinitcpio -v 会显示各种钩子(例如 filesystem 钩子, SCSI 钩子等)装入的模块。如果要禁用这些模块,记得在配置完成后,将.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/false
...

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

使用内核命令行

同样可以通过内核命令行(位于 GRUBLILOSyslinux)禁用模块:

modprobe.blacklist=modname1,modname2,modname3

当某个模块导致系统无法启动时,可以使用此方法禁用模块。

参阅Kernel parameters.

技巧

显示所有内核参数的脚本

下面的 bash 脚本可以显示当前装入模块、模块参数及当前参数的数值。它使用 /proc/modules 获取当前装入模块的列表,然后用 modinfo 获取模块的描述和模块的参数,最后访问 sysfs 文件系统获得当前模块名和参数值。

function aa_mod_parameters () 
{ 
    N=/dev/null;
    C=`tput op` O=$(echo -en "\n`tput setaf 2`>>> `tput op`");
    for mod in $(cat /proc/modules|cut -d" " -f1);
    do
        md=/sys/module/$mod/parameters;
        [[ ! -d $md ]] && continue;
        m=$mod;
        d=`modinfo -d $m 2>$N | tr "\n" "\t"`;
        echo -en "$O$m$C";
        [[ ${#d} -gt 0 ]] && echo -n " - $d";
        echo;
        for mc in $(cd $md; echo *);
        do
            de=`modinfo -p $mod 2>$N | grep ^$mc 2>$N|sed "s/^$mc=//" 2>$N`;
            echo -en "\t$mc=`cat $md/$mc 2>$N`";
            [[ ${#de} -gt 1 ]] && echo -en " - $de";
            echo;
        done;
    done
}

示例输出:

# aa_mod_parameters
>>> ehci_hcd - USB 2.0 'Enhanced' Host Controller (EHCI) Driver
        hird=0 - hird:host initiated resume duration, +1 for each 75us (int)
        ignore_oc=N - ignore_oc:ignore bogus hardware overcurrent indications (bool)
        log2_irq_thresh=0 - log2_irq_thresh:log2 IRQ latency, 1-64 microframes (int)
        park=0 - park:park setting; 1-3 back-to-back async packets (uint)

>>> processor - ACPI Processor Driver
        ignore_ppc=-1 - ignore_ppc:If the frequency of your machine gets wronglylimited by BIOS, this should help (int)
        ignore_tpc=0 - ignore_tpc:Disable broken BIOS _TPC throttling support (int)
        latency_factor=2 - latency_factor: (uint)

>>> usb_storage - USB Mass Storage driver for Linux
        delay_use=1 - delay_use:seconds to delay before using a new device (uint)
        option_zero_cd=1 - option_zero_cd:ZeroCD mode (1=Force Modem (default), 2=Allow CD-Rom (uint)
        quirks= - quirks:supplemental list of device IDs and their quirks (string)
        swi_tru_install=1 - swi_tru_install:TRU-Install mode (1=Full Logic (def), 2=Force CD-Rom, 3=Force Modem) (uint)

>>> video - ACPI Video Driver
        allow_duplicates=N - allow_duplicates: (bool)
        brightness_switch_enabled=Y - brightness_switch_enabled: (bool)
        use_bios_initial_backlight=Y - use_bios_initial_backlight: (bool)

参见