Kernelを再構築する

カーネルの再構築をやったことがないサーバーの管理者などいるであろうか。・・・いるだろう。最近のカーネルはよく使うドライバは組み込まれていたり、モジュールとしてコンパイル済みであったりして、再構築の必要を感じない方も結構いるのが現状ではないか。しかし、実はそんなに難しい作業ではないので、現在のカーネルの最適化を目指したり、必要に迫られてやらなければならないときのために、何度かトライしておくとよいと思う。ここでは最初に一般的な再構築手順、それからDebian流の便利な方法を紹介する。

カーネルソースのインストール
コンパイルの準備
コンパイル手順
カーネルのコピーとliloの編集
Debian 流のカーネル再構築

 

カーネルソースのインストール

ソースもaptでひっぱってこれる。まずは下記のようにコマンドを一発かましてみる。

# apt-get install kernel-source

すると次のように取得できるカーネルソースの一覧が出力される。この中で使いたいソースを選べばよい。

Package kernel-source is a virtual package provided by:
  kernel-source-2.4.18-hppa 12.1
  kernel-source-2.4.17-hppa 32.1
  kernel-source-2.4.16 2.4.16-1
  kernel-source-2.4.14 2.4.14-1
  kernel-source-2.4.10 2.4.10-1
  kernel-source-2.2.22 2.2.22-1
  kernel-source-2.4.18 2.4.18-14
  kernel-source-2.4.17-ia64 011226.14
  kernel-source-2.4.17 2.4.17-1woody1
  kernel-source-2.2.20 2.2.20-5woody2
You should explicitly select one to install.
E: Package kernel-source has no installation candidate

今回はkernel-source-2.4.18を選んだ

# apt-get install kernel-source-2.4.18


△top

 

コンパイルの準備

/usr/srcに移動すると、そこに kernel-source-2.4.18.tar.bz2 がある。

# cd /usr/src
# ls /usr/src/
kernel-source-2.4.18.tar.bz2

これを展開する。

# tar jxvf kernel-source-2.4.18.tar.bz2

カーネルソース名でディレクトリができるので、それに対して linux という名前のシンボリックリンクを作る。

# ln -s kernel-source-2.4.18 linux
# ls -F
kernel-source-2.4.18.tar.bz2 kernel-source-2.4.18/ @linux

次に、展開したディレクトリに移動し、Makefileを編集する。ここでお勧めしたいのが、最初から4行目のEXTRAVERSIONに自分のわかるサフィックス(たとえばイニシャルに数字など)をつけることである。これは既存のカーネルのバージョンと重複を避けるためである。

もし同じ名前だと、モジュールがインストールされるディレクトリ名が/lib/modules/カーネルのバージョン名/ となるので、既存のモジュールのディレクトリを上書きしてしまう恐れがある。これからインストールするのがカスタムカーネルであることを明示するためにも、下記の例のように記述しておこう。

# cd linux
# emacs Makefile

VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 18
EXTRAVERSION = -eu1   ← ここを編集
               ~~~~~

また、次のカーネル・コンフィギュレーションで make menuconfig を使用するなら libncurses5-dev を忘れずにインストールしておく。これがないと make menuconfig が起動すらしない。

apt-get install libncurses5-dev


△top

 

コンパイル手順

いろいろ意見の持つ方もあろうが、下記の手順を実行するのが定石といえるだろう。make menuconfig で有効にする内容は再構築する目的によって異なるので、特に言及しないが、注意して有効にすべきは、自分が使用しているマシンのチップセット、ネットワークコントローラ、使用するファイルシステム、ファイルシステムの中にある言語サポート(Japanese charsets)である。

逆に自分のマシンが明らかに必要としていないデバイスは無効にしてしまってもよいし、モジュールにしてしまってもよい。特に絶対に使わないと分かっているチップセットのドライバ、USB関連の機能、該当しないNICのドライバ、サーバー用途ならマルチメディア関係の項目を無効にすると、標準のカーネルより明らかに小さなカーネルを作ることができる。

# make mrproper               → 設定の初期化
# make menuconfig             → コンフィギュレーション
# make dep                    → 依存関係の処理
# make clean                  → 中間ファイルの削除
# make bzImage                → カーネルのコンパイル
# make modules                → モジュールのコンパイル
# make modules_install        → モジュールのインストール


△top

 

カーネルのコピーとliloの編集

新しく作成されたカーネルは /usr/src/linux/arch/i386/boot/bzImage として存在している。これを /boot に名前を変えてコピーする。

# cp arch/i386/boot/bzImage /boot/vmlinuz-2.4.18-eu1

デビアンの流儀(?)に従って、/(ルート)ファイルシステムにカーネルへのシンボリックを貼る

# ln -s /boot/vmlinuz-2.4.18-eu1 /vmlinuz-eu1

次はlilo.confの編集だ。最後のimageブロックに追記した部分が、新しいカーネルで起動する設定となっている。
(注意:/etc/lilo.conf の結果は環境によって左右される。今まで使っていたデフォルトカーネルとそのラベル名、コメントの有り無しなど。)

# emacs /etc/lilo.conf

lba32
boot=/dev/hda
root=/dev/hda1
install=/boot/boot-menu.b
map=/boot/map
delay=20
vga=normal

default=LinuxNew
image=/vmlinuz
        label=Linux
        read-only

# 以下カスタムカーネルの記述を追記
image=/vmlinuz-eu1
        label=LinuxNew
        read-only
        optional

正常に起動しなかったときに以前のカーネルを選択できるよう、下記の記述もdelayの次行あたりに追記しておく。まあ、これを書かなくても、起動時にshiftを押すと、どのカーネルで起動するかを選べるが。

prompt
timeout=50

変更を保存したら、liloコマンドを忘れずに

# /sbin/lilo
Warning: Int 0x13 function 8 and function 0x48 return different
head/sector geometries for BIOS drive 0x80
Added Linux
Added LinuxNew *

上記のワーニングが出ることが多数報告されている。liloのブートセクタの情報と、BIOSの持っている情報が異なっているということだが、たいていは再構築したカーネルで正常にリブートするので、気にしなくてもよいようだ。

# reboot

正常に起動すればOKだ。もし正常に起動しなかったり、使えない機能が出てきてしまっていたら、以前のカーネルで起動し、うまくいくまで何度でもやり直そう。


△top

 

Debian 流のカーネル再構築

私はこれまでずっと、上記のように手動で作業していたわけだが、ある時 Debian でカーネル再構築するにあたって、大変便利な方法があるということを知った。make-kpkg というコマンドで、カーネルのdebパッケージが自動的にできてしまう。さすがDebian!

その大変便利なコマンドを利用するには、kernel-package というパッケージをインストールする必要がある。

# apt-get install kernel-package

カーネルソースのインストールから、make menuconfig までは、手順はまったく同じである。その後のコンパイルからが、Debianツールの本領発揮である。make menuconfig が終わったら、下記のコマンドを実行する。

# make-kpkg clean
# make-kpkg --revision=031210 kernel-image

make-kpkg --revision=031210 kernel-image 。このコマンドラインでは、カーネルのバージョンのあとにリビジョン番号を付加してカーネルイメージをコンパイルする。(というか deb ファイルにこのリビジョン番号が付けられる)。リビジョンは数字のほかに" . "(ドット)と " + " (プラス)が使用できる。

ただ、このリビジョン番号は、後ほどカーネルイメージがインストールされたところを見ると、Makefileの4行目 EXTRAVERSION のパラメータに指定したときのような、イメージファイルやモジュールのインストールディレクトリの区別になるようなものではないので、この方法でも EXTRAVERSION に短く指定しておくことをお勧めする。(たとえばイニシャルと数字など。私の場合だったら -eu1 のような感じで)

コンパイルが終わると、/usr/src に コンパイル済みカーネルの deb パッケージができている。

# cd /usr/src
# ls -F
kernel-source-2.4.18/         linux@
kernel-image-2.4.18-eu1_031210_i386.deb  kernel-source-2.4.18.tar.bz2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~これ

これを dpkg コマンドでインストールすればよい。カーネルイメージのコピー、モジュールのインストール、lilo.confの書き換え、lilo のインストール・・・すべてをやってくれる。

# dpkg -i kernel-image-2.4.18-eu1_031210_i386.deb

すると下記のようなメッセージが表示される。ブートディスクの作成と、lilo のインストールについて質問されるので、自分の都合にしたがって答える。

(kernel-image-2.4.18-eu1_031210_i386.deb から) kernel-image-2.4.18 を展開しています...
kernel-image-2.4.18-eu1 (031210) を設定しています ...
A new kernel image has been installed, and usually that means
that some action has to be taken to make sure that the new
kernel image is used next time the machine boots. Usually,
this entails running a ``bootloader'' like SILO, loadlin, LILO,
ELILO, QUIK, VMELILO, ZIPL, or booting from a floppy.   (Some
boot loader, like grub, for example, do not need to be run on
each new image install, so please ignore this if you are using
such a boot loader).

WARNING
If you are keeping another operating system or another version
of Linux on a separate disk partition, you should not have LILO
install a boot block now. Wait until you read the LILO documentation.
That is because installing a boot block now might make the other
system un-bootable. If you only want to run this version of Linux,
go ahead and install the boot block here. If it does not work, you
can still boot this system from a boot floppy.


Would you like to create a boot floppy now? [No]
You already have a LILO configuration in /etc/lilo.conf
Install a boot block using the existing /etc/lilo.conf? [Yes]
Testing lilo.conf ...
Testing successful.
Installing the partition boot sector...
Installation successful.

最後に 「Installation successful.」 とあるので、文字通り成功していることが分かる。liloの設定を確認し、どちらの新旧どちらのカーネルがデフォルトになっているか確認し、必要であれば default= を編集する。 image= で指定されているカーネルイメージは、/(ルート)直下に作成されたシンボリックリンクなので、どちらをさしているかを確認するとよい。今回の場合は、デフォルトで新しいカーネルで起動する形になっていた。
(注意:/etc/lilo.conf の結果は環境によって左右される。今まで使っていたデフォルトカーネルとそのラベル名、コメントの有り無しなど。)


# cat /etc/lilo.conf

lba32
boot=/dev/hda
root=/dev/hda1
install=/boot/boot-menu.b
map=/boot/map
delay=20
vga=normal
prompt
timeout=50

default=LinuxNew
image=/vmlinuz
        label=Linux
        read-only

image=/vmlinuz-eu1
        label=LinuxNew
        read-only
        optional

早速再起動をかけてみる。

# reboot

正常に起動できればOKだ。もし正常に起動しなかったり、使えない機能が出てきてしまっていたら、以前のカーネルで起動し、うまくいくまで何度でもやり直そう。


△top