はじめに
Linuxにおいてデバイスドライバ実装などの場面でカーネルモジュールの開発をする際には、原則としてカーネルモジュールを動作させる環境とビルドする環境のカーネルのバージョンを揃える必要がある。
しかし開発過程において、動作させる環境と異なる環境で開発を行いたい場面が出てくるかもしれない。(使用しているディストリビューションの種類などが違えば、環境をまったく同じにするのは困難である)
そのような際に、カーネルのバージョンの異なる環境で開発したカーネルモジュールを、他の環境で動かすためのテクニックを紹介する。
本記事の内容はあくまでも開発の過程においての利便性のための工夫であり、システムが壊れることが許されない本番環境での使用は推奨しません。
また本記事に掲載している行為によりシステムの環境を壊してしまった際の責任を、筆者は一切負いません。
ご了承ください。
!!!
後述するが本記事では、vermagicによる整合性検証をパスするための方法を解説する。
カーネルモジュールの整合性検証
参考文献 : vermagic と modversions に関する覚え書き
Linuxのカーネルモジュールの整合性検証の仕組み
カーネルモジュールをカーネルにインストールする際には、モジュール自体がビルドされたカーネルのバージョンと、今から動作させようとしている環境のカーネルのバージョンが一致しているかのチェックが行われ、一致しない場合はインストールできないようになっている。
その検証にはvermagicによる検証とmodversionsによる検証があり、どちらが行われるかはカーネルコンパイル時のconfigで決まる(らしい)。
本記事ではvermagicの検証について扱っている。
詳細は上記2つの記事を参照されたい。
modversionsによる検証についての情報も記載されている。
vermagic
modinfo <モジュール名>
で確認することができる。
カーネルコンパイル時に設定されている主な設定値を文字列化したものが入っている。
デフォルトでvermagicに入る文字列は、以下のヘッダファイルで定義されている。
https://elixir.bootlin.com/linux/v6.6.4/source/include/linux/vermagic.h#L42
#define VERMAGIC_STRING \
UTS_RELEASE " " \
MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \
MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS \
MODULE_ARCH_VERMAGIC \
MODULE_RANDSTRUCT
vermagicの検証をパスさせる方法
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
このようなコマンドでカーネルモジュールをビルドすると、<モジュール名>.mod.c
というファイルができあがる。このファイルにはモジュールの依存関係や、カーネルがモジュールを正しくロードして管理するために必要な情報が含まれている。
このファイルの中に、MODULE_INFOマクロにてvermagicを定義している箇所がある。
MODULE_INFO(vermagic, VERMAGIC_STRING);
VERMAGIC_STRINGは前節で紹介した、デフォルトでvermagicに入る文字列である。
この部分を、
MODULE_INFO(vermagic, "versionX");
このように任意の文字列に置き換えて再びmakeを行うことで、任意のvermagicを持ったカーネルモジュールのオブジェクトファイルを生成することができる。
ここを動作させる環境のカーネルバージョンに合った文字列にすることで、異なる環境でビルドしたカーネルモジュールを使うことができる。
動作確認
こちらの記事の要領でサンプルのカーネルモジュールを作る流れの中で、本記事で紹介したvermagic改変の動作確認を簡単に行うことができます。
とても簡単にカーネルモジュールを動かすことができるので、興味のある方はぜひ試してみてください。
(上記のmakeコマンドもこの記事のものです。)
組み込みLinuxデバイスドライバの作り方 (1)