Linuxのカーネルのコンパイル

パッチの適用などによりカーネルのソースコードに編集を行った場合、これをコンパイルする必要がある。

カーネルのソースコード配置

カーネルのソースコードは、カーネルソースとカーネルヘッダに大別される。

カーネルヘッダ(*.h)は、モジュール作成時に他のモジュールのインタフェースのみを参照するために用いるものである。
カーネルソース(*.c)は、モジュールのインタフェースの実装を記述する部分である。
この実装は、呼び出し元モジュールがカーネルヘッダに定義されたインタフェースを通じて動的にリンクされ、処理を実行される。

オブジェクト指向に共通する部分の多いこの技は、カーネルモジュールという仕組みを実現する上で重要な役割を担っている。
モジュールとモジュールを動的にリンクさせることができるため、モジュールごとに複数のバージョンを持ちメンテナンスを行うことを可能とする。

これらのソースコードは、ディストリビューションのポリシーによって配置される位置は異なるが、RedHat系ディストリビューションの場合、以下の通り、「/usr/src/kernels/(カーネルバージョン + アーキテクチャ)」へ配置される。
(※「/usr/src/linux」へシンボリックリンクが張られることがあるため、LPIC試験ではこのディレクトリを格納ディレクトリとしている。)

以下、ディレクトリ内の一覧情報である。

# ls /usr/src/kernels/2.6.23.17-88.fc7-i686/
Makefile  Module.symvers  System.map  arch  block  crypto  drivers  
fs  include  init  ipc  kernel  lib  mm  net  scripts  security  sound  usr


ファイル名 内容
Makefile カーネルコンパイルのコンフィギュレーション設定を行うためのファイル。
.config カーネル自体の設定ファイル。
System.map カーネルのシンボルのメモリ上での配置位置(アドレス)を持つ。コンパイル後に生成されるため、デフォルトで存在しない。

ディレクトリ名 内容
arch i386などのアーキテクチャ依存のコード。
block ブロックディバイス関連のコード
crypto 暗号化・復号関連のアルゴリズムのコード
drivers ディバイスドライバ関連のコード
fs ファイルシステム関連のコード
include ヘッダファイル
init 初期化関連のコード
ipc SystemV互換のプロセス間通信関連のコード
kernel カーネル機能関連のコード
lib モジュール関連のコード。
mm メモリ管理機能関連のコード。(→Memory Management)
net ネットワークプロトコル関連のアルゴリズム等のコード
scripts 先述したpatch-kernel等、カーネル再構築の補助関連のスクリプト
security セキュリティ関連のコード
sound サウンド関連のコード


カーネルコンフィギュレーションの反映

カーネルコンフィギュレーションが記録された.configファイルは、ディレクトリ「/usr/src/kernels/(カーネルバージョン + アーキテクチャ)」へ配置される。カーネルコンフィギュレーションには、カーネルの機能を、カーネルベースへ組み込むか、カーネルモジュールにするか、組み込まないか、といった設定情報が記述されている。

これは、直接vi等を用いて編集することが可能であるが、makeコマンドを用いるとより効率的に行える。

# cd /usr/src/kernels/(カーネルバージョン + アーキテクチャ)
# make config

  • Y - カーネルベースへ組み込む
  • M - カーネルモジュール(ローダブルモジュール)化する
  • N - 組み込まない

カーネルコンフィギュレーションは大量である。(2.6.23.17-88.fc7-i686でも約3500行ある。)
そのため、新しいカーネルコンフィギュレーションへ古いコンフィギュレーションを一から再設定するのは、負荷が大きい。

この課題は、「make oldconfig」の実行により解決される。
これを実行すると、古い設定情報をそのまま流用することが可能となる。

# cd /usr/src/kernels/(カーネルバージョン + アーキテクチャ)
# cp /boot/config-2.6.23.17-88.fc7 .config
# make oldconfig

カーネルコンフィギュレーションの設定ファイル

設定ファイル「.config」は、カーネルソースコードが配置されているディレクトリ以下に配置される。
コマンド「make」実行時の実行プロセスについては、同ディレクトリに配置された設定ファイル「Makefile」を元に実行されるが、makeのコンパイル対象となるカーネルのソースコードへ様々な設定情報を与えるのは、.configの役割である。
先述したコマンド「make config」や「make oldconfig」によって設定された情報は、このファイルへ書き込まれる。


カーネルのコンパイルとインストール


以下のコマンドを実行すると、カーネルモジュールのコンパイルが行われる。

# make
  CHK     include/linux/version.h
  CHK     include/linux/utsrelease.h
・・・(略)

これにより、カーネルのバイナリプログラムが生成される。
次にこれを、適切なディレクトリへ配置する。
この際、ユーティリティ「make」は、Makefileの先頭数行を参照するため、注意が必要である。

# head -4 Makefile
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 23
EXTRAVERSION = .17-88.fc7

上記の設定であった場合、「/lib/modules/2.6.23.17-88.fc7」へ配置されることになる。
設定が確かであれば、以下のコマンドによりディレクトリへの配置を行う。

# make modules_install

コマンド実行後、いよいよインストールを行う。
以下のコマンドでこれを行える。

# make install
sh /usr/src/kernels/2.6.23.17-88.fc7-i686/arch/i386/boot/install.sh 2.6.23.17-88.fc7 arch/i386/boot/bzImage System.map "/boot"
・・・(略)

インストールでは、/bootにカーネルイメージを配置する。
この際、initrd(初期RAMディスク)が必要であれば、これを生成して配置する。
また、liloやgrubといったブートローダへ、このカーネルイメージへアクセスするためのエントリを追加する。

これらの作業は必要に応じて、手作業によって行うことも可能である。
例えば、/bootにカーネルイメージを配置するのみで良いのであれば、以下のようなコマンドによって行える。

# cp /usr/src/(カーネルバージョン + アーキテクチャ)/arch/(アーキテクチャ)/boot/bzImage \
/boot/vmlinuz-(バージョン)
# cp /usr/src/(カーネルバージョン + アーキテクチャ)/System.map /boot/System.map-(カーネルバージョン + アーキテクチャ)

「make」を実行した際にカーネルイメージはbzImage形式で圧縮が行われており、「make modules_install」により上記のディレクトリに配置されている。これを、/boot上へ適切な名称へ変更して配置する。また同時に、コンパイル時に生成されたSystem.mapも適切な位置に配置する。

その他については、「初期RAMディスク」「ブートローダ」を参照して頂きたい。

  • 最終更新:2009-12-26 02:49:53

このWIKIを編集するにはパスワード入力が必要です

認証パスワード