内核模块程序结构以及编译内核模块(单个文件以及多个文件)

单个文件编译的内核模块例子

#include <linux/module.h>
#include <linux/init.h>

static int __init hello_init()
{
  printk("Hello world!\n");
} 

static int __exit hello_exit()
{
  printk("<7>Hello <0>exit!\n");
}

module_init( hello_init);
module_exit( hello_exit); 

1.模块加载函数,通过module_init宏来指定

2.模块卸载函数,通过module_exit宏来指定

3.编译模块需要使用makefile文件,单一依赖文件的makefile

ifneq ($(KERNELRELEASE),)

obj-m := hello.o 

else
	
KDIR := /lib/modules/2.6.18-53.el5/build

all:
	make -C $(KDIR) M=$(PWD) modules
clean:
	rm -f *.ko *.o *.mod.o *.mod.c *.symvers

endif

注释

ifneq ($(KERNELRELEASE),) 

如果KERNELRELEASE这个变量不为空就执行

obj-m := hello.o 

第一次执行makefile文件 KERNELRELEASE是为空的,所以就会执行

KDIR := /lib/modules/2.6.18-53.el5/build

all:
	make -C $(KDIR) M=$(PWD) modules

KDIR :=的作用

编译内核模块需要依赖内核源代码,KDIR 指出内核源代码的路径

make -C $(KDIR) M=$(PWD) modules的讲解

make -C的含义是进出后面$(KDIR)指定的目录,使用此目录下的makefile来编译内核模块,此例中就是进入 /lib/modules/2.6.18-53.el5/build 下使用它的makefile来编译
M=$(PWD) M是build目录的makefile要求的,表示需要被编译的内核模块代码所在路径(.c文件路径)
$(PWD)代表当前目录下面。
modulesmakefile处理当中的目标。
使用/lib/modules/2.6.18-53.el5/build路径下的makefile文件,编译当前目录下的模块,生成modules。
在编译过程中会第二次使用本makefile,第二次使用makefileKERNELRELEASE就有内核版本号了,
然后就会运行obj-m := hello.o
hello.o是编译完成后内核模块的名字。

编译后会生成.ko文件,就是内核模块

单一.c文件必须和生成的.o文件名对应才行。之后会讲解多文件makefile的写法。

多个文件编译的内核模块例子

main.c

#include <linux/module.h>
#include <linux/init.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Fzh");
MODULE_DESCRIPTION("HELLO");

extern int add(int a, int b);

static int __init hello_init()
{
  printk("Hello world!\n");
  add(1,2);
  return 0;
} 

static int __exit hello_exit()
{
  printk("<7>Hello <0>exit!\n");
}

module_init( hello_init);
module_exit( hello_exit); 

add.c

int add(int a, int b)
{
  return a+b;
}

makefile

ifneq ($(KERNELRELEASE),)

obj-m := hello.o

hello-objs := main.o add.o 

else
	
KDIR := /lib/modules/2.6.18-53.el5/build

all:
	make -C $(KDIR) M=$(PWD) modules
clean:
	rm -f *.ko *.o *.mod.o *.mod.c *.symvers

endif

需要注意的是

obj-m := hello.o        //最终生成hello.ko

hello-objs := main.o add.o //为了最终生成hello.ko需要main.o 和 add.o