# 核心与核心模块
整个开机流程讲完,在整个开机过程中,是否能够成功的驱动我们主机的硬件设备,是核心的工作,而核心一般都是压缩文件,因此需要先解压后才能加载主存储器中
目前的核心都是具有可读取模块化驱动程序的功能,即模块化(modules),该模块可能由硬件开发厂商提供,也有可能核心本来就支持,较新的硬件,通常都需要硬件开发商提供驱动程序的模块
核心与核心模块位置:
- 核心:
/boot/vmlinuz
或/boot/vminuz-version
- 核心解压缩需 RAM disk:
/boot/initramfs(/boot/initramfs-version)
- 核心模块:
/lib/modules/version/kernel
或/lib/modules/$(uname-r)
/kernel - 核心原始码:
/usr/src/linux
或/usr/src/kernels/
(默认不安装,安装才会有)
如果该核心被顺利加载到系统中了,那么就会有如下信息记录下来
- 核心版本:
/proc/version
- 系统核心功能:
/proc/sys/kernel
问题来了:如果有个新的硬件,我的操作系统不支持怎么办?
- 重新编译核心,并加入最新的硬件驱动程序原始码
- 将该硬件的驱动程序编译成为模块,在开机时加载该模块
关于怎么编译可以参考后续的第 21 章。
# 核心模块与相依性
基本上核心模块在 /lib/modules/$(uname -r)/kernel
中,主要分成几个目录
arch:与硬件平台有关项目,例如 CPU 的等级等
crypto:核心所支持的加密技术,例如 md5 或则是 des 等
drivers:一些硬件的驱动程序,例如显卡、网卡、PCI 相关硬件
fs:核心所支持的 filesystems,例如 vfat、reiserfs、nfs 等
lib:一些函数库
net:与网络有关的各项协议数据,还有防火墙模块(net、ipv4、netfilter) 等
sound:与音效有关
2
3
4
5
6
7
有一个文件记录了核心支持的模块的各项相依性:/lib/modules/$(uname -r)/modules.dep
, 可以使用 depmod 指令来管理
depmod [-Ane]
选项与参数:
-A:不加任何参数时,depmod 会主动分析目前核心的模块,并且重新写入该文件中。若加入 -A 参数时,则会去搜索比 modules.dep 内还要新的模块,如果找到新模块,才会更新
-n:不写入 modules.dep ,而是将结果输出到屏幕上
-e:显示出目前已加载的不可执行的模块名称
2
3
4
5
6
# 范例:若我做好一个网卡驱动程序,文件名为 a.ko ,如何更新核心想依性?
cp a.ko /lib/modules/$(uname -r)/kernel/drivers/net
depmod
2
3
核心模块扩展名一定是 .ko
结尾,当使用 depmod 后,该程序会在 /lib/modules/$(uname -r)/kernel/
目录内,根据相关目录的定义将全部的模块拿来分析,最终才会将分析的结果写入 modules.dep 文件中
该文件很重要,会影响到本章后续会介绍的 modprobe 指令的应用
# 核心模块的观察
可以通过 lsmod 知道目前核心加载了多少模块
[root@study ~]# lsmod
# 模块名 大小 模块是否被其他模块所使用
Module Size Used by
xt_CHECKSUM 12549 1
ipt_MASQUERADE 12678 3
nf_nat_masquerade_ipv4 13430 1 ipt_MASQUERADE
tun 32026 1
bridge 151336 0
stp 12976 1 bridge
llc 14552 2 stp,bridge
...
drm 311588 4 qx1,ttm,drm_kms_helper
2
3
4
5
6
7
8
9
10
11
12
13
模块是有相依性的,比如上面 nf_nat_masquerade_ipv4 先加载,ipt_MASQUERADE 模块才能够进一步加载到系统中,这两者是有相依性的
想要了解某个块,可以使用 modinfo
modinfo [-adln] [module_name|filename]
选项与参数:
-a:仅列出作者名称
-d:仅列出该 modules 的说明(description)
-l:仅列出授权 license
-n:仅列出该模块的详细路径
2
3
4
5
6
# 范例:列出 drm 模块的相关信息
[root@study ~]# modinfo drm
# 该模块的来源
filename: /lib/modules/3.10.0-1062.el7.x86_64/kernel/drivers/gpu/drm/drm.ko.xz
license: GPL and additional rights
# 该模块的简介
description: DRM shared core routines
author: Gareth Hughes, Leif Delgass, José Fonseca, Jon Smirl
license: GPL and additional rights
description: DRM bridge infrastructure
author: Ajay Kumar <ajaykumar.rs@samsung.com>
retpoline: Y
rhelversion: 7.7
srcversion: 0B7C5A6948CEE2DF7C405B0
depends: drm_panel_orientation_quirks
...
sig_hashalgo: sha256
parm: edid_firmware:Do not probe monitor, use specified EDID blob from built-in data or /lib/firmware instead. (string)
parm: vblankoffdelay:Delay until vblank irq auto-disable [msecs] (0: never disable, <0: disable immediately) (int)
parm: timestamp_precision_usec:Max. error on timestamps [usecs] (int)
parm: edid_fixup:Minimum number of valid EDID header bytes (0-8, default 6) (int)
parm: debug:Enable debug output, where each bit enables a debug category.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
该指令处理可以查询在核心内的模块,还可以检查某个模块文件。
# 核心模块的加载与移除
如想手动加载模块?有很多方法,这里推荐最简单的方式,就是使用 modprobe 指令来加载模块,因为它会主动搜索 modules.dep 的内容,先克服了模块的相依性后,才决定需要加载的模块有哪些
而 insmod 则完全由使用者加载一个完整文件名的模块,并不会主动分析模块的相依性
insmod [/full/path/module_name] [parameters]
# 范例 1:尝试载入 cifs.ko 文件系统模块
[root@study ~]# insmod /lib/modules/$(uname -r)/kernel/fs/fat/fat.ko.xz
[root@study ~]# lsmod | grep fat
fat 65950 0
2
3
4
5
like就被加载了,但是需要完整的路径
rmmod [-fw] module_name
-f:强制移除该模块,无论是否正在使用
2
3
# 范例 1:将刚刚加载的模块移除
[root@study ~]# rmmod fat
[root@study ~]# lsmod | grep fat
# 就被移除掉了
# 范例 2:加载 vfat 这个文件系统模块
[root@study ~]# insmod /lib/modules/$(uname -r)/kernel/fs/fat/vfat.ko.xz
insmod: ERROR: could not insert module /lib/modules/3.10.0-1062.el7.x86_64/kernel/fs/fat/vfat.ko.xz: Unknown symbol in module
# 无法加载
2
3
4
5
6
7
8
9
上面就由于有模块相依性,无法直接被加载,就可以使用 modprobe 来处理
modprobe [-cfr] module_name
选项与参数:
-c:列出目前系统所有的模块(更详细的代号对应表)
-f:强制加载该模块
-r:类似 rmmod
2
3
4
5
6
# 范例 1: 加载 vfat 模块
[root@study ~]# modprobe vfat
[root@study ~]# lsmod | grep vfat
vfat 17461 0
fat 65950 1 vfat
# 可以看到,自己就帮我们解决了模块的相依性问题,而且只需要知道模块名
2
3
4
5
6
7
# 核心模块的额外参数设置:/etc/modprobe.d/*.conf
如果有某些特殊的需求导致你必须要让核心模块加上某些参数时,这个时候可以回到上一章的最后一小节 开机过程会用到的主要配置文件 中去了解,重点就是要自己建议 .conf
的文件,通过 options 来带入核心模块参数