next up previous contents index
Next: 字符设备文件 Up: Hello, world Previous: 内核模块的Make文件

     
多文件内核模块

有时候将内核模块分为几个源文件是有意义的,你需要做下面的事情:

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.   

这里有一个这样的内核模块的范例。

范例 start.c   

 
/* start.c 
 * Copyright (C) 1999 by Ori Pomerantz
 * 
 * "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");

  /* If we return a non zero value, it means that 
   * init_module failed and the kernel module 
   * can't be loaded */
  return 0;
}

范例 stop.c   

 
/* stop.c 
 * Copyright (C) 1999 by Ori Pomerantz
 * 
 * "Hello, world" - 内核模块版本 
 * 这个文件只包含终止程序
 */

/* 必要的头文件 */

/* 内核模块的标准头文件 */
#include <linux/kernel.h>   /* 我们正在做内核的工作 */

#define __NO_VERSION__      /* 这不是内核模块文件 */
#include <linux/module.h>   /* 明确的指定是内核模块 */

#include <linux/version.h>   /* 因为有 __NO_VERSION__ 而不能被自动包含*/



/* 处理 CONFIG_MODVERSIONS */
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include <linux/modversions.h>
#endif        




/* Cleanup - 撤消init_module 所做的任何事情 */
void cleanup_module()
{
  printk("Short is the life of a kernel module\n");
}

范例 Makefile   

 
# 多文件内核模块的Make文件

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


next up previous contents index
Next: 字符设备文件 Up: Hello, world Previous: 内核模块的Make文件

1999-05-19