10.5.3  内核模块的多个文件

有时,可以从逻辑上把内核模块分成几个源文件,在这种情况下,你需要做以下事情:

(1)     除了一个源文件外,在其他所有的源文件中都要增加一行 #define __NO_VERSION__,这是比较重要的,因为 module.h通常包括了对kernel_version的定义,kernel_version是一个具有内核版本信息的全局变量,并且编译模块时要用到它。如果你需要version.h,你就必须自己包含它,但如果你定义了 __NO_VERSION__module.h不会被包含进去。

(2)     像通常那样编译所有的源文件。

   3) 把所有的目标文件结合到一个单独文件中。在x86下,这样连接:

 ld -m elf_i386 -r -o <name of module>.o <1个源文件>.o <2个源文件>.o  

 

请看下面例子start.c   

 

 /* start.c

 *

 * "Hello, world" 

 * 这个文件包含了启动例程

 */

 

/*下面是必要的头文件 */

 

/* 内核模块的标准形式*/

#include <linux/kernel.h> 

#include <linux/module.h>  

 

/* 处理CONFIG_MODVERSIONS */

#if CONFIG_MODVERSIONS==1

#define MODVERSIONS

#include <linux/modversions.h>

#endif       

 

/* 初始化模块 */

int init_module()

{

  printk("Hello, world - this is the kernel speaking\n");

 

  return 0;

}

 

另一个例子 stop.c   

 

/* stop.c */

/* 这个文件仅仅包含 stop 例程。*/

 

/* 必要的头文件*/

 

#include <linux/kernel.h>  

 

#define __NO_VERSION__    

#include <linux/module.h>

#include <linux/version.h>

 

#if CONFIG_MODVERSIONS==1

#define MODVERSIONS

#include <linux/modversions.h>

#endif       

 

void cleanup_module()

{

  printk("Short is the life of a kernel module\n");

}

 

下面是多个文件的Makefile

 

CC=gcc

MODCFLAGS := -Wall -DMODULE -D__KERNEL__ -DLINUX

 

hello.o:   start.o stop.o

       ld -m elf_i386 -r -o hello.o start.o stop.o

 

start.o:   start.c /usr/include/linux/version.h

       $(CC) $(MODCFLAGS) -c start.c

 

stop.o:    stop.c /usr/include/linux/version.h

       $(CC) $(MODCFLAGS) -c stop.c

hello” 是模块名,它占用了一页(4K)的内存,此时,没有其它内核模块依赖它。要从内核移走这个模块,敲入“rmmod hello,注意,rmmod命令需要的是模块名而不是文件名。其它实用程序的使用可参看相关的文挡。

关于模块编程更多的内容我们将在后续章节继续讨论。