カーネルモジュールのマジック番号(その1)


カーネルモジュールのmakeは、ソースファイルをtest.cとすると、testmod.mod.cというファイルが作成され、tset.c/testmod.mod.cのオブジェクトファイルをバインドし、testmod.koとして、ローダブルカーネルモジュールが作成されるようです。なおtestmod.mod.cにバージョンマジックが埋め込まれ、insmod時モジュールをインサートしてもいいかどうのかのチェックが行われます。
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 Tortoise
utsrelease.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を修正するだけで、よかったように記憶していますが・・・。記憶違いかもしれません。

最終更新 2012/01/16 19:04:36 - north
(2012/01/16 18:53:30 作成)


検索

アクセス数
3689475
最近のコメント
コアダンプファイル - sakaia
list_head構造体 - yocto_no_yomikata
勧告ロックと強制ロック - wataash
LKMからのファイル出力 - 重松 宏昌
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
Adsense
広告情報が設定されていません。