Linux | 内核 | 内核模块(LKM)基础

 

LKM(Linux kernel module)作为Linux内核的插件,其安装和卸载都很方便(热插拔),可以满足一些需要特殊内核操作而不想重新编译整个内核的场景,在存储和安全厂商的产品中,LKM使用非常广泛。

Demo1

下面以一个非常简单的内核模块来了解LKM的使用

编写.c文件

/*  hello-5.c  */
#include <linux/module.h>      //Needed by all modules                                                                                                                 
#include <linux/kernel.h>      //Needed for KERN_INFO                                                                                                                  
#include <linux/moduleparam.h> //参数处理相关头文件                                                                                                                                          
#include <linux/init.h>                                                                                                                                                  
#include <linux/stat.h>                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                         
MODULE_LICENSE("GPL");         //声明Licesne                                                                                                                                        
MODULE_AUTHOR("Hunk He");      //声明模块作者                                                                                                                                          
                                                                                                                                                                         
static int param_cnt = 0;                                                                                                                                                
static char *param_arr[3] = {"", "", ""};        

module_param_array(param_arr, charp, &param_cnt, 0644);     //接收模块参数,参数名为param_arr,类型是字符串数组                                                                                                               
//MODULE_PARAM_DESC(param_arr, "My param array[up to 3]."); //参数描述信息,这里有奇怪编译错误

static int __init hello_5_init(void)
{
    printk(KERN_INFO "Hello world 5.\n"); //printk是内核的打印函数,可以向系统日志打印log
    int i;
    for( i = 0; i < 3; ++i) {
        printk(KERN_INFO "param_arr[%d] = %s.\n", i, param_arr[i]);
    }
        
    return 0;
}

static void __exit hello_5_exit(void)
{
    printk(KERN_INFO "Goodbye world 5.\n");
}

//实际上,模块安装卸载函数的用法还有好几种,可以参考References中的guide
module_init(hello_5_init); //模块加载函数,用modprobe或者insmod命令安装模块时被调用
module_exit(hello_5_exit); //模块卸载函数,用rmmod命令卸载模块时被调用,可以执行一些清理还原操作

编译LKM

内核模块一定是绑定某个特定内核版本来进行编译的,所以需要用-C指定内核源路径,如果需要绑定编译和当前系统不同的内核版本,可以下载内核rpm包解压后来作为源路径编译。

#Makefile
obj-m += hello-5.o
all:
        make -C /usr/src/kernels/3.10.0-862.11.6.el7.x86_64/ M=$(PWD) modules
clean:
        make -C /usr/src/kernels/3.10.0-862.11.6.el7.x86_64/ M=$(PWD) clean

执行make命令编译后生成内核模块hello-5.ko,后缀.ko是LKM的特有格式。

$ ll | grep hello-5.ko
-rw-r--r-- 1 root root 104728 Apr 20 18:21 hello-5.ko

安装LKM

下面将用modprobe命令来演示安装hello-5,也可以用更老一些的insmod命令跟上模块路径来进行安装。

$ mkdir -p /lib/modules/$(uname -r)/hunk/demo       #创建模块安装路径,一般是../组织名称/模块名称
$ cp hello-5.ko /lib/modules/$(uname -r)/hunk/demo  #拷贝LKM
$/sbin/depmod                                       #在依赖关系中自动添加模块相对路径,否则modprobe命令找不到模块
$ cat /lib/modules/$(uname -r)/modules.dep | grep hunk
hunk/demo/hello-5.ko:
$ /sbin/modprobe hello-5 param_arr=baidu,google,sina  #安装模块,模块名不包含.ko后缀
$ lsmod | grep hello                                #检查模块是否正在运行
hello_5                12629  0                     #注意此处的模块名称被转换了一下
root@n8-h27:/home/hunk/lkm/hello-5# modinfo hello_5 #modinfo可以查看模块详细信息,模块即使还没有安装到内核,也可以用此命令
filename:       /lib/modules/3.10.0-862.11.6.el7.x86_64/hunk/demo/hello-5.ko
author:         Hunk He
license:        GPL
retpoline:      Y
rhelversion:    7.5
srcversion:     6A562C1EA3F25D2CD3C1714
depends:        
vermagic:       3.10.0-862.11.6.el7.x86_64 SMP mod_unload modversions 
parm:           param_arr:array of charp
$ cat /var/log/messages | grep param_arr
Apr 20 18:55:33 n8-h27 kernel: param_arr[0] = baidu.
Apr 20 18:55:33 n8-h27 kernel: param_arr[1] = google.
Apr 20 18:55:33 n8-h27 kernel: param_arr[2] = sina.

卸载LKM

$ rmmod hello_5
$ lsmod | grep hello
$ cat /var/log/messages | grep bye
Apr 20 18:59:34 n8-h27 kernel: Goodbye world 5.

References

https://www.tldp.org/LDP/lkmpg/2.6/html/lkmpg.html #强烈推荐这篇文章

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值