跨越多个文件的模块

有时,将一个内核模块拆分到多个源文件是有意义的。在这种情况下,你需要:

  1. 在除了一个源文件之外的所有源文件中,添加代码行 #define __NO_VERSION__。这很重要,因为module.h通常包含以下内容的定义:kernel_version,一个全局变量,包含模块编译时针对的内核版本。如果你需要version.h,你需要自己包含它,因为module.h不会因为你使用了__NO_VERSION__.

  2. 像往常一样编译所有源文件。

  3. 将所有目标文件合并为一个。在x86架构下,使用 ld -m elf_i386 -r -o <模块名.o> <第一个源文件.o> <第二个源文件.o>

这是一个这样的内核模块的示例。

示例 2-8. start.c

/*  start.c - Illustration of multi filed modules
 *
 *  Copyright (C) 2001 by Peter Jay Salzman
 *
 *  08/02/2006 - Updated by Rodrigo Rubira Branco <rodrigo@kernelhacking.com>
 */

/* Kernel Programming */
#define MODULE
#define LINUX
#define __KERNEL__

#include <linux/kernel.h>       /* We're doing kernel work */
#include <linux/module.h>       /* Specifically, a module */

int init_module(void)
{
  printk("Hello, world - this is the kernel speaking\n");
  return 0;
}

MODULE_LICENSE("GPL");

下一个文件

示例 2-9. stop.c

/*  stop.c - Illustration of multi filed modules
 *
 *  Copyright (C) 2001 by Peter Jay Salzman
 *
 *  08/02/2006 - Updated by Rodrigo Rubira Branco <rodrigo@kernelhacking.com>
 */

/* Kernel Programming */
#define MODULE
#define LINUX
#define __KERNEL__

#if defined(CONFIG_MODVERSIONS) && ! defined(MODVERSIONS)
   #include <linux/modversions.h> /* Will be explained later */
   #define MODVERSIONS
#endif        

#include <linux/kernel.h>  /* We're doing kernel work */
#include <linux/module.h>  /* Specifically, a module  */
#define __NO_VERSION__     /* It's not THE file of the kernel module */
#include <linux/version.h> /* Not included by module.h because of
	                                      __NO_VERSION__ */
	
void cleanup_module()
{
   printk("<1>Short is the life of a kernel module\n");
}  

最后,是makefile文件

示例 2-10. 用于多文件模块的Makefile

CC=gcc
MODCFLAGS := -O -Wall -DMODULE -D__KERNEL__
   	
hello.o:	hello2_start.o hello2_stop.o
   ld -m elf_i386 -r -o hello2.o hello2_start.o hello2_stop.o
   	
start.o: hello2_start.c
   ${CC} ${MODCFLAGS} -c hello2_start.c
   	
stop.o: hello2_stop.c
   ${CC} ${MODCFLAGS} -c hello2_stop.c