私は_CentOS-6.5
_を使用しており、デフォルトのカーネルは_2.6.32-431.11.2.el6.x86_64
_です。 _2.6.32
_をダウンロードし、そのカーネルをビルドしました(_/lib/modules/2.6.32
_の下)。
単純な_hello world
_プログラムのモジュールを作成しました。このプログラムは、以下の場合に機能します。
Makefile:/lib/modules/$(Shell uname -r)/build
(デフォルトのカーネル)
_$ Sudo insmod hello.ko
$ dmesg
module inserted..
hello world..
_
私のプログラムは以下の場合には機能しません:
Makefile:_/lib/modules/3.2.32/build
_(新しく構築されたカーネル)
_$ Sudo insmod hello.ko
insmod: error inserting 'hello.ko': -1 Invalid module format
dmesg:
hello: disagrees about version of symbol module_layout
_
どちらの場合もmodprobe
を試しましたが、以下のエラーが表示されています
_FATAL: Module hello not found.
_
モジュールを_2.6.32
_カーネルでどのようにコンパイルしますか?
Linuxカーネルには、バージョンごとだけでなく、コンパイルオプションによってもレイアウトが異なるデータ構造が含まれています。結果として、カーネルモジュールをコンパイルするときは、カーネルソースからのヘッダーファイルだけでなく、カーネルコンパイル中に生成されるいくつかのヘッダーファイルも必要になります。カーネルソースを解凍するだけでは不十分です。
CONFIG_MODVERSIONS
で構築されたカーネルでは、バージョン番号が異なる場合がありますが、データ構造のレイアウトは同じである必要があります。このオプションは、Ubuntuカーネルでアクティブ化されます。このオプションでは、ヘッダーに加えて、モジュールを適切なModule.symvers
ファイルに対してコンパイルする必要があります。 CentOSは、ほとんどのディストリビューションと同様に、コンパイル結果のカーネルヘッダーと同じパッケージにこのファイルを含めます。 CentOSカーネルヘッダーパッケージはkernel-headers
と呼ばれます。コンパイルするカーネルと一致するバージョンをインストールしてください。 CentOSドキュメントの カーネルパッケージの概要 およびwikiの 完全なカーネルソースは必要ありません も参照してください。
CONFIG_MODVERSIONS
なしでビルドされたカーネル(独自のカーネルをコンパイルした場合など)では、モジュールをロードするときのチェックは単純なバージョンチェックです。解凍されたカーネルソースを取得し、実行中のカーネルのコンパイル中に使用された.config
をコピーして、make modules_prepare
を実行できます。カーネルに加えたパッチがバイナリ互換性に影響を与えないことを確認する責任はあなたにあります。
2.6.32カーネルはどこでダウンロードしましたか?
CentOSを使用する場合、RedHatはパッチが適用されたカーネルを使用するため、CentOSリポジトリからカーネルのソース2.6.32-431.11.2.el6.x86_64
をインストールするだけです。また、構築するカーネルソースツリーの構成が、実行中のカーネルとまったく同じであることを確認してください。
通常、config-*
ディレクトリに/boot/
ファイルがあります。または、/proc/config.gz
から実行中のカーネルの構成を取得することもできます。
公式のCentOSHowTosを参照することもできます。