内核模块是Linux内核向外部提供的一个插口,全称为动态可加载内核模块,简称模块。Linux内核提供模块机制,是因为Linux本身是一个单内核。单内核的最大特点是效率高,因为所有的内容都集成在一起,缺点是可扩展性和可维护性相对较差,模块机制就是为了弥补这一个缺陷。
1.5.1 模块的定义
模块是具有独立功能的程序,可以被单独编译,但不能独立运行。在运行时被链接到内核作为内核的一部分在内核空间运行,这与运行在用户空间的进程是不同的。模块由一组函数和数据结构组成,用来实现一种文件系统、一个驱动程序或其他内核上层的功能。
1.5.2 编写一个简单的模块
模块和内核都在内核空间运行,模块编程也是内核编程。
1.程序举例
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
/**
* __init宏告诉编译程序相关的函数和变量仅用于初始化,
* 编译程序将标有__init的所有代码存储到特殊的内存段中,
* 初始化结束后就释放这段内存
*/
static int __init lkp_init(void)
{
printk("Hello, World! from kernel space...\n");
return 0;
}
static void __exit lkp_exit(void)
{
printk("Goodbye, World! leaving kernel space...\n");
}
/* lkp_init模块的初始化函数 */
module_init(lkp_init);
/* lkp_exit模块的退出和清理函数 */
module_exit(lkp_exit);
/* 告诉内核该模块具有GNU公共许可证 */
MODULE_LICENSE("GPL");
MODULE_VERSION("v1.0");
MODULE_AUTHOR("xz@vichip.com.cn");
2.编译模块
ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
#$(warning "11111111111111111111111)
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
else
obj-m := test.o
endif
3.安装内核模块
sudo insmod test.ko
4.查看已安装的内核模块
lsmod
5.卸载内核模块
sudo rmmod test
6.查看消息
dmesg
Hello, World! from kernel space...
Goodbye, World! leaving kernel space...