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 が第 6.2.6 節「複数ディストリビューションの利用」の説明に従って設定されている場合、大きな危険性はないと言えます)。Debian のカーネルソースパッケージに含まれるソースコードは Linus Torvalds さんとカーネル管理者が公開したソースコードと完全に一致するわけではないことに注意してください。さらに、すべてのディストリビューションと同様に、Debian もまたカーネルソースに数多くのパッチを適用します。このパッチは今後 Linux の上流開発版に含まれるかもしれません (含まれない場合もあります)。これらの変更には、新しいカーネルバージョンに追加された修正/機能/ドライバの移植、まだ上流開発の Linux ツリーに (完全に) マージされていない新機能、場合によっては Debian 特有の変更、が含まれます。
この節のこれ以降の説明では、Linux カーネルのバージョン 3.16 を例に挙げます。この例はもちろん、他のカーネルの特定のバージョンにも適用できます。
linux-source-3.16 パッケージがインストール済みと仮定します。linux-source-3.16 パッケージには、カーネルソースの圧縮アーカイブである /usr/src/linux-source-3.16.tar.xz が含まれます。この圧縮アーカイブを新しいディレクトリに展開してください (/usr/src/ の下のディレクトリに展開しないよう注意してください。なぜなら、Linux カーネルをコンパイルするのに特別なパーミッションは要らないからです)。すなわち ~/kernel/ に展開することが適切です。
$ mkdir ~/kernel; cd ~/kernel
$ tar -xaf /usr/src/linux-source-3.16.tar.xz

8.10.3. カーネルの設定

次の段階で、必要性に応じてカーネルを設定します。完全な手順はその目標に依存します。
より最近のカーネルのバージョンを再コンパイルする (おそらく追加的パッチを適用する) 場合、その設定は Debian の提案する設定と可能な限り似たものになるでしょう。この場合、すべてを最初から再設定するのではなく、/boot/config-version ファイル (ここで version は現在使っているカーネルで、uname -r コマンドでわかります) をカーネルソースに含まれるディレクトリ内の .config ファイルにコピーするだけで十分です。
$ cp /boot/config-3.16.0-4-amd64 ~/kernel/linux-source-3.16/.config
設定を変更する必要がなければ、この節を中止して、第 8.10.4 節「パッケージのコンパイルとビルド」に進むことも可能です。一方で、設定を変更する必要があったり、最初からすべてを再設定する場合、カーネルを設定する時間を取らなければいけません。カーネルソースディレクトリには、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 (Debian の配布しているカーネルソースからカーネルをビルドする場合、このパッケージが必要な場合があります)、カーネルイメージとモジュールのデバッグシンボルを含む linux-image-version-dbg、GNU glibc などのユーザ空間ライブラリに関連するヘッダを含む linux-libc-dev が生成されます。
ここで version は上流開発バージョン (Makefile 中の VERSIONPATCHLEVELSUBLEVELEXTRAVERSION が定義する)、LOCALVERSION 設定パラメータ、LOCALVERSION 環境変数を連結したものです。パッケージバージョンは、KDEB_PKGVERSION 環境変数を使ってそれを上書きする場合を除き、通例増え続けるリビジョン番号 (.version に保存されている) を追加しただけで後は同じバージョン文字列を再利用します。
$ make deb-pkg LOCALVERSION=-falcot KDEB_PKGVERSION=$(make kernelversion)-1
[...]
$ ls ../*.deb
../linux-headers-3.16.7-ckt4-falcot_3.16.7-1_amd64.deb
../linux-image-3.16.7-ckt4-falcot_3.16.7-1_amd64.deb
../linux-image-3.16.7-ckt4-falcot-dbg_3.16.7-1_amd64.deb
../linux-libc-dev_3.16.7-1_amd64.deb

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

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

[...]
xtables-addons-dkms (2.6-1) を設定しています ...
Loading new xtables-addons-2.6 DKMS files...
First Installation: checking all kernels...
Building only for 3.16.0-4-amd64
Building initial module for 3.16.0-4-amd64
Done.

xt_ACCOUNT:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/3.16.0-4-amd64/updates/dkms/
[...]
DKMS: install completed.
$ sudo dkms status
xtables-addons, 2.6, 3.16.0-4-amd64, x86_64: installed
$ sudo modinfo xt_ACCOUNT
filename:       /lib/modules/3.16.0-4-amd64/updates/dkms/xt_ACCOUNT.ko
license:        GPL
alias:          ipt_ACCOUNT
author:         Intra2net AG <opensource@intra2net.com>
description:    Xtables: per-IP accounting for large prefixes
[...]

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

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