"Энциклопедия разработчика модулей ядра Linux" - читать интересную книгу автора (Померанц Ори)

Модули ядра из нескольких файлов

Иногда имеет смысл разделить модуль на несколько файлов. В этом случае Вы должны делать следующее:

1. Во всех исходных файлах добавьте строку #define __NO_VERSION__. Это важно, потому что module.h обычно включает определение kernel_version, глобальная переменная версии ядра для которой компилируется модуль. Если Вы нуждаетесь в version.h, Вы должны включить его непосредственно, потому что module.h не будет делать этого после указания __NO_VERSION__.

2. Скомпилируйте все исходные файлы как обычно.

3. Объедините все объектные файлы в один. Под x86 это делается командой:

ld -m elf_i386 -r -o lt;имя_модуляgt;.o lt;1-ый исходный файлgt;.o lt;2-ой исходный файлgt;.o.

Пример такого модуля:

start.c

/* start.c

* Copyright (C) 1999 by Ori Pomerantz

*

* "Hello, world" - the kernel module version.

* This file includes just the start routine

*/


/* The necessary header files */

/* Standard in kernel modules */

#include lt;linux/kernel.hgt;   /* We're doing kernel work */

#include lt;linux/module.hgt;   /* Specifically, a module */


/* Deal with CONFIG_MODVERSIONS */

#if CONFIG_MODVERSIONS==1

#define MODVERSIONS

#include lt;linux/modversions.hgt;

#endif


/* Initialize the module */

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" - the kernel module version. This

* file includes just the stop routine.

*/


/* The necessary header files */

/* Standard in kernel modules */

#include lt;linux/kernel.hgt; /* We're doing kernel work */


#define __NO_VERSION__ /* This isn't "the" file of the kernel module */

#include lt;linux/module.hgt; /* Specifically, a module */

#include lt;linux/version.hgt; /* Not included by module.h because of the __NO_VERSION__ */


/* Deal with CONFIG_MODVERSIONS */

#if CONFIG_MODVERSIONS==1

#define MODVERSIONS

#include lt;linux/modversions.hgt;

#endif


/* Cleanup - undid whatever init_module did */

void cleanup_module(){

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

}

Makefile

# Makefile for a multifile kernel module

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