[Linux驱动开发一]最简单的内核模块

  • Post author:
  • Post category:linux



目录


一、预备知识


1.1 什么是内核模块?


1.2 Linux内核模块组成部分


二、源码编写


1.1 hello.c源码编写


1.2 Makefile编写


三、源码编译


3.1 make编译


3.2 insmod加载内核模块


3.3 rmmod移除内核模块


3.4 查看内核模块


3.4.1 lsmod命令


3.4.2 cat /proc/modules


3.4.3 ls /sys/module/hello/


3.5 dmesg查看模块输出


四、小结



相关代码下载链接

一、预备知识

1.1 什么是内核模块?

Linux 内核模块(LKM)是一些在启动的操作系统内核需要时可以载入内核执行的代码块,不

需要时由操作系统卸载。它们扩展了操作系统内核功能却不需要重新编译内核、启动系统。如果没

有内核模块,就不得不反复编译生成操作系统的内核镜像来加入新功能,当附加的功能很多时,还

会使内核变得臃肿。

1.2 Linux内核模块组成部分

(1) 模块加载函数(

必须

):当通过insmod 或modprobe 命令加载内核模块时,模块的加载函

数会自动被内核执行,完成本模块相关初始化工作。

(2) 模块卸载函数(

必须

):当通过rmmod 命令卸载模块时,模块的卸载函数会自动被内核执

行,完成与模块加载函数相反的功能。

(3) 模块许可证声明(

必须

):模块许可证(LICENCE)声明描述内核模块的许可权限,如果

不声明LICENCE,模块被加载时将收到内核被污染的警告。大多数情况下,内核模块应遵循GPL 兼

容许可权。

(4) 模块参数(

可选

):模块参数是模块被加载的时候可以被传递给他的值,它本身对应模块内部

的全局变量。

(5) 模块导出符号(

可选

):内核模块可以导出符号(symbol,对应于函数或变量),这样其他模

块可以使用本模块中的变量或函数。

(6) 模块作者等信息声明(

可选

一个内核模块至少初始化函数init_module()和结束函数cleanup_module()。两个函数可以起任

意的名字,通过宏module_init()和module_exit()注册调用要编译内核模块,把代码嵌进内核空间。

二、源码编写

本节所提供示例十分简单,仅仅实现了在内核加载时打印“HELLO LINUX MODULE”,在内核

卸载时打印“GOODBYE LINUX MODULE”。

1.1 hello.c源码编写

/* 内核模块必须包含的头文件 */
#include<linux/module.h>

/* 加载函数:__init表示该函数只能在初始化期间使用,模块装载完后内核就会空间回收,释放内存*/
static int __init hello_init(void){
    printk(KERN_INFO "HELLO LINUX MODULE\n");
    return 0;
}

/* 卸载函数 */
static void __exit hello_exit(void){
    printk(KERN_INFO "GOODBYE LINUX MODULE\n");
}

/* 宏:指明初始化函数和清除函数 */
module_init(hello_init);
module_exit(hello_exit);

/* 描述性定义*/
MODULE_LICENSE("Dual BSD/GPL");  /* 许可协议 */
MODULE_AUTHOR("XZX");  /* 作者 */
MODULE_VERSION("V1.0")  /* 版本号 */

1.2 Makefile编写

# 定义内核源码的目录
KERNELDIR ?=/lib/modules/$(shell uname -r)/build
# 定义当前目录
PWD        := $(shell pwd)
# 要生成的内核模块
obj-m := hello.o

all:
	make -C $(KERNELDIR) M=$(PWD) modules
clean:
	rm -rf *.o *~ core .depend .*.cmd *.ko *.mode.c .tmp_versions *.mod *.order *.symvers

1.2 Makefile编写

三、源码编译

3.1 make编译

3.2 insmod加载内核模块

我们可以通过”sudo insmod hello.ko”加载内核模块,并通过lsmod查看

3.3 rmmod移除内核模块

通过“sudo rmmod hello”命令移除hello模块。如下图所示,此时列表中不再存在hello模块

3.4 查看内核模块

3.4.1 lsmod命令

3.4.2 cat /proc/modules

3.4.3 ls /sys/module/hello/

3.5 dmesg查看模块输出

四、小结

本节主要帮助大家了解基本的Linux内核模块开发框架和编译方法,掌握Linux内核模块添加流

程,理解了Linux内核模块代码中的一些常见宏和参数。



版权声明:本文为weixin_42857944原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。