一个简单的内核模块包括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