一、helloword模块示例
1.第一个模块,hello-world模块
源程序
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("DUAL BSD/GPL");
static int hello_init(void)
{
printk(KERN_ALERT"hello, world\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT"Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
Makefile
obj-m := hello-world.o
KERNEL_DIR:=/lib/modules/$(shell uname -r)/build #指向内核源码
PWD:=$(shell pwd) #指向当前目录
all:
make -C $(KERNEL_DIR) M=$(PWD) modules
clean:
make -C $(KERNEL_DIR) M=$(PWD) clean
运行结果:
【释】
1.KERN_ALERT:定义日志优先级,不同级别使用不同字符串表示,数字越小,级别越高。
2.模块仅仅被链接到内核,因此它能调用的函数仅仅是由内核导出的那些函数。
二、用户空间和内核空间
模块运行在所谓的内核空间,而应用程序运行在所谓的用户空间。这两种模式具有不同的优先权等级,而且每个模式都有自己的内存映射,即有自己的地址空间。
三、内核中的并发
Linux内核代码必须是可重入的,必须能够同时运行在多个上下文中。
四、编译与构造
makefile的编写
obj-m := hello-world.o
#上面赋值语句,利用GNU make的扩展语法说明了有一个模块需要从
#hello.o中构造,而从该目标构造的模块名称为hello.ko
obj-m := module.o
module-objs := file1.o file2.o
#构造模块名为module.ko,并由两个源文件生成
KERNEL_DIR:=/lib/modules/$(shell uname -r)/build #指向内核源码
PWD:=$(shell pwd) #指向当前目录
make -C $(KERNEL_DIR) M=$(PWD) modules
#-C --- 指定内目录位置
# M --- 让该Makefile在构造modules之前回到模块源代码目录
五、装载和卸载模块
1.insmod – 装载
2.lsmod – 查看内核模块
3.rmmod – 卸载内核模块