linux中的内核模块以及模块操作工具modprobe|insmod|rmmod|depmod|lsmod|modinfo等学习小结

1.linux中的内核模块

       为了应付日新月异的硬件,目前linux内核都具有可读取模块化驱动程序的功能,即所谓的“模块化”。“模块化”可以将它想成是一个“插件”,该插件可能有硬件开发厂商提供,也有可能是linux内核本来就支持的。一般来说,较新的硬件通常都需要硬件开发商提供驱动程序模块的。在linux系统中,内核模块一般会放到/lib/moudles/$(uname -r)/kernel目录中。


2.内核模块之间的依赖性以及模块依赖性生成工具depmod

       在linux中的有些内核模块是有依赖关系的,比如模块A依赖模块B,也就是模块A要工作,就必须要先加载模块B。那么,这个内核模块的依赖关系是维护在/lib/moudles/$(uname -r)/modules.dep文件中。而depmod命令可以生成modules.dep文件。例如,新做好的网卡驱动程序a.ko,更新内核模块的依赖性的方法是:

cp a.ko /lib/moudles/$(uname -r)/kernel/drivers/net
depmod

3.内核模块的相关操作命令

(1)查看系统安装了哪些模块

lsmod
(2)查看内核模块详细信息

modinfo 模块名/文件名
例如,
modinfo mii #查看模块mii的详细信息
modinfo a.ko #查看模块文件a.ko的详细信息
(3)模块的安装

(1)insmod
使用方法:
insmod 模块文件名
范例:
insmod /lib/modules/$(uname -r)/kernel/fs/cifs/cifs.ko

(2)modprobe
使用方法:
modprobe 模块名
范例:
modprobe cifs
(4)模块的卸载

(1)与insmod对应的rmmod
使用方法:
rmmod 模块名
范例:
rmmod cifs

(2)使用modprobe命令删除模块
使用方法:
modprobe -r 模块名
范例:
modprobe -r cifs

备注:

和insmod,rmmod相比较,使用modprobe加载删除某个内核模块时,它会去查找modules.dep,用户不需要考虑内核模块间的依赖关系。而insmod,rmmod需要用户去考虑依赖关系,否则可以加载删除失败。


4.关于内核模块的开发及使用的demo

       在Linux下,驱动程序是内核的一部分,运行在内核态下,你可以将驱动静态的和内核编译在一起,这样的缺点是内核会比较大,而且如果驱动出错,会导致整个系统崩溃;也可以以module的方式编译,在需要的时候动态的载入。

下面介绍下模块,一个简单的“helloworld module”如下所示:

/*  hello-1.c - The simplest kernel module.
 */
#include
  /* Needed by all modules */
#include
  /* Needed for KERN_ALERT */
 
int init_module(void)
{
   printk("<1>Hello world 1.\n");
 
   // A non 0 return means init_module failed; module can't be loaded.
   return 0;
}
 
void cleanup_module(void)
{
  printk(KERN_ALERT "Goodbye world 1.\n");
}
       其中,init_module函数是加载模块时会被调用的,一般作一些初始化的工作;cleanup_module函数是卸载模块时会被调用的,做一些清理的工作。因为模块是运行在内核态的,你自然不能使用库函数,因此要打印信息,需要使用printk函数而不是printf函数。另外,你可以使用任意函数名(只要同内核函数名不冲突)来替换init_module和cleanup_module这两个函数名,但必须使用module_init(初始化函数名),module_exit(卸载时函数名)这两个宏来声明一下,也就是说,下面这个模块和上面的模块是等价的:

/*  hello-1.c - The simplest kernel module.
 */
#include
  /* Needed by all modules */
#include
  /* Needed for KERN_ALERT */
 
int helloworld(void)
{
   printk("<1>Hello world 1.\n");
 
   // A non 0 return means init_module failed; module can't be loaded.
   return 0;
}
 
void goodbyeworld(void)
{
  printk(KERN_ALERT "Goodbye world 1.\n");
}
module_init(helloworld);
module_exit(goodbyeworld);
编译和加载一个模块也很容易:

linux中的内核模块以及模块操作工具modprobe|insmod|rmmod|depmod|lsmod|modinfo等学习小结_第1张图片
从上面的图可以看到,我们通过make编译生成一个模块文件".ko"之后,使用"insmod"命令来加载模块,那么“insmod”具体做了什么呢?

下面让我们来介绍下insmod这个工具:
insmod是linux下加载模块的工具,路径一般是/sbin/insmod,当你调用这个工具后,它的工作基本如下:

(1)在用户空间打开待安装的module

(2)调用query_module()系统调用询问无法落实的符号在内核或其他模块中的地址

(3)链接操作,落实模块中的符号引用

(4)调用create_module()系统调用在内核中创建module数据结构,并申请所需的内核空间

(5)调用init_module()系统调用将链接好的module映像装入内核空间,然后调用模块中的init_module()函数(注意:这里面的两个init_module函数不一样,一个是系统调用,一个是你写在模块里面的函数)

 从已加载模块中卸载模块使用的是“rmmod”,"rmmod"所做工作如下:

(1)调用delete_module()系统调用释放模块的module结构,同时释放模块所占的内核空间

(2)调用模块中的cleanup_module()的函数。

那么,一般情况下,驱动程序会在init_module()和cleanu_module()函数中做些什么呢?

(1)init_module(): 向内核登记本模块中一些包含着函数指针的数据结构(file_operations)
(2)cleanup_module(): 向内核撤销本模块提供的数据结构的登记,使内核在模块拆卸后不至于再企图访问这些数据结构


学习资料来源于:

http://www.cnblogs.com/amaoxiaozhu/archive/2013/03/08/2950002.html

你可能感兴趣的:(linux中的内核模块以及模块操作工具modprobe|insmod|rmmod|depmod|lsmod|modinfo等学习小结)