Linux 内核模块管理 | 加载 / 卸载 / 自动启动配置

注:本文为 “Linux 内核模块管理” 相关文章合辑

机翻,未校。


Linux: How to load a kernel module automatically at boot time

Linux:如何在启动时自动加载内核模块

Author: Vivek Gite

Last updated: February 10, 2022

How do I load a Linux kernel module automatically at boot time to recognize my hardware during the system boot sequence?
如何在系统启动时自动加载 Linux 内核模块以识别我的硬件?

The Linux kernel follows modular kernel design. Loadable Kernel Modules (LKM) are object files that contain code to extend the running kernel or so-called base kernel. LKM’s are typically used to add support for new hardware, filesystems, NICs and more. Most of the time, they are device drivers for hardware, but LKM’s are common for file systems, firewalls, and other purposes. This page explains how to load a Linux kernel module (driver) at boot time using configuration options.
Linux 内核遵循模块化内核设计。可加载内核模块(LKM)是包含代码以扩展运行中的内核或所谓的基础内核的对象文件。LKM 通常用于添加对新硬件、文件系统、网卡等的支持。大多数情况下,它们是硬件的设备驱动程序,但 LKM 也常用于文件系统、防火墙等其他用途。本页面解释了如何使用配置选项在启动时加载 Linux 内核模块(驱动程序)。

Linux config file to load a kernel module

Linux 配置文件用于加载内核模块

Loading a Linux kernel module is an essential task for sysadmins. You need to edit the file named /etc/modules or put a new config file in /etc/modules-load.d/ directory. Use any one of the methods for loading kernel modules. The configuration file consists of a set of lines. All empty lines, and all text on a line after a #, will be ignored. The file /etc/modules (or other files in /etc/modules-load.d/) is used if new hardware is added after installation and the hardware requires a kernel module, the system must be configured to load the proper kernel module for the new hardware.
加载 Linux 内核模块是系统管理员的一项基本任务。您需要编辑名为 /etc/modules 的文件,或者在 /etc/modules-load.d/ 目录中放置一个新的配置文件。可以使用其中任何一种方法来加载内核模块。配置文件由一组行组成。所有空行以及 # 后面的所有文本都将被忽略。如果在安装后添加了新硬件,并且该硬件需要内核模块,则必须配置系统以加载适用于新硬件的正确内核模块。此时会使用 /etc/modules 文件(或 /etc/modules-load.d/ 中的其他文件)。

Examples

示例

For example, if a system included an IDE CD-ROM, the module configuration file contains the following 3 lines in the /etc/modules file. You can use the vim command or cat command to display it:
例如,如果系统包含一个 IDE CD-ROM,则模块配置文件在 /etc/modules 文件中包含以下 3 行。您可以使用 vim 命令或 cat 命令来显示它:

# vi /etc/modules # cat /etc/modules

Now you can append following lines:
现在您可以添加以下行:

ide-cd ide-core cdrom

Save and close the file. Reboot the Linux system for testing purpose using the reboot command or shutdown command:
保存并关闭文件。使用 reboot 命令shutdown 命令重新启动 Linux 系统以进行测试:

# reboot

How do I find out location of my Linux kernel device drivers/modules

如何查找我的 Linux 内核设备驱动程序 / 模块的位置

Use the ls command along with the uname command as follows:
使用以下命令结合 ls 命令和 uname 命令:

ls /usr/lib/modules/$(uname -r)/kernel/
ls -l /usr/lib/modules/$(uname -r)/kernel/

We use the uname to find out Linux kernel version and device drivers on the system:

我们使用 uname 来 查找 Linux 内核版本以及系统上的设备驱动程序:

Listing Linux kernel module on Linux CLI

Listing Linux kernel module on Linux CLI
在 Linux CLI 上列出 Linux 内核模块

Loading a device driver without rebooting the Linux machine

在不重启 Linux 机器的情况下加载设备驱动程序

Another option is to load drivers without rebooting the system. Use the modprobe command. For instance:
另一个选项是 在不重启系统的情况下加载驱动程序。使用 modprobe 命令。例如:

# modprobe {driver-name}
# modprobe {driver-name} *variable=value*
# modprobe ide-cd
# modprobe ide-cd cdrom
# pass the start_ro=1 option to md_mod module
# modprobe md_mod start_ro=1

Please note that if you are using an older version of Debian Linux or Ubuntu Linux use the file /etc/modules file instead of /etc/modules.conf which works on on an older version of Red Hat/Fedora/CentOS Linux too. These days it is better to use the directory /etc/modules-load.d/ on all Linux distros.
请注意,如果您使用的是 Debian Linux 或 Ubuntu Linux 的较早版本,请使用 /etc/modules 文件,而不是在较早版本的 Red Hat / Fedora / CentOS Linux 中也适用的 /etc/modules.conf。如今,最好在所有 Linux 发行版中使用 /etc/modules-load.d/ 目录。

Configuration directory for modprobe

modprobe 的配置目录

The modprobe command can add or remove more than one module at a time. Many modules have dependencies. Hence Linux provides a method of specifying what options are to be used with those modules. Therefore, use the /etc/modprobe.d/ directory with commands to build your logic. For example, here is my logic for Intel Wifi driver:
modprobe 命令可以同时添加或删除多个模块。许多模块存在依赖关系。因此,Linux 提供了一种指定与这些模块一起使用的选项的方法。因此,请使用 /etc/modprobe.d/ 目录中的命令来构建您的逻辑。例如,这是我的 Intel Wifi 驱动程序的逻辑:

$ cat /etc/modprobe.d/iwlwifi.conf
# /etc/modprobe.d/iwlwifi.conf
# iwlwifi will dyamically load either iwldvm or iwlmvm depending on the
# microcode file installed on the system. When removing iwlwifi, first
# remove the iwl?vm module and then iwlwifi.
remove iwlwifi \ 
(/sbin/lsmod | grep -o -e ^iwlmvm -e ^iwldvm -e ^iwlwifi | xargs /sbin/rmmod) \ 
&& /sbin/modprobe -r mac80211

You can see list of those commands using the man command:
您可以使用 man 命令查看这些命令的列表:

$ man modprobe.d

A note about modern Linux kernels

关于现代 Linux 内核的说明

These days udev is used for for automatic module handling. There is no need to put modules in any configuration file as udev takes care of it. However, sometimes you still need add an extra module during the boot process, or blacklist another one for your Linux laptop or server to function correctly. For example, kernel modules can be loaded during boot a boot in files under /etc/modules-load.d/. For instance:
如今,udev 用于自动处理模块。无需将模块放入任何配置文件,因为 udev 会处理它们。然而,有时您仍然需要在启动过程中添加一个额外的模块,或者将另一个模块列入黑名单,以确保您的 Linux 笔记本电脑或服务器正常运行。例如,可以在 /etc/modules-load.d/ 下的文件中在启动时加载内核模块。例如:

# cat /etc/modules-load.d/kvm.conf
kvm

kvm_intel

Task: See what Linux kernel modules are currently loaded
任务:查看当前已加载的 Linux 内核模块

Type the lsmod command as follows:
输入以下 lsmod 命令:

$ lsmod

OR

$ lsmod | more

Sample outputs:
示例输出:

在这里插入图片描述

Fig.01: Obtaining information about currently loaded modules/drivers
图 01:获取有关当前已加载的模块 / 驱动程序的信息

To get information about a module, run modinfo command
要获取有关模块的信息,请运行 modinfo 命令

You need to use the modinfo command as follows:
您需要使用以下 modinfo 命令:

$ modinfo {module_name}

For example get info about a module named igb:
例如,获取名为 igb 的模块的信息:

$ modinfo igb

Sample outputs:
示例输出:

在这里插入图片描述

Fig.02: Find information about a module
图 02:查找有关模块的信息

One can also use the systool command:
您还可以使用 systool 命令:

$ systool -v -m igb
$ systool -v -m nvme

How to unload/remove a module
如何卸载 / 删除模块

The syntax is as follows for the rmmod command
rmmod 命令的语法如下:

$ sudo rmmod {module_name}
OR
$ sudo modprobe -r {module_name}

In some cases, the Linux kernel modules cannot be removed by sysadmin at runtime to maintain system stability. You need to delete the configuration option from the /etc/modules file in such cases. Also delete the config file in /etc/modules-load.d/ directory using the rm command and cp command:
在某些情况下,为了维护系统稳定性,系统管理员无法在运行时删除 Linux 内核模块。在这种情况下,您需要从 /etc/modules 文件中删除配置选项。同样,使用 rm 命令和 cp 命令删除 /etc/modules-load.d/ 目录中的配置文件:

# ls -l /etc/modules-load.d/
# First, make a backup #
# cp /etc/modules-load.d/my-config.conf /root/my-config.conf-backup
# rm -i /etc/modules-load.d/my-config.conf

Summing up
总结

You learned about Linux kernel module configuration file locations on your disk and related commands. I would recommend reading the documentation using the help command or man command:
您了解了 Linux 内核模块配置文件在磁盘上的位置以及相关命令。我建议您使用 help 命令或 man 命令阅读文档:

man lsmod
man rmmod
man modinfo

How to Add, Remove, and Manage Linux Kernel Modules (Drivers)

如何添加、删除和管理 Linux 内核模块(驱动程序)

Author: Vivek Gite

Last updated: May 11, 2024

How do I add or remove hardware device driver (module) from running Linux kernel?
如何从运行中的 Linux 内核中添加或删除硬件设备驱动程序(模块)?

Linux systems comes with the modprobe command, to add and remove device drivers (modules) from the Linux Kernel. Please note that, Under MS-Windows you use term device driver for modules and under Linux you use term modules for device drivers. At boot time, only a minimal resident kernel is loaded into memory. If you add new hardware you need to add driver i.e. modules. The modprobe command intelligently adds or removes a module from the Linux kernel. Let us see how to easily add or remove Linux kernel modules from the CLI.
Linux 系统带有 modprobe 命令,用于从 Linux 内核中添加和删除设备驱动程序(模块)。请注意,在 MS-Windows 下,您使用术语“设备驱动程序”来指代模块,而在 Linux 下,您使用术语“模块”来指代设备驱动程序。在启动时,只有最小的驻留内核被加载到内存中。如果您添加了新硬件,则需要添加驱动程序,即模块。modprobe 命令可以智能地从 Linux 内核中添加或删除模块。让我们看看如何轻松地从命令行界面添加或删除 Linux 内核模块。

Listing Linux kernel modules (drivers)

列出 Linux 内核模块(驱动程序)

Usually, all Linux kernel modules (drivers) are stored in the module directory located that /lib/modules/$(uname -r) directory. To see current modules, type the following ls command:
通常,所有 Linux 内核模块(驱动程序)都存储在位于 /lib/modules/$(uname -r) 目录的模块目录中。要查看当前模块,请输入以下 ls 命令:

$ ls /lib/modules/$(uname -r)

Output:
输出:

build modules.ccwmap modules.order
initrd modules.dep modules.pcimap
kernel modules.dep.bin modules.seriomap
misc modules.devname modules.softdep
modules.alias modules.ieee1394map modules.symbols
modules.alias.bin modules.inputmap modules.symbols.bin
modules.builtin modules.isapnpmap modules.usbmap
modules.builtin.bin modules.ofmap updates

The entire command becomes ls /lib/modules/your_linux_kernel_version_here because of the uname command, effectively listing the kernel modules available for your currently running kernel version. Use the following command to list all drivers for various devices:
由于 uname 命令,整个命令变为 ls /lib/modules/your_linux_kernel_version_here,有效地列出了当前 运行中的内核版本可用的内核模块。使用以下命令列出各种设备的所有驱动程序:

$ ls /lib/modules/$(uname -r)/kernel/drivers/

Sample outputs:
示例输出:

Fig.01: Device drivers on my Linux based system

Fig.01: Device drivers on my Linux based system
图 01:我的基于 Linux 的系统上的设备驱动程序

Task: Add a Module (driver) Called foo

任务:添加名为 foo 的模块(驱动程序)

Type the following command as root user:
以 root 用户身份输入以下命令:

# modprobe foo

In this example, I am loading a module called i8k, enter:
在本例中,我正在加载一个名为 i8k 的模块,输入:

# modprobe -v i8k

Sample outputs:
示例输出:

insmod /lib/modules/3.5.0-30-generic/kernel/drivers/char/i8k.ko

Find out info about loaded module

查找已加载模块的信息

You need to use the modinfo command to see information about a Linux Kernel module. The syntax is:
您需要使用 modinfo 命令来查看有关 Linux 内核模块的信息。语法如下:

# modinfo -v {module-name-here} # modinfo i8k

Fig.02: Displaying information about a Linux Kernel module called i8k

Fig.02: Displaying information about a Linux Kernel module called i8k
图 02:显示名为 i8k 的 Linux 内核模块的信息

Task: List all loaded modules

任务:列出所有已加载的模块

Use the lsmod command to show the status of modules in the Linux Kernel:
使用 lsmod 命令显示 Linux 内核中模块的状态:

# lsmod

Sample outputs:
示例输出:

Module                  Size  Used by
smbfs                  75465  0
md5                     5953  1
ipv6                  284193  10
ipt_TOS                 4033  2
iptable_mangle          4545  1
ip_conntrack_ftp       74801  0
ip_conntrack_irc       74033  0
ipt_REJECT              8897  43
ipt_LOG                 8513  2
ipt_limit               4033  6
iptable_filter          4673  1
ipt_multiport           3521  4
ipt_state               3393  16
ip_conntrack           54297  3 ip_conntrack_ftp,ip_conntrack_irc,ipt_state
ip_tables              21825  8 ipt_TOS,iptable_mangle,ipt_REJECT,ipt_LOG,ipt_limit,iptable_filter,ipt_multiport,ipt_state
i2c_dev                13889  0
i2c_core               28865  1 i2c_dev
dm_mirror              32721  0
dm_mod                 68609  1 dm_mirror
button                  9313  0
battery                11465  0
ac                      6985  0
ohci_hcd               24529  0
ehci_hcd               33989  0
tg3                   109381  0
floppy                 66065  0
ext3                  137937  2
jbd                    69105  1 ext3
sata_svw               10053  3
libata                 78345  1 sata_svw
sd_mod                 19393  4
scsi_mod              141457  2 libata,sd_mod

Task: Remove a module called foo

任务:移除名为 foo 的模块

Pass the -r option to modprobe command to remove a module, type:
将 -r 选项传递给 modprobe 命令以移除模块,输入:

# modprobe -r foo

You can also use the rmmod command, which is simple program to remove a module from the Linux Kernel:
您还可以使用 rmmod 命令,这是一个简单的程序,用于从 Linux 内核中移除模块:

# rmmod foo

Configuring Linux drivers to automatically load at boot time

配置 Linux 驱动程序在启动时自动加载

You must create a new config file in the /etc/modules-load.d/ directory. First, Cd into that folder using the cd command:
您必须在 /etc/modules-load.d/ 目录中创建一个新的配置文件。首先,使用 cd 命令进入该文件夹:

$ cd /etc/modules-load.d/

Next, create a .conf file in this directory. For example, foo-driver.conf:
接下来,在此目录中创建一个 .conf 文件。例如,foo-driver.conf:

$ sudo vim foo-driver.conf

Now add the names of the kernel modules you want to autoload, one module name per line:
现在添加您想要自动加载的内核模块的名称,每个模块名称占一行:

# /etc/modules-load.d/foo-driver.conf

# Load my custom complied driver:

foo1

bar2

Please note that the /etc/modules is also the Linux kernel modules config file that load modules at boot time. However, we do not edit this file these days. Instead you need to make a new file in the /etc/modules-load.d/ directory. Please note that most modern Linux systems, using systemd as init, load Linux modules during boot via configuration files stored into the /etc/modules-load.d/ directory. If needed, you can still load modules manually using the modprobe command as explained earlier.
请注意,/etc/modules 也是在启动时加载模块的 Linux 内核模块配置文件。但是,我们如今不再编辑这个文件。相反,您需要在 /etc/modules-load.d/ 目录中创建一个新文件。请注意,大多数现代 Linux 系统使用 systemd 作为初始化程序,会在启动时通过存储在 /etc/modules-load.d/ 目录中的配置文件加载 Linux 模块。如果需要,您仍然可以使用前面解释过的 modprobe 命令手动加载模块。

Summing up

总结

You learned how to use various Linux command to list, add, and remove Linux kernel modules in the current Linux kernel. For more information see the following manual pages using the man command/ help command:

您学习了如何使用各种 Linux 命令在当前 Linux 内核中列出、添加和删除 Linux 内核模块。有关更多信息,请使用 man 命令/ help 命令查看以下手册页:

$ man modinfo $ man lsmod $ man insmod $ man modprobe

篇外:相关讨论

What is the sequence loading linux kernel module on startup? How priority is set to them?

启动时加载 Linux 内核模块的顺序是什么?如何设置它们的优先级?

I have a Linux kernel module which I compiled dynamically. How is it added to startup? There are lot of .ko files in /lib/modules. How is priority set for loading these modules?
我有一个动态编译的 Linux 内核模块。它是如何添加到启动中的?在 /lib/modules 中有许多 .ko 文件。这些模块的加载优先级是如何设置的?

edited Sep 10, 2013 at 21:12

Gilles ‘SO- stop being evil’

asked Sep 10, 2013 at 6:24

ganeshredcobra

2 Answers

14

They are not loaded automatically at start-up or any other time, although a lot of them do end up being loaded during boot. There are three different mechanisms by which this happens:
它们不会在启动时或任何其他时间自动加载,尽管许多模块确实会在启动过程中被加载。这通过三种不同的机制发生:

  • Userspace request: Which covers everything from init services to udev to the command-line. Init or udev are probably the most straightforward means if you want to load a specific module at boot time.

  • 用户空间请求:涵盖从初始化服务到 udev 再到命令行的所有内容。如果您想在启动时加载特定模块,init 或 udev 可能是最直接的方法。

  • Hotplugged device: When you connect something to, e.g., USB or PCI, the kernel detects this and requests an appropriate module based on how the device identifies itself.

  • 热插拔设备:当您将某物连接到 USB 或 PCI 等时,内核会检测到这一点,并根据设备的自我标识请求合适的模块。

  • Needed protocol or other implementation: When the kernel needs to do something, such as read a filesystem, and discovers it lacks the knowledge to do so, it will request a module.

  • 所需协议或其他实现:当内核需要执行某些操作(例如读取文件系统)并发现自身缺乏相关知识时,它会请求一个模块。

Notice that for the last two I used the phrase “request a module” – this is because the kernel actually loads via a userspace daemon, kmod which executes /sbin/modprobe. According to Wolfgang Mauerer in Linux Kernel Architecture, there are only ~100 different points in the 2.6 kernel where it calls an internal request_module() function.
请注意,对于最后两种情况,我使用了“请求模块”这一短语——这是因为内核实际上通过用户空间守护进程 kmod 加载,它执行 /sbin/modprobe。根据《Linux 内核架构》中 Wolfgang Mauerer 的说法,在 2.6 内核中,它调用内部 request_module() 函数的点大约只有 100 个。

modprobe uses a database of installed MODULE_ALIAS’s. These are specified in the module source code explicitly, or derived from it’s MODULE_DEVICE_TABLE, which is a list of OEM device IDs that the module services.
modprobe 使用已安装的 MODULE_ALIAS 的数据库。这些在模块源代码中明确指定,或者从其 MODULE_DEVICE_TABLE 推导而来,该表是模块服务的 OEM 设备 ID 列表。

edited Sep 10, 2013 at 14:38

answered Sep 10, 2013 at 8:58

goldilocks

5

Many systems are set up to use an initrd or initramfs. These are filesystem images that are loaded by the bootloader and made available to the kernel before it mounts the root partition. This allows drivers that are necessary to mount the root partition (disk drivers, filesystem drivers, device mapper or logical volume drivers, …) to be compiled as modules and loaded from the initrd/initramfs.

许多系统都设置为使用 initrd 或 initramfs。这些是由引导程序加载的文件系统镜像,并在内核挂载根分区之前提供给内核。这允许将挂载根分区(磁盘驱动程序、文件系统驱动程序、设备映射器或逻辑卷驱动程序等)所需的驱动程序编译为模块,并从 initrd/initramfs 加载。

The startup scripts on the initrd (/linuxrc) or initramfs (/init) typically loads some modules and locates the root filesystem. Each distribution has its own setup. Ubuntu uses an initramfs which is assembled from components in the initramfs-tools package and regenerated for each kernel based on the necessary drivers to mount the root filesystem.
initrd(/linuxrc)或 initramfs(/init)上的启动脚本通常会加载一些模块并定位根文件系统。每个发行版都有自己的设置。Ubuntu 使用一个 initramfs,它由 initramfs-tools 包中的组件组装而成,并根据挂载根文件系统所需的驱动程序为每个内核重新生成。

After the root filesystem is mounted, during the system boot, modules listed in /etc/modules (Debian, …) or /etc/modules.conf (Red Hat, Arch, …) are loaded. This file usually lists few modules if any. Most modules are loaded on demand.
在挂载根文件系统后,在系统启动期间,会加载 /etc/modules(Debian 等)或 /etc/modules.conf(Red Hat、Arch 等)中列出的模块。该文件通常列出的模块很少,如果有。大多数模块是按需加载的。

When the kernel detects some hardware for which it lacks a driver, or certain other components such as network protocols or cryptographic algorithms, it calls /sbin/modprobe to load the module. For hardware drivers, the kernel passes names that encode the PCI id, the USB id, or other systematic designation of the hardware. There is a table in /lib/modules/$VERSION/modules.alias that maps these systematic designations to module names. This table is generated by depmod and read by modprobe.
当内核检测到某些硬件缺少驱动程序,或者某些其他组件(如网络协议或加密算法)时,它会调用 /sbin/modprobe 来加载模块。对于硬件驱动程序,内核会传递编码 PCI ID、USB ID 或硬件的其他系统指定名称的名称。/lib/modules/$VERSION/modules.alias 中有一个表,将这些系统指定名称映射到模块名称。该表由 depmod 生成并由 modprobe 读取。

If you have an extra kernel module that you compiled manually for a hardware device, drop it into /lib/modules/$VERSION/local (create the local subdirectory if it doesn’t exist) and run depmod -a to regenerate the alias database. If the module is for some unusual feature that the kernel is unable to detect automatically, drop it into /lib/modules/$VERSION/local, run depmod -a to analyze its dependencies, and add the module name to /etc/modules.
如果您有一个为硬件设备手动编译的额外内核模块,请将其放入 /lib/modules/$VERSION/local(如果不存在,请创建 local 子目录),并运行 depmod -a 以重新生成别名数据库。如果该模块用于内核无法自动检测到的某些特殊功能,请将其放入 /lib/modules/$VERSION/local,运行 depmod -a 以分析其依赖项,并将模块名称添加到 /etc/modules

answered Sep 11, 2013 at 1:07

Gilles ‘SO- stop being evil’

I can’t find a /var/lib/modules nor a /lib/modules/*/local, nor can I find any mention of this on Google or in the depmod man page. Looked in CentOS 6.4, 7.4 and Ubuntu 19.04.
我找不到 /var/lib/modules/lib/modules/*/local,我也在 Google 上找不到任何相关内容,也没有在 depmod 的手册页中找到。我查看了 CentOS 6.4、7.4 和 Ubuntu 19.04。

– itsadok

Commented Sep 4, 2019 at 8:00

@itsadok I’m pretty sure I meant to write /lib/modules/…. Just create the local subdirectory (depmod traverses /lib/module/$VERSION recursively).
@itsadok 我相当确定我指的是 /lib/modules/…。只需创建 local 子目录(depmod 会递归遍历 /lib/module/$VERSION)。

– Gilles ‘SO- stop being evil’

Commented Sep 4, 2019 at 9:44

Do you know how to force kernel to pick my custom module instead of default one ?
您知道如何强制内核选择我的自定义模块而不是默认模块吗?

– EdiD

Commented Aug 28, 2021 at 13:38

@EdiD The kernel loads the code it’s told to load. The tool that maps a module name to a file containing code is modprobe. I guess it chooses the file to load based on modules.order but I don’t know what generates this. You should ask this as a new question on this site.
@EdiD 内核加载的是它被告知要加载的代码。将模块名称映射到包含代码的文件的工具是 modprobe。我猜它根据 modules.order 选择要加载的文件,但我不知道是什么生成了这个。您应该在这个网站上将此作为新问题提出。

– Gilles ‘SO- stop being evil’

Commented Aug 28, 2021 at 19:46

@Gilles’SO-stopbeingevil’ Ok thanks question asked.

– EdiD

Commented Aug 29, 2021 at 15:19


Are driver modules loaded and unloaded automatically?

驱动程序模块是否自动加载和卸载?

On Ubuntu 14.04, I found that when I don’t plug in my external wireless adapter, its module rt2800usb is still shown in lsmod.
在 Ubuntu 14.04 上,我发现即使我没有插入我的外部无线适配器,其模块 rt2800usb 仍然显示在 lsmod 中。

  1. when does automatically loading a driver module happen? Is it when the device is connected to the computer, or when the OS boots?

  2. 驱动程序模块何时自动加载?是当设备连接到计算机时,还是在操作系统启动时?

  3. when does automatically unloading a driver module happen? Is it when the device is disconnected to the computer, or when the OS shuts down?

  4. 驱动程序模块何时自动卸载?是当设备从计算机断开连接时,还是在操作系统关闭时?

asked Apr 21, 2015 at 17:14

Tim

2 Answers

16

When the kernel detects a new device, it runs the program modprobe and passes it a name that identifies the device. Most devices are identified through registered numbers for a vendor and model, e.g. PCI or USB identifiers. The modprobe program consults the module alias table /lib/modules/*VERSION*/modules.alias to find the name of the file that contains the driver for that particular device. A similar principle applies to drivers for things that are not hardware devices, such as filesystems and cryptographic algorithms. For more details, see Debian does not detect serial PCI card after reboot
当内核检测到新设备时,它会运行程序 modprobe 并传递一个标识设备的名称。大多数设备通过供应商和型号的注册号码进行标识,例如 PCI 或 USB 标识符。modprobe 程序会查阅模块别名表 /lib/modules/*VERSION*/modules.alias 以找到包含该特定设备驱动程序的文件名称。类似的原则也适用于非硬件设备的驱动程序,如文件系统和加密算法。

Once modprobe has identified which module file (.ko) contains the requested driver, it loads the module file into the kernel: the module code is dynamically loaded into the kernel. If the module is loaded successfully, it will then appear in the listing from lsmod.
一旦 modprobe 确定了哪个模块文件(.ko)包含请求的驱动程序,它就会将该模块文件加载到内核中:模块代码被 动态加载 到内核中。如果模块加载成功,它将出现在 lsmod 的列表中。

The automatic loading of modules happen when the kernel detects new hotpluggable hardware, e.g. when you connect a USB peripheral. The operating system also does a pass of enumerating all the hardware that’s present on the system early during startup, in order to load drivers for peripherals that are present at boot time.
模块的自动加载发生在内核检测到新的热插拔硬件时,例如当你连接一个 USB 外围设备时。操作系统还会在启动初期对系统上存在的所有硬件进行一次枚举,以便加载启动时存在的外围设备的驱动程序。

It’s also possible to manually request the loading of a module with the modprobe or insmod command. Most distributions include a startup script that loads the modules listed in /etc/modules. Another way for modules to be loaded is if they’re a dependency of a module: if module A depends on module B, then modprobe A loads B before loading A.
也可以使用 modprobeinsmod 命令手动请求加载模块。大多数发行版都包含一个启动脚本,用于加载 /etc/modules 中列出的模块。模块被加载的另一种方式是它们是某个模块的依赖项:如果模块 A 依赖于模块 B,那么 modprobe A 会在加载 A 之前加载 B。

Once a module is loaded, it remains loaded until explicitly unloaded, even if all devices using that driver have been disconnected. A long time ago, there was a mechanism to automatically unload unused modules, but it was removed, if I remember correctly, when udev came onto the scene. I suspect that automatic module unloading is not a common feature because the systems that would tend to need it are mostly desktop PCs that have lots of memory anyway (on the scale of driver code).
一旦模块被加载,它将保持加载状态,直到明确卸载,即使使用该驱动程序的所有设备都已断开连接。很久以前,有一个机制可以自动卸载未使用的模块,但如果我记正确的话,当 udev 出现时,这个机制被移除了。我怀疑自动卸载模块并不是一个常见的功能,因为需要它的系统大多是桌面电脑,而桌面电脑本身就有很多内存(就驱动程序代码的规模而言)。

edited Apr 13, 2017 at 12:36

answered Apr 22, 2015 at 1:34

Gilles ‘SO- stop being evil’

Thanks. I haven’t modified /etc/modules. rt2800usb is in the output of lsmod, and does that mean that I connected its device to my computer before since booting?
谢谢。我没有修改 /etc/modulesrt2800usb 出现在 lsmod 的输出中,这是否意味着我在启动后曾经将它的设备连接到我的电脑上?

– Tim

Commented Apr 22, 2015 at 2:311

@Tim If the module is loaded, and you didn’t load it explicitly, and it isn’t listed in /etc/modules, then yes, presumably the reason the module is loaded is because the device was present at some point.
@Tim 如果模块被加载了,而且你没有明确加载它,而且它也没有列在 /etc/modules 中,那么是的,假设模块被加载的原因是该设备在某个时刻存在过。

– Gilles ‘SO- stop being evil’

Commented Apr 22, 2015 at 11:15

The operating system also does a pass of enumerating all the hardware that's present on the system early during startup - How exactly is this done? What does the init script invoke to achieve this?
操作系统还会在启动初期对系统上存在的所有硬件进行一次枚举 - 这到底是如何完成的?启动脚本调用了什么来实现这一点?

– Axel Fontaine

Commented Dec 27, 2021 at 18:02

@AxelFontaine I think it’s udevadm trigger on a sysvinit system, and I guess that or some equivalent with systemd.
@AxelFontaine 我认为在 sysvinit 系统上是 udevadm trigger,我猜 systemd 也使用这个或类似的命令。

– Gilles ‘SO- stop being evil’

Commented Dec 27, 2021 at 19:01

5

Modules are loaded when the system boots via the Initial RAM Disk a.k.a the initrd. The Rationale Section states:
在系统启动时,通过 初始 RAM 磁盘,即 initrd 加载模块。理由部分指出:

Many Linux distributions ship a single, generic Linux kernel image – one that the distribution’s developers create specifically to boot on a wide variety of hardware. The device drivers for this generic kernel image are included as loadable kernel modules because statically compiling many drivers into one kernel causes the kernel image to be much larger, perhaps too large to boot on computers with limited memory. This then raises the problem of detecting and loading the modules necessary to mount the root file system at boot time, or for that matter, deducing where or what the root file system is.
 
许多 Linux 发行版都附带一个单一的通用 Linux 内核镜像,该镜像是由发行版的开发者专门创建的,以便能在各种各样的硬件上启动。针对这个通用内核镜像的设备驱动程序以可加载内核模块的形式包含在内,因为将大量驱动程序静态编译到一个内核中会使内核镜像变得大得多,对于内存有限的计算机来说,这个镜像可能大到无法启动。这就引出了一个问题,即在启动时检测并加载挂载根文件系统所需的模块,或者就此而言,推断根文件系统在哪里或者是什么。

Ubuntu like many other distributions, chooses to load every device driver into this initrd, regardless of whether the driver is needed or not, and also regardless if the device is present on the system or not. As Giles pointed out, the whole thing is loaded into RAM, and then the used modules are detected at startup, and the unused ones are removed from RAM. Using this approach ensures that Ubuntu will always start on any system regardless of setup. Ubuntu is mimicking a monolithic kernel using microkernel constructs. See The Reason This Works
Ubuntu 和许多其他发行版一样,选择将每个设备驱动程序都加载到这个 initrd 中,不管这个驱动程序是否需要,也不管该设备是否存在于系统中。正如 Giles 指出的那样,整个东西都被加载到 RAM 中,然后在启动时检测到使用的模块,并将未使用的模块从 RAM 中移除。采用这种方法可以确保 Ubuntu 总能在任何系统上启动,不管设置如何。Ubuntu 是使用微内核构造来模仿单内核的。


The module rt2800usb will always be loaded at bootup because the module was included in the initramfs that Gilles referred to. The initramfs is a successor of the initrd, therefore it will always be shown by lsmod. Note that you can insert a newly compiled module into the kernel by using modprobe followed by the module name.

模块 rt2800usb 总是在启动时加载,因为该模块被包含在 Gilles 提到的 initramfs 中。initramfs 是 initrd 的继承者,因此它总会被 lsmod 显示。注意,你可以通过使用 modprobe 后跟模块名称的方式,将新编译的模块插入内核。

As a test reboot your system with your wireless adapter unplugged. If all goes well the module will not be listed in lsmods output because during bootup the detection process started by the initramfs and the init system did not find the device during probing, and the module was removed from RAM.
作为一个测试,拔掉你的无线适配器后重新启动系统。如果一切顺利,该模块将不会出现在 lsmod 的输出中,因为在启动时,由 initramfs 启动的检测过程以及 init 系统在探测期间没有找到该设备,该模块被从 RAM 中移除。

To remove a module while a system is running, you can use commands such as rmmod, or modprobe -r followed by the module name. At the next boot the module will be reloaded. See Above. In most cases a module is not removed dynamically, as this would disable hotplugging, i.e once a module is removed the device using it cannot be detected again when replugged in.

要在系统运行时移除一个模块,你可以使用像 rmmod 这样的命令,或者使用 modprobe -r 后跟模块名称。在下次启动时,该模块将被重新加载。参见上文。在大多数情况下,模块不会被动态移除,因为这会禁用热插拔,即一旦模块被移除,当重新插入时,使用它的设备将无法再次被检测到。

In order to remove a module from lsmod, you must remove it from the initramfs image created by recompiling the kernel without the chosen module and then rebuilding the image. Doing this disables all detection of said module.
要从 lsmod 中移除一个模块,你必须从 initramfs 镜像中移除它,方法是重新编译内核而不包含选定的模块,然后重新构建镜像。这样做将禁用对该模块的所有检测。

edited Apr 13, 2017 at 12:36

answered Apr 21, 2015 at 18:55

eyoung100

You’re confusing loading a file into RAM as part of a RAM disk and loading (i.e. dynamically linking) a module into the running kernel. Modules are loaded temporarily into memory — not into the kernel — from the initrd (technically an initramfs nowadays), but they are then removed from memory after the real root is mounted. Modules are only loaded into the kernel when a device using them is detected (with a few exceptions).

你把将文件加载到 RAM 作为 RAM 磁盘的一部分和将(即动态链接)模块加载到运行中的内核中混淆了。模块是从 initrd(现在技术上是 initramfs)临时加载到内存中的——而不是加载到内核中——但在真正的根被挂载后,它们就会从内存中移除。只有在检测到使用它们的设备时(有一些例外),模块才会被加载到内核中。

– Gilles ‘SO- stop being evil’

Commented Apr 21, 2015 at 22:41

Whilst I agree here, he was talking about unloading and loading one module which cannot be done unless he chooses to reconfigure the Ubuntu RAM Disk, which is not recommended because Ubuntu chooses to load all the modules into RAM every kernel update. All modules are loaded every time, they are just not all used.
虽然我在这里同意,但他谈论的是卸载和加载一个模块,除非他选择重新配置 Ubuntu RAM 磁盘,否则这是无法做到的,而这是不推荐的,因为 Ubuntu 选择在每次内核更新时将所有模块加载到 RAM 中。每次都会加载所有模块,只是它们并非都被使用。

– eyoung100

Commented Apr 21, 2015 at 22:48

No, the question is about loading and unloading a module into the kernel. Neither your original answer nor your revised answer addresses that. The initramfs is irrelevant (or at most peripherally relevant) to this question.
不,问题是关于将模块加载和卸载到内核中。你的原始答案和修订后的答案都没有解决这个问题。initramfs 与这个问题无关(或者最多是边缘相关的)。

– Gilles ‘SO- stop being evil’

Commented Apr 21, 2015 at 23:02

@Gilles Is this better??

– eyoung100

Commented Apr 21, 2015 at 23:36

@eyoung100, I agree with Gilles. A discussion of initramfs is not relevant to the question. Modules are generally loaded by enumerating devices in /sys and loading the drivers for devices that are actually found in the system. This happens whether the device is present at boot or hot plugged later. udev has much more to do with it than initramfs/initrd does, and whether or not all, most, or only some modules are copied into the initramfs (a configuration option in /etc/initramfs-tools/initramfs.conf) is not especially relevant.
@eyoung100,我同意 Gilles 的观点。关于 initramfs 的讨论与问题无关。通常通过枚举 /sys 中的设备并加载系统中实际找到的设备的驱动程序来加载模块。无论设备是在启动时存在还是后来热插拔的,都会发生这种情况。udev 与之的关系比 initramfs/initrd 更大,而且是否将所有、大多数或仅部分模块复制到 initramfs(这是 /etc/initramfs-tools/initramfs.conf 中的一个配置选项)并不是特别相关。

– Celada

Commented Apr 21, 2015 at 23:54


via:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值