如何编写一个模块加载到内核中,以hello world为例来说明怎么编写

首先创建一个文件夹hello,再编写代码和makefile

linux-d109:/home/hello # vi hello.c

#include

#include

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);

这个模块定义了两个函数, 一个在模块加载到内核时被调用( hello_init )以及一个在模块被去除时被调用( hello_exit ). moudle_init 和 module_exit 这几行使用了特别的内核宏来指出这两个函数的角色. 另一个特别的宏 (MODULE_LICENSE) 是用来告知内核, 该模块带有一个自由的许可证; 没有这样的说明, 在模块加载时内核会抱怨.

linux-d109:/home/hello # vi Makefile

obj-m := hello.o

熟悉make,但是对2.6内核建立系统不熟悉的读者,可能奇怪这个 makefile 如何工作。毕竟上面的这一行不是一个传统的 makefile 的样子。答案当然是内核建立系统处理了余下的工作。上面的安排(它利用了由GNU make提供的扩展语法)表明有一个模块要从目标文件 hello.o 建立。在从目标文件建立后结果模块命名为 hello.ko。反之,如果你有一个模块名为 module.ko,是来自 2 个源文件(姑且称之为,file1.c 和 file2.c),正确的书写应当是:

obj-m := module.o

module-objs := file1.o file2.o

上面的makefile需要将hello文件夹拷贝到/usr/src/linux中make,为此我们重新改写makefile文件

linux-d109:/home/hello # vi Makefile

obj-m := hello.o

KERNELBUILD := /lib/modules/`uname -r`/build

default:

@echo "  BUILD kmod"

@make -C $(KERNELBUILD) M=$(shell pwd) modules

clean:

@echo "  CLEAN kmod"

@rm -rf *.o

@rm -rf .depend .*.cmd *.mod.c .tmp_versions *.symvers .*.d *.markers *.orderlinux-d109

这样就可以直接在我们创建的模块文件夹里make了

linux-d109:/home/hello # make

BUILD kmod

make[1]: Entering directory `/usr/src/linux-2.6.27.19-5'

CC [M]  /home/xingf/hello.o

Building modules, stage 2.

MODPOST 1 modules

CC   /home/xingf/hello.mod.o

LD [M]  /home/xingf/hello.ko

make[1]: Leaving directory `/usr/src/linux-2.6.27.19-5'

下面再将创建好的模块.ko加载到内核中,只能是管理员用户才能加载

linux-d109:/home/hello # insmod hello.ko

卸载模块