Module(模块)

概述

参考:

Linux 模块是 Loadable Kernel Module(全称为动态可加载内核模块,简称 LKM),简称为模块。模块是具有独立功能的程序,它可以被单独编译,但不能独立运行。它在运行时被链接到内核作为内核的一部分在内核空间运行,这与运行在用户空间的进程是不同的。模块通常由一组函数和数据结构组成,用来实现一种文件系统、一个驱动程序或其他内核上层的功能。

总之,模块是一个伪内核(从某种意义上来说,内核也是一个模块)或其他内核模块提供使用功能的代码块。

模块的管理方式:使用 systemd 控制的 unit:systemd-modules-load.service

该 unit 启动后读取其中指定目录下的配置以加载模块

模块关联文件与配置

系统启动后,依次从上到下从以下目录读取模块名称以加载它们

  • /etc/modules-load.d/*.conf
  • /run/modules-load.d/*.conf
  • /usr/lib/modules-load.d/*.conf

系统启动后,依次从上到下从以下目录读取模块的额外参数并应用它们

  • /etc/modprobe.d/*.conf
  • /run/modprobe.d/*.conf
  • /usr/lib/modprobe.d/*.conf
~]# cat /etc/modules-load.d/br_netfilter.conf
br_netfilter
  • 该目录格式为每个模块一行
  • 注意不要给模块名加任何后缀

/etc/sysconfig/modules/*.modules # 系统读取该目录下的脚本加载用户自定义的模块,该目录下的文件必须要以 .modules 为文件名结尾。该文件会被系统视为 shell 脚本,因此该文件应以解释器指令作为开头第一行。

/usr/lib/modules/$(uname -r)/kernel/ # 模块所在目录,不同类型的模块有不同目录

Note:不同版本内核的模块目录不同,所有安装的模块都在该目录下,如果需要把模块加载到内核中,则可以通过命令来加载该目录下的对应模块即可

  1. arch # 与硬件平台有关的项目,例如 CPU 的等级等等
  2. crypto # 核心所支持的加密的技术,例如 md5 或者 des 等等
  3. drivers # 一些硬件的驱动程序,例如显卡、网卡、PCI 相关硬件等等
  4. fs # 核心所支持的 filesystems,例如 vfat、reiserfs、nfs 等等
  5. lib # 一些函数库
  6. net # 与网络有关的各项协定数据,还有防火墙模块
  7. sound # 与音效有关的各项模块

模块之间的依赖性

使用 depmod 命令读取 /lib/modules/$(uname -r )/kernel/ 目录下每个模块并分析,然后把分析结果写入 /lib/modules/$(uname -r)/modules.dep 文件中。

模块管理命令行工具

查看已加载模块的当前参数

参考:https://serverfault.com/questions/62316/how-do-i-list-loaded-linux-module-parameter-values

depmod - 输出适用于 modprobe 可用性的依赖列表

depmod 输出的分析结果将会写入 /lib/modules/$(uname -r)/modules.dep 文件中。

EXAMPLE

  • depmod -n # 可以不写入文件而把结果输出到屏幕上
  • depmod -e # 显示出目前已载入的不可执行的模块名称

lsmod - 显示当前系统下已经加载了哪些模块

共三列信息 Module(模块名)、size(模块的大小)、Used by(此模块被哪个模块所使用)

~]# lsmod
Module                  Size  Used by
ip_vs                 155648  0
xt_conntrack           16384  1
xt_MASQUERADE          20480  1
......略

EXAMPLE

modinfo - 通过模块名或者模块文件名来查看模块信息

下面就是一个 ip_vs 模块的信息示例,第一列是想要显示的信息名称,第二列是该信息的具体内容

root@desistdaydream:~# modinfo ip_vs
filename:       /lib/modules/5.4.0-73-generic/kernel/net/netfilter/ipvs/ip_vs.ko
license:        GPL
srcversion:     D98100F31C2694A169510A5
depends:        nf_conntrack,nf_defrag_ipv6,libcrc32c
retpoline:      Y
intree:         Y
name:           ip_vs
vermagic:       5.4.0-73-generic SMP mod_unload modversions
sig_id:         PKCS#7
signer:         Build time autogenerated kernel key
sig_key:        76:5C:D9:9F:5C:00:1C:F9:61:BE:32:67:DA:52:57:FE:F4:C2:E1:6E
sig_hashalgo:   sha512
signature:      40:B0:9F:92:3C:6C:C8:9B:A2:E8:AA:91:15:44:DB:C6:0E:6E:31:0A:
  04:7F:42:FD:C0:EE:BB:8D:8B:67:49:A0:6A:72:8E:99:14:98:F3:D3:
    ......略
parm:           conn_tab_bits:Set connections' hash size (int)

我们可以通过 -F 选项来只列出来指定信息的值。

OPTIONS

  • -F,–field <STRING> # 仅仅列出指定字段的值,这对于在脚本中使用非常有用。STRING 就是上面示例中,第一列的字符串,比如 filename、license 等等,效果如下:
~]# modinfo -F filename ip_vs
/lib/modules/5.4.0-73-generic/kernel/net/netfilter/ipvs/ip_vs.ko
~]# modinfo -F license ip_vs
GPL
  • -F,–field 选项的简化用法
    • -a, –author # 仅列出作者名称
    • -d, –description # 仅列出 module 的 description
    • -l, –license # 仅列出 module 的 license
    • -n, –filename # 仅列出 module 的 filename 项(module 的文件所在路径)
    • -p, –parameters # 仅列出 modeule 的可用参数。
  • -b, –basedir <BASEDIR> #
  • -k KERNEL#

EXAMPLE

modprobe - 通过 module 的名字管理 module(不能通过文件名)

modprobe [OPTIONS] ModuleName

如果用该命令不加任何 OPTIONS 则是加载 module,重启后消失

modprobe(module 探针)(自动处理可载入模块)是 linux 的一个命令,可载入指定的个别模块,或是载入一组相依的模块。modprobe 会根据 depmod.dep 文件的相依关系,决定要载入哪些模块。若在载入过程中发生错误,在 modprobe 会卸载整组的模块

OPTIONS

  • -c # 列出目前系统所有的模块
  • -f # 强制载入该模块
  • -r # 移除摸个 module

EXAMPLE

rmmod - 卸载模块

modeprobe.d 配置文件详解

参考:

可用指令:

  • alias <Wildcard> modulename #
  • blacklist <ModuleName>
  • install <ModuleName> <COMMAND>… # 该命令指示 modprobe 工具运行我指定的命令,而不是像往常一样在内核中插入模块。该命令可以是任何 shell 命令: 这允许你做任何类型的复杂处理,你可能希望。例如,如果模块 “fred” 与已经安装的模块 “barney” 一起工作得更好 (但它不依赖于它,所以 modprobe 不会自动加载它),你可以说 “安装 fred /sbin/modprobe barney; /sbin/modprobe-ignore-install fred”,你想做什么就做什么。注意 – ignore-install,它阻止第二个 modprobe 再次运行相同的 install 命令。另请参阅下面的删除。
    • 注意:这个命令作为提供额外模块依赖的问题的解决方案的长期未来是不确定的,它打算用一个警告来代替这个命令,说明它在将来的版本中的某个时候最终被删除或弃用。它的使用使分发工具 (例如 mkinitrd) 对模块依赖关系的自动确定变得复杂 (因为它们现在需要以某种方式解释安装命令可能在做什么。在一个完美的世界中,模块将在不使用此命令的情况下提供所有依赖项信息,并且正在努力在 linux 内核中实现软依赖项支持。
  • options <ModuleName> <OPTION>… #
  • remove <ModuleName> <COMMAND>…#
  • softdep <ModuleName> pre: modules… post: modules… #

Dynamic Kernel Module Support

参考:

Dynamic Kernel Module Support(动态内核模块支持,简称 DKMS)


最后修改 July 29, 2024: wireguard (46e74df2)