一个简单的内核模块包括3个要素
1、MODULE_LICENSE("Dual BSD/GPL"); //模块许可声明
2、module_init(s5pv210_led_init); //模块加载入口声明
3、module_exit(s5pv210_led_exit); //模块卸载入口声明
代码实现:hello_world.c
#include <linux/kernel.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL"); //模块许可声明
static int hello_world_init(void)
{
printk("hello_world init\n");
return 0;
}
static void hello_world_exit(void)
{
printk("hello_worldexit\n");
}
module_init(hello_world_init); //模块加载入口声明
module_exit(hello_world_exit); //模块卸载入口声明
Makefile:
ifeq ($(KERNELRELEASE),) /* 如果KERNELRELEASE 未定义则执行下面语句
(KERNELRELEASE 是内核源码的顶层Makefile定义的变量,在第一次读取执行此Makefile时,KERNELRELEASE没有被定义)*/
KERNELDIR ?= /home/linux/store/linux-3.14 //对应内核源码目录
PWD := $(shell pwd)
all: //make 时从该目标执行
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules /* -C $(KERNELDIR) 跳转到内核源码目录下读取那里的Makefile
M=$(PWD) 返回到当前目录继续读入、执行当前的Makefile,而此时 KERNELRELEASE已被定义
故执行下面的obj-m := hello.o 生成.ko 模块文件
最后的modules 它指向的是读入的kernel顶层Makefile里的modules
*/
clean: //清除编译生成的文件
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module* modules* a.out
else
obj-m := hello_world.o //指定编译的文件名
endif