Linux入门之CentOS7内核编译三部曲(3)

在上篇通过一些简单的例子和使用介绍了linux系统中模块的功能和作用。那么每次系统启动完成之后,又是怎么去自动加载所需要的模块,那么回过头来看还是要连续模块加载具体在系统启动中的哪个阶段开始触发的。同时模块的加载是依据内核本身的预定程序,还是linux文件系统中的相应配置文件呢?

 

默认安装的模块文件路径:/lib/modules/$(uname -r)/kernel,如:

#查看内核模块列表目录

[root@localhost ~]# ls /usr/lib/modules/$(uname -r)/kernel
arch  crypto  drivers  fs  kernel  lib  mm  net  sound

#当然还有另外一个目录 /usr/lib/modules/$(uname -r)/kernel

[root@localhost ~]# ls /usr/lib/modules/$(uname -r)/kernel
arch  crypto  drivers  fs  kernel  lib  mm  net  sound

注:在CentOS6之前是默认是存放在/lib/modules目录下的,并没有在/usr/lib/modules下存放,但是在安装 CentOS7之后会发现有两个目录都存放了内核模块文件。

#其实是CentoOS7为了保留原来的结构,添加了软连接

[root@localhost ~]# ls -dl /usr/lib /lib 
lrwxrwxrwx.  1 root root    7 Sep   7 16:11 /lib -> usr/lib
dr-xr-xr-x.   27 root root  4096 Sep  7 16:17 /usr/lib


 

具体操作模块的基本命令及常见方法:

 

查看当前已经加载的模块

cat /proc/modules#通过映射文件

lsmod#通过命令工具

 

实例:

#查找ext4文件系统相关的模块

[root@localhost ~]# grep '\<ext4\>' /proc/modules 
ext4 507694 3 - Live 0xffffffffa018e000
mbcache 14958 1 ext4, Live 0xffffffffa004c000
jbd2 98466 1 ext4, Live 0xffffffffa0174000
[root@localhost ~]# lsmod | grep '\<ext4\>'
ext4                507694  3 
mbcache               14958  1 ext4
jbd2                 98466  1 ext4


 

查看具体指定模块的信息

modinfo  module_name

wKioL1fj-ULSkGiZAAAxVjZ-6Ys299.png 

 

查看指定包的依赖

modprobe  --show-depends  module_name


例子:查看ext4的相关的依赖包

#通过命令查询

[root@mzf ~]# modprobe --show-depends ext4
insmod /lib/modules/2.6.32-642.el6.x86_64/kernel/fs/mbcache.ko 
insmod /lib/modules/2.6.32-642.el6.x86_64/kernel/fs/jbd2/jbd2.ko 
insmod /lib/modules/2.6.32-642.el6.x86_64/kernel/fs/ext4/ext4.ko

#通过depmod生成的配置文件查询

[root@mzf ~]# grep '\<ext4\>' /lib/modules/$(uname -r)/modules.dep
kernel/fs/ext4/ext4.ko: kernel/fs/jbd2/jbd2.ko kernel/fs/mbcache.ko

#当然如果此模块已经被加载,也可以通过 lsmod查看依赖

[root@mzf ~]# lsmod | grep '\<ext4\>'
ext4                  379655  3 
jbd2                  93252  1 ext4
mbcache                  8193  1 ext4


查看模块具体参数

modprobe  -c

 

#查看isofs的具体参数

[root@mzf ~]# modprobe -c | grep '\<isofs\>'
alias iso9660 isofs

解析:这里没有额外的内核参数,但是定义了一个别名为iso9660表示。

 

查看指定模块加载时使用的选项

systool  -v  -m  module_name

 

#查看ext4的具体选项属性

wKiom1fj-caDBVF4AAAXK88LQi4934.png 

 

手动加载卸载模块

modprobe  modprobe_name           #指定模块名称卸载模块
modprobe  -r  modprobe_name        #指定模块名称卸载模块
 
insmod  /path/to/modprobe.ko                #指定模块文件路径加载模块
rmmod  /path/to/modprobe.ko                 #指定模块文件路径卸载模块

解析:可以通过modinfo  -n  module_name来查看模块的文件存放路径,如果此模块功能正在被程序使用中,是不会被卸载掉的,如果想卸载,可以使用 -f选项进行强制卸载,modprobe和rmmod都支持此选项,但是不建议强制卸载,除非出现系统故障。

 

 

模块功能的高级配置

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

 

开机的模块加载

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

#查看虚拟化驱动目录

[root@localhost ~]# ls /usr/lib/modules/3.10.89/kernel/drivers/virtio/
virtio_balloon.ko  virtio.ko  virtio_pci.ko  virtio_ring.ko

#希望开机加载额外的virtio-net驱动

[root@localhost ~]# vim /etc/modules-load.d/virtio.conf
[root@localhost ~]# cat /etc/modules-load.d/virtio.conf 
# Load virtio.ko at boot
virtio

提示:具体配置可以查看man帮助手册,man  5  modules-load.d

 

 

小案例:解决光盘不能挂载,系统无法识别光盘文件系统。

#挂载光盘,发现挂载出错

[root@localhost ~]# mount /dev/cdrom /mnt/cdrom/
mount: unknown filesystem type 'iso9660'

说明:这里提示了未识别的文件系统 iso8660类型,开始推测是不是需要挂载时指定类型,是mount的挂载时出了问题,于是,再次挂载。

#再次挂载,并用mount -t指定类型

[root@localhost ~]# mount -t ISO9660 /dev/cdrom /mnt/cdrom
mount: unknown filesystem type 'ISO9660'

说明:仍然不行,难当当前系统内核不支持iso9660文件系统?于是查看当前系统内核模块支持的文件系统类别。

#查看当前内核支持的文件系统

[root@localhost ~]# cat /proc/filesystems 
nodevsysfs
nodevrootfs
nodevbdev
nodevproc
nodevcgroup
nodevcpuset
nodevtmpfs
nodevdevtmpfs
nodevdebugfs
nodevsecurityfs
nodevsockfs
nodevpipefs
nodevanon_inodefs
nodevconfigfs
nodevdevpts
nodevramfs
nodevhugetlbfs
nodevautofs
nodevpstore
nodevmqueue
nodevselinuxfs
ext4

说明:其中nodev表示已经加载此功能但是没有被设备或进程使用,左侧显示空白字符,表示此设备正在被使用。因此发现有autofs 自动挂载功能,就没有iso9660的文件系统模块。

#于是开始查看iso9660需要的模块,在查看前,先使用depmod命令重新生成依赖配置

[root@localhost ~]# depmod -a

#然后通过滤iso来查找对应的配置文件

[root@localhost ~]# grep '\<iso' /usr/lib/modules/$(uname -r)/modules.dep
kernel/fs/isofs/isofs.ko:

解析:这里搜索到了isofs文件系统模块,而且:后面没有其它模块说明此模块没有依赖于其它模块,因此可以直接加载此模块。

#加载模块,但是显示的相对于/usr/lib/modules/版本号/下的kernel目录,要加全路径

[root@localhost ~]# insmod /usr/lib/modules/$(uname -r)/kernel/fs/isofs/isofs.ko

#检查是否已经加载isofs模块

[root@localhost ~]# lsmod | grep '\<isofs\>'
isofs                  39846  0 
[root@localhost ~]# grep '\<isofs\>' /proc/modules 
isofs 39846 0 - Live 0xffffffffa022b000

#确定加载isofs模块后,再次尝试挂载

[root@localhost ~]# mount /dev/cdrom /mnt/cdrom/
mount: /dev/sr0 is write-protected, mounting read-only

#查看是否已经挂载成功

[root@localhost ~]# findmnt /dev/cdrom 
TARGET     SOURCE   FSTYPE  OPTIONS
/mnt/cdrom /dev/sr0 iso9660 ro,relatime

#将isofs文件系统模块设置开启自动加载,修改配置文件

[root@localhost ~]# cat /etc/modules-load.d/virtio.conf 
# Load virtio.ko at boot
virtio                            #这里表示模块名称

解析:文件名一般建议设置为模块的名称,下面没一行都可以添加一个模块名称,开机会自动从这些配置文件中逐行加载每个指定模块名称模块。

#然后reboot重启测试

[root@localhost ~]# reboot

#重启机器后,查看当前是否已经加载了isofs模块

[root@localhost ~]# lsmod | grep '\<isofs\>'
isofs                  39846  0 
[root@localhost ~]# grep '\<isofs\>' /proc/modules 
isofs 39846 0 - Live 0xffffffffa0129000

#再次查看此时内核支持的文件系统列表

[root@localhost ~]# cat /proc/filesystems

wKiom1fj-umBF9ISAAAdnEgMAX4209.png

解析:这里显示有刚才设置的iso9660表示此格式以后开启都会被加载,就不会再遇到iso9660格式的镜像文件系统格式不支持了。


总结以及问题遗留:

  本片接上篇再次整理了一下模块管理的相关命令以及其用法,同时补充了一个遇到的问题来说明模块管理的一些思路。无论是文件系统、硬件设备驱动、以及服务调用,只要功能不能支持,那么很有可能就是模块功能没有正常加载,这点和程序文件需要依赖于相应的库文件一样,密不可分。模块的加载都是通过一些配置,那么这些模块又是通过内核中的什么机制去读取modprobe.conf配置去加载相应的模块参数的呢?又是怎么根据加载硬件驱动后把对应识别到的每个硬件识别一个可访问的文件呢?这些都是留下的疑问?当然模块的问题只有不断的能深刻处理才能去处理之后的加载机制问题。