内核模块不是独立的可执行文件,但在运行时其目标文件被连接到内核中,因此,编译内核模块时必须加 -c 标志,另外, 还得加确定的预定义符号。
__KERNEL__ -- 这相当于告诉头文件,这个代码必须运行在内核模式下,而不是用户进程的一部分。
MODULE -- 这个标志告诉头文件,要给出适当的内核模块的定义。
LINUX -- 从技术上讲,这个标志不是必要的。但是,如果你希望写一个比较正规的内核模块,在多个操作系统上能进行编译,这个标志将会使你感到方便。它可以允许你在独立于操作系统的部分进行常规的编译。
还有其它的一些标志是否被包含进去,这取决于编译模块时的选项。如果你不能明确内核怎样被编译,可以在in/usr/include/linux/config.h中查到。
__SMP__ -- 对称多处理机。如果内核被编译成支持对称多处理机(即使它只不过运行在单个CPU上),这必须被定义。如果你要用对称多处理机,还有一些其它的事情必须做,在此不进行详细的讨论。
CONFIG_MODVERSIONS -- 如果CONFIG_MODVERSIONS被激活,当编译内核模块时,你必须定义它,并且包含进usr/include/linux/modversions.h中,这也可以由代码本身来做。
Makefile 举例
CC=gcc
MODCFLAGS := -Wall -DMODULE -D__KERNEL__ -DLINUX
hello.o: hello.c
/usr/include/linux/version.h
$(CC)
$(MODCFLAGS) -c hello.c
echo insmod hello.o to turn it on
echo rmmod hello to turn it off
echo
现在,你以root的身份对这个内核模块进行编译并连接后,形成一个目标文件hello.o,然后用insmod把hello插入到内核,也可以用rmmod命令把hello从内核移走。如果你想知道结果如何,你可以查看/proc/modules文件,从中会找到一个新加入的模块。