カーネルモジュールのマジック番号(その1)
カーネルモジュールのmakeは、ソースファイルをtest.cとすると、testmod.mod.cというファイルが作成され、tset.c/testmod.mod.cのオブジェクトファイルをバインドし、testmod.koとして、ローダブルカーネルモジュールが作成されるようです。なおtestmod.mod.cにバージョンマジックが埋め込まれ、insmod時モジュールをインサートしてもいいかどうのかのチェックが行われます。
定かでないですが、以前はMakefieのEXTRAVERSIONを修正するだけで、よかったように記憶していますが・・・。記憶違いかもしれません。
testmod.mod.c
#include <linux/module.h>
#include <linux/vermagic.h>
#include <linux/compiler.h>
MODULE_INFO(vermagic, VERMAGIC_STRING);
struct module __this_module
__attribute__((section(".gnu.linkonce.this_module"))) = {
.name = KBUILD_MODNAME,
.init = init_module,
#ifdef CONFIG_MODULE_UNLOAD
.exit = cleanup_module,
#endif
.arch = MODULE_ARCH_INIT,
};
static const char __module_depends[]
__used
__attribute__((section(".modinfo"))) =
"depends=";
MODULE_INFO(srcversion, "DC76D599D92E61B57FEADEC");
VERMAGIC_STRINGがマジック番号となります。これは以下のvermagic.hで定義されていて、CONFIG_SMP/CONFIG_PREEMPT/CONFIG_MODULE_UNLOAD/CONFIG_MODVERSIONSのコンパイルオプションに依存して作成されます。
vermagic.h
#include <linux/utsrelease.h>
#include <linux/module.h>
/* Simply sanity version stamp for modules. */
#ifdef CONFIG_SMP
#define MODULE_VERMAGIC_SMP "SMP "
#else
#define MODULE_VERMAGIC_SMP ""
#endif
#ifdef CONFIG_PREEMPT
#define MODULE_VERMAGIC_PREEMPT "preempt "
#else
#define MODULE_VERMAGIC_PREEMPT ""
#endif
#ifdef CONFIG_MODULE_UNLOAD
#define MODULE_VERMAGIC_MODULE_UNLOAD "mod_unload "
#else
#define MODULE_VERMAGIC_MODULE_UNLOAD ""
#endif
#ifdef CONFIG_MODVERSIONS
#define MODULE_VERMAGIC_MODVERSIONS "modversions "
#else
#define MODULE_VERMAGIC_MODVERSIONS ""
#endif
#ifndef MODULE_ARCH_VERMAGIC
#define MODULE_ARCH_VERMAGIC ""
#endif
#define VERMAGIC_STRING \
UTS_RELEASE " " \
MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \
MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS \
MODULE_ARCH_VERMAGIC
なお、UTS_RELEASEがカーネルソース下のMakefieで設定する、バージョン番号です。Makefile VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 27 EXTRAVERSION = .41-170.2.117.fc10.i686 NAME = Trembling Tortoiseutsrelease.hは以下の1行だけのファイルです。推測ですが、これはカーネルmake時に作成されるのではと思います。ためしに、Makefileのこれらの設定を変更して、モジュールを作成しても、作成モジュールのマジック番号に反映されませんでした。マジック番号はUTS_RELEASEのその番号のままでした。
utsrelease.h #define UTS_RELEASE "2.6.27.41-170.2.117.fc10.i686"動作しているカーネルと異なるソース下でモジュールを作成する場合、modinfoでシステムで動作しているモジュールのマジック番号を調べ、本ヘッダファイルを修正すれば、そのシステム下で動作するモジュールを作成できるのではと思います。
補足
CONFIG_MODVERSIONSが設定されているシステムでは、マジック番号はVERMAGIC_STRING全体でチェックされ、そうでなければUTS_RELEASEだけのチェックとなっています。CONFIG_MODVERSIONSはシンボルにCRCを埋め込み、その正当性のチェックも行うもので、ロード時のチェックロジックは異なってます。従ってCONFIG_MODVERSIONSが設定されているシステムなら、マジック番号(UTS_RELEASEだけでよい)を一致させるだけでなく、モジュール作成時に、CONFIG_MODVERSIONSとして作成する必要があります。定かでないですが、以前はMakefieのEXTRAVERSIONを修正するだけで、よかったように記憶していますが・・・。記憶違いかもしれません。





