转:http://www.groad.net/bbs/read.php?tid-1006.html

程序代码

引用
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

MODULE_LICENSE("Dual BSD/GPL");

static int hello_init (void)
{
    printk("hello linux kernel\n");
   
    return 0;
}

static void hello_exit (void)
{
    printk("bye..lwave from the kernel\n");
   
}

module_init(hello_init);
module_exit(hello_exit);

编译方法( 只针对 2.6 内核 )


编写 Makefile 文件,Makefile 文件内容很简单,只有一行:


引用
obj-m := hello.o

执行命令


引用
beyes@linux-beyes:~/C/kernel> make -C /usr/src/linux-2.6.30 M=`pwd` modules
make: Entering directory `/usr/src/linux-2.6.30'
  CC [M]  /home/beyes/C/kernel/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/beyes/C/kernel/hello.mod.o
  LD [M]  /home/beyes/C/kernel/hello.ko
make: Leaving directory `/usr/src/linux-2.6.30'

引用
beyes@linux-beyes:~/C/kernel> ls
hello.c  hello.ko  hello.mod.c  hello.mod.o  hello.o  Makefile  Module.markers  modules.order  Module.symvers


说明


经过以上简单几步后,即生成了一个简单的模块。这个模块在加载之后,属于内核空间,是内核空间的一部分,而不是用户空间。


在 2.6 内核版本里,编译模块,首先需要有一份完整的,编译了的内核源代码树。编译内核见:

http://www.groad.net/bbs/read.php?tid=770

在 Makefile 文件里,obj-m 名字不能改变成别的,假如写成 objj-m ,那么编译后并不会输出 hello.ko 内核模块文件,而是只有:


引用
make: Entering directory `/usr/src/linux-2.6.30'
  Building modules, stage 2.
  MODPOST 0 modules
make: Leaving directory `/usr/src/linux-2.6.30'
beyes@linux-beyes:~/C/kernel> ls
hello.c  Makefile  Module.markers  modules.order  Module.symvers


假如要从两个源文件里编译得到一个名为 module.ko 的模块,那么 Makefile 文件可写成:


引用
obj-m := module.o
module-objs := file1.o file2.o



在编译命令 make -C /usr/src/linux-2.6.30 M=`pwd` modules 中,
-C 参数后面接内核源码树路径,这是个顶层路径,也就是说在这目录下可以找到编译内核的 Makefile 文件;
M= 选项使 "makefile" 移动回到所要编译的源码所在的目录下。也就是说,一开始,需要找到内核源码树下的 Makefile,然后需要再找到欲编译源码下的 Makefile