Linux模块详解(原创)

简介:

linux模块概述
内核模块是Linux内核向外部提供的一个插口,其全称为动态可加载内核模块(Loadable Kernel Module,LKM),我们简称为模块。Linux内核之所以提供模块机制,是因为它本身是一个单内核(monolithic kernel)。单内核的最大优点是效率高,因为所有的内容都集成在一起,但其缺点是可扩展性和可维护性相对较差,模块机制就是为了弥补这一缺陷。
模块是具有独立功能的程序,它可以被单独编译,但不能独立运行。它在运行时被链接到内核作为内核的一部分在内核空间运行,这与运行在用户空间的进程是不同的。模块通常由一组函数和数据结构组成,用来实现一种文件系统、一个驱动程序或其他内核上层的功能。

一个内核模块的从创建到使用会经过如下过程

源代码-->Makefile文件-->编译模块-->加载模块-->卸载模块
从某种意义上来说,内核也是一个模块。模块可以理解为为内核或其他内核模块提供使用功能的代码块,是内核的动态扩展。

内核模块的优缺点
优点
将内核映象的尺寸保持在最小,并具有最大的灵活性;
便于检验新的内核代码,而不需重新编译内核并重新引导。
缺点
装入的内核模块和其他内核部分一样,具有相同的访问权限,因此,差的内核模块会导致系统崩溃;
为了使内核模块访问所有内核资源,内核必须维护符号表,并在装入和卸载模块时修改这些符号表;
有些模块要求利用其他模块的功能,因此,内核要维护模块之间的依赖性。
内核必须能够在卸载模块时通知模块,并且要释放分配给模块的内存和中断等资源;
内核版本和模块版本的不兼容,也可能导致系统崩溃,因此,严格的版本检查是必需的。
尽管内核模块的引入同时也带来不少问题,但是模块机制确实是扩充内核功能一种行之有效的方法,也是在内核级进行编程的有效途径。

内核模块的加载与卸载

开机自动加载模块
手动编译一些驱动程序或者是 tarball 的套件后,会得到 *.ko 一个编译成功的目标档案。我们需要把编译好的模块放置在核心应该要放置的地方
核心的模块放置目录: /lib/modules/`uname –r`/kernel/
核心的档案格式模块: /lib/modules/`uname –r`/kernel/fs
核心的网络卡驱动程序模块: /lib/modules/`uname –r`/kernel/drivers/net
在模块的加载方面,最主要的开机时加载/etc/modprobe.conf中记录的模块。因此,我们把编译好的模块放在相应位置后,想要在开机的时候立即启动这个模块,那么需要在写入/etc/modprobe.conf相应记录。

一般的Linux发行版本都有 /etc/modules.conf 或 /etc/modprobe.conf 。在这个文件中一般是写入模块的加载命令或模块的别名的定义等;比如我们在modules.conf 中可能会发现类似的一行 ;
格式:alias 别名 模块名称
代码:alias eth0 8139too
这样系统启动的时候,首先会modprobe 8139too ,然后再为8139too 指定别名为 eth0,然后我们在登录的时候,用 ifconfig就会查看到网卡的IP等情况,当然您得为网卡设置IP 才行;
一般的情况下,modproe.conf 或modules.conf的内容 是我们用相应的硬件配置工具而生成的;如果您的硬件驱动是没有被内核支持,您自己到硬件的厂商下载而来的驱动。一般的情况下都有安装和帮助文件。他们的驱动在配置时,他会写入硬件的支持到modules.conf 或modprobe.conf 文件中。

lsmod
lsmod显示当前加载的所有模块,相当于cat /proc/modules,假设你没有设定开机加载某个模块,比如ntfs,那么开机后执行lsmod,列表里不会有ntfs这个模块的,这时你再执行 mount -t ntfs xxx后,执行lsmod后列表里就会有ntfs这个模块了。
还要注意的是lsmod显示的是模块名,而不是别名(alias)。

# lsmod 
Module                  Size  Used by
nfs                   229569  0

lockd                  63081  1 nfs

注意:第三列表示该模块被几个模块依赖,如共有1个模块依赖lockd模块,该模块为nfs

modinfo

用于查看模块的详细信息

# modinfo lockd
filename:       /lib/modules/2.6.18-164.el5/kernel/fs/lockd/lockd.ko
license:        GPL
description:    NFS file locking service version 0.5.
author:         Olaf Kirch <okir@monad.swb.de>
srcversion:     5AB38783DF566BC39C8C6D4
depends:        sunrpc
vermagic:       2.6.18-164.el5 SMP mod_unload 686 REGPARM 4KSTACKS gcc-4.1
parm:           nlm_max_connections:uint
module_sig:     883f3504a.......9c902f38b

insmod

insmod想内核加载模块
# insmod [-fkps] module_name
参数说明:
-f :强制将模块加载,要加载不相同版本的模块时候可能会用到的参数
-k:自动在核心没有使用到该模块的时候,先清除干净!
-p:测试模块是否可以被加载,不会直接加载系统中!
-s:将一些执行讯息写到 syslog 这种登录档,而不是写到 terminal 当中!
insmod可以读取非 /lib/modules/`uname -r`/kernel 内的模块。而且还可以为模块进行加载测试,利用-p参数可以验证该模块的可执行性与否!

modprobe 
insmod与modprobe都是载入kernel module,不过一般差别于modprobe能够处理 module 载入的相依问题。
比方你要载入 a module,但是 a module 要求系统先载入 b module 时,直接用insmod挂入通常都会出现错误讯息,不过 modprobe 倒是能够知道先载入b module后才载入a module,如此相依性就会满足。
modprobe之所以会知道模块之间的相依性,是通过读取 /lib/modules/`uname -r`/modules.dep得知的。而该档案是透过 depmod 程式所建立。
man modprobe
节选如下:
从linux核心中添加或删除模块。
为了一致性,模块名字中包含的_和-是没有任何区别的。modprobe会检查/lib/modules/`uname -r`下的所有模块,除了/etc/modprobe.conf配置文件和/etc/modprobe.d目录以外。所有/etc/modprobe.d/arch/目录下的文件将被忽略。
值得注意的是现在modprobe不会对模块本身进行操作,解析symbols和理解参数的工作都交由kernel来作,所以模块加载等错误有时将会包含在内核信息中,利用dmesg可以查看到。
modprobe会根据depmod生成的文件modules.dep来获取模块之间的依赖关系,从而添加或者删除模块。

现在版本的modprobe只支持2.5.48及以上的内核,如果它发现内核支持老版本的模块(该模块的大部分工作都在自己的运行空间完成),modprobe将在自己的运行空间尝试运行modprobe.modutils,该过程对用户完全透明。
如果在加载模块时指定参数,这些参数会和模块一起被传到内核中,并记录在配置文件中。

参数选项:
-l :列出目前系统所有的模块 ( 实际上modprobe会长modules.dep文件中找到相应模块后,才去搜索/lib/modules/`uname -r`下的模块 ),可以使用wildcard。

-c:列出目前系统所有的模块!(更详细的代号对应表)
-r:删除模块。

depmod

上文提到的模块依赖性是通过depmod命令生成的,该命令会分析/lib/modules/$(uname -r)/kernel目录下的所有模块,并将最终结果记录在modules.dep文件中供modprobe应用!

参数选项:
-A:不加任何参数時, depmod会主动的去分析目前内核模块,並且重新写入/lib/modules/$(uname -r)/modules.dep 当中。若加入 -A 参数时,depmod则会去搜索比modules.dep內还要新的模块,如果真找到新模块,才会更新。
-n:不写入modules.dep ,而是将結果输出到屏幕上(standard out);
-e:显示出目前已载入的不可执行的模块名称

 

参考至:http://blog.163.com/hu_cuit/blog/static/12284914320113972637691/

                  http://hi.baidu.com/scuxy06/item/7046362d0f5be8fd51fd8724

                  http://hi.baidu.com/20065562/item/15dcc4ce92c3d510b67a24af

                  http://baike.baidu.com/view/9243025.htm

                  http://www.cnitblog.com/xijia0524/archive/2012/11/08/86741.html

                  http://linux.vbird.org/linux_basic/0510osloader.PHP#kernel_modprobe

本文原创,转载请注明出处、作者

如有错误,欢迎指正
邮箱:czmcj@163.com

作者:czmmiao  文章出处:http://czmmiao.iteye.com/blog/1772502
相关文章
|
26天前
|
存储 Shell Linux
【Shell 命令集合 系统设置 】Linux 生成并更新内核模块的依赖 depmod命令 使用指南
【Shell 命令集合 系统设置 】Linux 生成并更新内核模块的依赖 depmod命令 使用指南
30 0
|
26天前
|
Shell Linux C语言
【Shell 命令集合 系统设置 】⭐Linux 卸载已加载的内核模块rmmod命令 使用指南
【Shell 命令集合 系统设置 】⭐Linux 卸载已加载的内核模块rmmod命令 使用指南
29 1
|
26天前
|
存储 Linux Shell
【Shell 命令集合 系统设置 】Linux 获取指定模块的元信息 minfo命令 使用指南
【Shell 命令集合 系统设置 】Linux 获取指定模块的元信息 minfo命令 使用指南
27 0
|
7月前
|
安全 Ubuntu Linux
Linux Kernel openvswitch模块权限提升漏洞(CVE-2022-2639)
Linux 内核模块Open vSwitch 存在越界写入漏洞,在足够多actions情况下,在为新的flow的新的action拷贝和预留内存时,如果next_offset比MAX_ACTIONS_BUFSIZE大,reserve_sfa_size并不会如期返回 -EMSGSIZE,此时会产生越界写入漏洞。攻击者可以利用该漏洞将普通权限提升至ROOT权限。
69 1
|
26天前
|
Linux Shell 文件存储
【Shell 命令集合 系统设置 】Linux 加载和卸载内核模块 modprobe命令 使用指南
【Shell 命令集合 系统设置 】Linux 加载和卸载内核模块 modprobe命令 使用指南
36 1
|
26天前
|
存储 Linux Shell
【Shell 命令集合 系统设置 】Linux 显示Linux内核模块的详细信息 modinfo命令 使用指南
【Shell 命令集合 系统设置 】Linux 显示Linux内核模块的详细信息 modinfo命令 使用指南
24 0
|
26天前
|
Shell Linux C语言
【Shell 命令集合 系统设置 】⭐Linux 向内核中加载指定的模块 insmod命令 使用指南
【Shell 命令集合 系统设置 】⭐Linux 向内核中加载指定的模块 insmod命令 使用指南
29 0
|
29天前
|
Linux 开发工具 C语言
【研究Qt webengine 模块编译】linux 交叉编译qt5.12的webengine模块成功的条件
【研究Qt webengine 模块编译】linux 交叉编译qt5.12的webengine模块成功的条件
34 1
|
6月前
|
传感器 机器人 Linux
Linux驱动基础(HC-SR04超声波模块)
Linux驱动基础(HC-SR04超声波模块)
52 0
|
6月前
|
传感器 Linux
Linux驱动基础(SR501人体感应模块)
Linux驱动基础(SR501人体感应模块)
55 0