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 特有の変更が含まれます。
The remainder of this section focuses on the 4.19 version of the Linux kernel, but the examples can, of course, be adapted to the particular version of the kernel that you want.
We assume the linux-source-4.19 package has been installed. It contains /usr/src/linux-source-4.19.tar.xz, a compressed archive of the kernel sources. You must extract these files in a new directory (not directly under /usr/src/, since there is no need for special permissions to compile a Linux kernel): ~/kernel/ is appropriate.
$ mkdir ~/kernel; cd ~/kernel
$ tar -xaf /usr/src/linux-source-4.19.tar.xz

8.10.3. カーネルの設定

次の段階で、必要性に応じてカーネルを設定します。完全な手順はその目標に依存します。
より最近のカーネルのバージョンを再コンパイルする場合 (おそらく追加的パッチを適用する場合)、その設定は Debian の提案する設定と可能な限り似たものになるでしょう。この場合、すべてを最初から再設定するのではなく、/boot/config-version ファイル (ここで version は現在使っているカーネルで、uname -r コマンドでわかります) をカーネルソースに含まれるディレクトリ内の .config ファイルにコピーするだけで十分です。
$ cp /boot/config-4.19.0-5-amd64 ~/kernel/linux-source-4.19/.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.19.37-falcot_4.19.37-1_amd64.deb
../linux-image-4.19.37-falcot_4.19.37-1_amd64.deb
../linux-libc-dev_4.19.37-1_amd64.deb

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

Some modules are maintained outside of the official Linux kernel. To use them, they must be compiled alongside the matching kernel. A number of common third party modules are provided by Debian in dedicated packages, such as vpb-driver-source (extra modules for Voicetronix telefony hardware) or leds-alix-source (driver of PCEngines ALIX 2/3 boards).
These packages are many and varied, apt-cache rdepends module-assistant$ can show the list provided by Debian. However, a complete list isn't particularly useful since there is no particular reason for compiling external modules except when you know you need it. In such cases, the device's documentation will typically detail the specific module(s) it needs to function under Linux.
For example, let's look at the dahdi-source package: after installation, a .tar.bz2 of the module's sources is stored in /usr/src/. While we could manually extract the tarball and build the module, in practice we prefer to automate all this using DKMS. Most modules offer the required DKMS integration in a package ending with a -dkms suffix. In our case, installing dahdi-dkms is all that is needed to compile the kernel module for the current kernel provided that we have the linux-headers-* package matching the installed kernel. For instance, if you use linux-image-amd64, you would also install linux-headers-amd64.
$ sudo apt install dahdi-dkms

[...]
Setting up xtables-addons-dkms (2.12-0.1) ...
Loading new xtables-addons-2.12 DKMS files...
Building for 4.19.0-5-amd64
Building initial module for 4.19.0-5-amd64
Done.

dahdi_dummy.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/4.19.0-5-amd64/updates/dkms/
[...]
DKMS: install completed.
$ sudo dkms status
dahdi, DEB_VERSION, 4.19.0-5-amd64, x86_64: installed
$ sudo modinfo dahdi_dummy
filename:       /lib/modules/4.19.0-5-amd64/updates/dkms/dahdi_dummy.ko
license:        GPL v2
author:         Robert Pleh <robert.pleh@hermes.si>
description:    Timing-Only Driver
[...]

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-*/ ディレクトリに含まれます) を参照してください。多くの場合、メンテナはそのパッチがどのカーネルバージョンを対象にしたものかを書いています。