Product SiteDocumentation Site

8.10. カーネルのコンパイル

Debian の提供するカーネルには、既存のハードウェア構成の広い領域をカバーするために、最も多くの考え得る機能およびドライバが含まれています。このため、一部のユーザは、本当に必要なものだけを含める目的で、カーネルを再コンパイルする事を好みます。カーネルを再コンパイルする理由は 2 つあります。1 つ目は、メモリ消費量を最適化できるかもしれないからです。全く使われないカーネルコードは無駄にメモリを専有するため (カーネルコードは決してスワップ領域に「移動」されません、なぜなら、カーネルコードはスワップ領域を実際の RAM として使っているからです)、全システムのパフォーマンスを低下させます。2 つ目は、ローカルでコンパイルされたカーネルはセキュリティ問題の危険性を限定する事が可能だからです。カーネルコードのごく一部がコンパイルされ実行されます。
パッチでしか利用できない (標準的なカーネルのバージョンに含まれていない) 特定の機能を使いたい場合、カーネルの再コンパイルが必要です。

8.10.1. 紹介と必須条件

当然ながら、Debian はパッケージの形でカーネルを管理します。このやり方は伝統的にカーネルをコンパイルしてインストールしていた方法とは異なります。カーネルがパッケージ化システムの制御下にあるお陰で、カーネルを綺麗に削除したり、複数のマシンに配布できます。さらに、カーネルのパッケージに関連付けられたスクリプトのお陰で、ブートローダと initrd ジェネレータとの連動が自動化されます。
上流開発の Linux ソースには、カーネルの Debian パッケージをビルドするために必要なすべてが含まれています。しかし、Debian パッケージをビルドするのに必要なツールを確実に揃えるためには、build-essential のインストールが必要です。さらに、カーネルを設定する際に、libncurses5-dev パッケージが必要です。最後に、fakeroot パッケージを使えば、管理者権限を使わずに Debian パッケージを作成する事が可能になります。

8.10.2. ソースを入手

Debian システム上で便利に使えるプログラムと同様に、Linux カーネルソースはパッケージとして提供されています。Linux カーネルソースを手に入れるには、linux-source-version パッケージをインストールしてください。apt-cache search ^linux-source コマンドは Debian がパッケージ化した様々なカーネルバージョンを表示します。最新のバージョンは不安定版ディストリビューションで利用可能です: 大して危険性を伴わずに、カーネルの最新バージョンを入手可能です (特に APT が「複数ディストリビューションの利用」の説明に従って設定されている場合は)。Debian のカーネルソースパッケージに含まれるソースコードは Linus Torvalds さんとカーネル管理者が公開したソースコードと完全に一致するわけではないことに注意してください; すべてのディストリビューションと同様に、Debian もまたカーネルソースに数多くのパッチを適用します。このパッチは今後 Linux の上流開発版に含まれるかもしれません (含まれない場合もあります)。これらの変更には、新しいカーネルバージョンに追加された修正/機能/ドライバの移植、まだ上流開発の Linux ツリーに (完全に) マージされていない新機能、場合によっては Debian 特有の変更、が含まれます。
この節のこれ以降の説明では、Linux カーネルのバージョン 3.2 を例に挙げます。この例はもちろん、他のカーネルの特定のバージョンにも適用できます。
linux-source-3.2 パッケージがインストール済みと仮定します。linux-source-3.2 パッケージには、カーネルソースの圧縮アーカイブである /usr/src/linux-source-3.2.tar.bz2 が含まれます。この圧縮アーカイブを新しいディレクトリに展開してください (/usr/src/ の下のディレクトリに展開しないよう注意してください。なぜなら、Linux カーネルをコンパイルするのに特別なパーミッションは要らないからです): ~/kernel/ が適切です。
$ mkdir ~/kernel; cd ~/kernel
$ tar -xjf /usr/src/linux-source-3.2.tar.bz2

8.10.3. カーネルの設定

次の段階で、必要性に応じてカーネルを設定します。完全な手順はその目標に依存します。
より最近のカーネルのバージョンを再コンパイルする (おそらく追加的パッチを適用する) 場合、その設定は Debian の提案する設定と可能な限り似たものになるでしょう。この場合、すべてを最初から再設定するのではなく、/boot/config-version ファイル (ここで version は現在使っているのカーネルで、uname -r コマンドでわかります) をカーネルソースに含まれるディレクトリ内の .config ファイルにコピーするだけで十分です。
$ cp /boot/config-3.2.0-4-amd64 ~/kernel/linux-source-3.2/.config
設定を変更する必要がなければ、この節を中止して、次の節に進む事が可能です。一方で、設定を変更する必要があったり、最初からすべてを再設定する場合、カーネルを設定する時間を取らなければいけません。カーネルソースディレクトリには、make target コマンドを呼び出して使う様々な専用のインターフェースがあります。ここで target は以下に説明するものの 1 つです。
make menuconfig は、階層構造でオプションを案内するテキストモードインターフェースをコンパイルして実行します (ここで libncurses5-dev パッケージが要求されます)。Space キーで選択されたオプションの値を変更します。Enter キーで画面の下部にある選択状態のボタンを押します; Select ボタンで選択されたサブメニューを返します; Exit ボタンで現在の画面を閉じて階層を一段階上に戻ります; Help ボタンで選択されたオプションの役割に関するより詳細な情報を表示します。矢印キーでオプションリストとボタンの間を移動します。設定プログラムを終了するには、メインメニューから Exit ボタンを選択してください。すると、このプログラムは変更を保存するよう提案します; 変更に満足なら、保存してください。
他のインターフェースも同様の機能を持っていますが、より現代的なグラフィカルインターフェースで機能します; make xconfig は Qt グラフィカルインターフェース、make gconfig は GTK+ を使います。make xconfig には libqt4-dev が必要で、make gconfig には libglade2-devlibgtk2.0-dev が必要です。
これらの設定インターフェースの内 1 つを使う場合、合理的なデフォルト設定から始めるのが良いアイディアです。カーネルのデフォルト設定は arch/arch/configs/*_defconfig に置かれています。この設定ファイルを適切な場所に置くには、make x86_64_defconfig (64 ビット PC の場合) や make i386_defconfig (32 ビット PC の場合) などのコマンドを使います。

8.10.4. パッケージのコンパイルとビルド

カーネル設定の準備が完了したら、make deb-pkg で 5 つの Debian パッケージが生成されます: カーネルイメージと関連モジュールを含む linux-image-version、外部モジュールのビルドに必要なヘッダファイルを含む linux-headers-version、一部のドライバに必要なファームウェアファイルを含む linux-firmware-image-version、カーネルイメージとモジュールのデバッグシンボルを含む linux-image-version-dbg、GNU glibc 等のユーザ空間ライブラリに関連するヘッダを含む linux-libc-dev です。
ここで version は上流開発バージョン (Makefile 中の VERSIONPATCHLEVELSUBLEVELEXTRAVERSION が定義する)、LOCALVERSION 設定パラメータ、LOCALVERSION 環境変数を連結したものです。パッケージバージョンは、KDEB_PKGVERSION 環境変数を使ってそれを上書きする場合を除き、通例増え続けるリビジョン番号 (.version に保存されている) を追加しただけで後は同じバージョン文字列を再利用します。
$ make deb-pkg LOCALVERSION=-falcot KDEB_PKGVERSION=1
[...]
$ ls ../*.deb
../linux-firmware-image-3.2.46-falcot_1_amd64.deb
../linux-headers-3.2.46-falcot_1_amd64.deb
../linux-image-3.2.46-falcot_1_amd64.deb
../linux-image-3.2.46-falcot-dbg_1_amd64.deb
../linux-libc-dev_1_amd64.deb

8.10.5. 外部モジュールのコンパイル

幾つかのモジュールは公式の Linux カーネルの外で保守されています。このようなモジュールを使うには、適合するカーネルと一緒にモジュールをコンパイルしなければいけません。Debian は専用パッケージの形で数多くのサードパーティ製モジュールを配布しています。例えば、virtualbox-source (VirtualBox 仮想化ソリューションのカーネルサポート)、oss4-source (Open Sound System、代替音声ドライバ) などです。
これらの外部パッケージは多種多様で、ここですべてを挙げることはできません; apt-cache search source$ コマンドは検索範囲を狭める事ができます。しかしながら、完全なリストは特に有益ではありません。なぜなら、外部モジュールが必要であるとわかっている場合を除いて、外部モジュールをコンパイルする特別な理由は無いからです。そのような場合、デバイスの文書では、Linux 下でそのデバイスを機能させるために必要な特定のモジュールについて詳しく説明されている場合が多いです。
例えば、virtualbox-source パッケージを見てみましょう: インストールの後、モジュールのソース .tar.bz2/usr/src/ に保存されます。手作業でこの tarball を展開してモジュールをビルドする事も可能ですが、実際のところ、DKMS を使ってビルド作業を自動化する方が良いです。ほとんどのモジュールは、パッケージ名が -dkms サフィックスで終わるパッケージの中で、DKMS 統合に必要な要素を提供します。インストール済みカーネルに対応する linux-headers-* パッケージを持っているならば、virtualbox-dkms をインストールする事が現在のカーネル用のカーネルモジュールをコンパイルするのに必要なすべてです。例えば、linux-image-amd64 を使っている場合、linux-headers-amd64 をインストールする必要があります。
$ sudo apt-get install virtualbox-dkms

[...]
Loading new virtualbox-4.1.18 DKMS files...
First Installation: checking all kernels...
Building only for 3.2.0-4-amd64
Building initial module for 3.2.0-4-amd64
Done.

vboxdrv:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/3.2.0-4-amd64/updates/dkms/
[...]
DKMS: install completed.
$ sudo dkms status
virtualbox, 4.1.18, 3.2.0-4-amd64, x86_64: installed
virtualbox-guest, 4.1.18, 3.2.0-4-amd64, x86_64: installed
$ sudo modinfo vboxdrv
filename:       /lib/modules/3.2.0-4-amd64/updates/dkms/vboxdrv.ko
version:        4.1.18_Debian (0x00190000)
license:        GPL
description:    Oracle VM VirtualBox Support Driver
[...]

8.10.6. カーネルパッチの適用

十分に成熟していなかったり、カーネルメンテナとの意見の不一致が原因で、標準的なカーネルに含まれない機能もあれば、カーネルソースに対して自由に適用できるようにするために、パッチとして配布される機能もあります。
Debian は幾つかのパッチを linux-patch-*kernel-patch-* パッケージの形で配布します (例えば、linux-patch-grsecurity2 はカーネルのセキュリティポリシーを厳しくするパッチです)。これらのパッケージは /usr/src/kernel-patches/ ディレクトリにファイルをインストールします。
インストール済みパッチをカーネルに適用するには、ソースディレクトリの中で patch コマンドを使い、上で述べたとおり、カーネルのコンパイルを始めてください。
$ cd ~/kernel/linux-source-3.2
$ make clean
$ zcat /usr/src/kernel-patches/diffs/grsecurity2/grsecurity-2.9.1-3.2.21-201206221855.patch.gz | patch -p1
$ make deb-pkg LOCALVERSION=-grsec
与えられたパッチがカーネルのどのバージョンでも動作するとは限らないことに注意してください; カーネルソースにパッチを適用する際に、patch が失敗する事もあります。エラーメッセージが表示され、失敗に関する詳細を提示するでしょう; この場合、そのパッチの Debian パッケージで利用可能な文書 (/usr/share/doc/linux-patch-*/ ディレクトリに含まれます) を参照してください。多くの場合、メンテナはそのパッチがどのカーネルバージョンを対象にしたものかを書いています。