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

8.10.3. カーネルの設定

次の段階で、必要性に応じてカーネルを設定します。完全な手順はその目標に依存します。
より最近のカーネルのバージョンを再コンパイルする場合 (おそらく追加的パッチを適用する場合)、その設定は Debian の提案する設定と可能な限り似たものになるでしょう。この場合、すべてを最初から再設定するのではなく、/boot/config-version ファイル (ここで version は現在使っているカーネルで、uname -r コマンドでわかります) をカーネルソースに含まれるディレクトリ内の .config ファイルにコピーするだけで十分です。
$ cp /boot/config-4.9.0-3-amd64 ~/kernel/linux-source-4.9/.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 環境変数を連結したものです。パッケージバージョンは version に規則正しく増え続けるリビジョン番号 (.version に保存されています) を付け加えたものになります。ただし、KDEB_PKGVERSION 環境変数を使えばパッケージバージョンを上書きすることも可能です。
$ make deb-pkg LOCALVERSION=-falcot KDEB_PKGVERSION=$(make kernelversion)-1
[...]
$ ls ../*.deb
../linux-headers-4.9.30-ckt4-falcot_4.9.30-1_amd64.deb
../linux-image-4.9.30-ckt4-falcot_4.9.30-1_amd64.deb
../linux-image-4.9.30-ckt4-falcot-dbg_4.9.30-1_amd64.deb
../linux-libc-dev_4.9.30-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.12-0.1) を設定しています ...
Loading new xtables-addons-2.12 DKMS files...
Building for 4.9.0-3-amd64
Building initial module for 4.9.0-3-amd64
Done.

xt_ACCOUNT:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/4.9.0-6-amd64/updates/dkms/
[...]
DKMS: install completed.
$ sudo dkms status
xtables-addons, 2.12, 4.9.0-3-amd64, x86_64: installed
$ sudo modinfo xt_ACCOUNT
filename:       /lib/modules/4.9.0-3-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-* パッケージの形で配布しますが、安定版でそれをすることはめったにありません (公式の上流カーネルにマージされなかったなどの理由によりパッチを配布することもあります)。これらのパッケージは /usr/src/kernel-patches/ ディレクトリにファイルをインストールします。
インストール済みパッチをカーネルに適用するには、ソースディレクトリの中で patch コマンドを使い、上で述べた通り、カーネルのコンパイルを始めてください。
$ cd ~/kernel/linux-source-4.9
$ make clean
$ zcat /usr/src/kernel-patches/diffs/grsecurity2/grsecurity-3.1-4.9.11-201702181444.patch.gz | patch -p1
与えられたパッチがカーネルのどのバージョンでも動作するとは限らないことに注意してください。さらに、カーネルソースにパッチを適用する際に、patch が失敗することもあります。エラーメッセージが表示され、失敗に関する詳細が表示されるでしょう。この場合、そのパッチの Debian パッケージで利用できる文書 (/usr/share/doc/linux-patch-*/ ディレクトリに含まれます) を参照してください。多くの場合、メンテナはそのパッチがどのカーネルバージョンを対象にしたものかを書いています。