第8章 FreeBSD カーネルのコンフィグレーション

8.1. この章では

カーネルは FreeBSD オペレーティングシステムの中核をなすものです。 カーネルは、メモリ管理、セキュリティ制御の強制、ネットワーク、 ディスクアクセスなどを担っています。 FreeBSD の大部分は動的に構成することができるようになっていますが、 まだ、時にはカスタムカーネルを設定してコンパイルする必要があります。

この章では、以下のことを扱っています。

  • いつカスタムカーネルの構築が必要になるか。

  • ハードウェア一覧の作成方法。

  • カーネルコンフィグレーションファイルのカスタマイズの方法。

  • カーネルコンフィグレーションファイルから新しいカーネルを構築する方法。

  • 新しいカーネルのインストール方法。

  • うまく行かないときの問題解決法。

この章で表示されているすべてのコマンドは、root 権限で実行する必要があります。

8.2. なぜカスタムカーネルを作るか?

伝統的に、FreeBSD はモノリシック (monolithic) カーネルを使っていました。 このカーネルは、単一の巨大なプログラムで、 扱えるデバイスは固定されていて、 カーネルの振る舞いを変えたければ構築してコンピュータを再起動し、 新しいカーネルを動かさなれければなりませんでした。

今日では、FreeBSD カーネルのかなりの機能はモジュールに含まれるようになり、 必要に応じて動的にカーネルに組み込んだり外したりできるようになりました。 この移行により、 動作しているカーネルが新しいハードウェアに迅速に対応したり、 カーネルに新たな機能を取り入れられるようになります。 このようなカーネルは、モジュラ (modular) カーネルと呼ばれます。

しかしながら、 いまだにいくらかは静的にカーネルを構成する必要があります。 機能がカーネルとあまりに密接に結びついているため、 動的に組み込むことができない場合があるためです。 環境によっては、セキュリティの観点から、 カーネルモジュールを読み込んだり外すことができず、 必要となる機能を静的にカーネルにコンパイルしなければならない場合もあります。

システムに合わせたカーネルを構築することは、多くの場合、 高度な知識を持つ BSD ユーザが避けて通ることのできない通過儀礼です。 この作業は多くの時間を必要としますが、FreeBSD システムに利益をもたらします。 広範囲のハードウェアをサポートしなければならない GENERIC カーネルとは異なり、カスタムカーネルは、 使用しているコンピュータのハードウェアのみをサポートするように、 必要のない機能を省くことができます。これは、 次にあげるような利益をもたらします。

  • 素早く起動します。 カーネルはシステム上にあるハードウェアしか検出しないので、 システムの起動にかかる時間を短くできます。

  • メモリの消費量を減らすことができます。 システムに合わせたカーネルは、 使用しない機能やデバイスドライバを含まないので、 大抵 GENERIC カーネルより少ないメモリしか消費しません。 カーネルコードは常に物理メモリ上に存在し、 アプリケーションはその容量分のメモリを使用できないので、 これは重要なことです。 したがって、メモリが少ないシステムでは、 カーネルの再構築は重要です。

  • 追加のハードウェアをサポートします。 カスタムカーネルは、GENERIC カーネルに存在しないデバイスのサポートを追加することができます。

カスタムカーネルを構築する前に、再構築する理由を考えてください。 ある特定のハードウェアに対応する必要がある場合に、 そのハードウェアに対応するためのモジュールがすでに用意されていることがあります。

カーネルモジュールは /boot/kernel にあります。モジュールによっては kldload(8) により、 すでに実行中のカーネルに動的に読み込まれています。 ほとんどのカーネルドライバには、 読み込み可能なモジュールやマニュアルページが用意されています。 たとえば、ath(4) ワイヤレスイーサネットドライバのマニュアルページには以下のような記述があります。

Alternatively, to load the driver as a module at boot time, place the
following line in loader.conf(5):

    if_ath_load="YES"

/boot/loader.confif_ath_load="YES" を追加すると、 起動時にモジュールが読み込まれるようになります。

対応するモジュールが /boot/kernel に存在しないこともあります。 特定のサブシステムでは、ほとんど多くの場合存在しません。

8.3. システムのハードウェアについて知る

カーネルコンフィグレーションファイルの編集を始める前に、 コンピュータのハードウェア一覧を作成すると良いでしょう。 デュアルブートシステムでは、 現在インストールされている別のオペレーティングシステムの設定を調べることで、 一覧を作成できます。 たとえば、Microsoft® の デバイスマネージャ は、インストールされているデバイスに関する情報を持っています。

Microsoft® Windows® のバージョンによっては、 システム アイコンを使って、 デバイスマネージャ にアクセスできます。

インストールされているオペレーティングシステムが FreeBSD だけであれば、dmesg(8) を使い、 起動時に検出されたハードウェアの一覧を調べてください。 FreeBSD のほとんどのデバイスドライバにはマニュアルページが用意され、 対応しているハードウェアの一覧を提供しています。 たとえば、以下の行は、psm(4) ドライバがマウスを検出したことを示しています。

psm0: <PS/2 Mouse> irq 12 on atkbdc0
psm0: [GIANT-LOCKED]
psm0: [ITHREAD]
psm0: model Generic PS/2 mouse, device ID 0

このハードウェアはシステムに存在するので、 カスタムカーネルコンフィグレーションファイルからこのドライバを外さないでください。

dmesg が起動時の検出結果を表示しない場合には、 かわりに /var/run/dmesg.boot で出力を確認してください。

ハードウェアを見つけるためのもうひとつのツールは、 より冗長な出力を行う pciconf(8) です。 たとえば、以下のようになります。

% pciconf -lv
ath0@pci0:3:0:0:        class=0x020000 card=0x058a1014 chip=0x1014168c rev=0x01 hdr=0x00
    vendor     = 'Atheros Communications Inc.'
    device     = 'AR5212 Atheros AR5212 802.11abg wireless'
    class      = network
    subclass   = ethernet

この出力は、ath ドライバがワイヤレスイーサネットデバイスにあることを示しています。

man(1)-k フラグで実行すると、 有用な情報を得ることができます。たとえば、 ある特定のデバイスブランドや名前を含むマニュアルページの一覧を表示するには、 以下のように実行してください。

# man -k Atheros
ath(4)                   - Atheros IEEE 802.11 wireless network driver
ath_hal(4)               - Atheros Hardware Access Layer (HAL)

ハードウェアの一覧を作成したら、 この一覧を利用して、 カスタムカーネルのコンフィグレーションファイルを編集している時に、 インストールされているハードウェアのドライバが削除されていないことを確認してください。

8.4. コンフィグレーションファイル

カスタムカーネルのコンフィグレーションファイルを作成し、 カスタムカーネルを構築するには、 FreeBSD の全ソースツリーがまずインストールされている必要があります。

もし /usr/src/ が存在していなかったり、空であれば、 カーネルのソースはインストールされていません。 「Subversion を使う」 で説明した Subversion を使ってソースをインストールしてください。

ソースをインストールしたら、 /usr/src/sys を確認して下さい。 このディレクトリには、いくつものサブディレクトリがあります。 その中には、サポートされている各アーキテクチャ amd64, i386, powerpc および sparc64 のサブディレクトリがあります。 各アーキテクチャのディレクトリ内部にあるファイルはすべてそのアーキテクチャでのみ使用されます。 残りのコードは、アーキテクチャに依存しない、 すべてのプラットフォームで共有されるコードです。 サポートされている各アーキテクチャには、 conf サブディレクトリがあり、 そのアーキテクチャ用の GENERIC カーネルコンフィグレーションファイルが用意されています。

この GENERIC は編集しないでください。 かわりに、このファイルを別名でコピーし、コピーを編集してください。 慣習として、この名前はすべて大文字でつづられます。もし、 いくつかの異なるハードウェアの FreeBSD マシンを扱うなら、 この名前にホスト名を含めるとよいでしょう。ここでは、例として MYKERNEL という名前の amd64 アーキテクチャ用の GENERIC コンフィグレーションファイルのコピーを作成します。

# cd /usr/src/sys/amd64/conf
# cp GENERIC MYKERNEL

これで、MYKERNEL を ASCII テキストエディタで編集できます。 初心者に対してより簡単なエディタである ee も FreeBSD とともにインストールされていますが、 デフォルトのエディタは vi です。

コンフィグレーションファイルのフォーマットはシンプルです。 各行はデバイスやサブシステム、引数、または簡単な説明を含んでいます。 に続くテキストはすべてコメントとして扱われ、 無視されます。 カーネルからデバイスもしくはサブシステムのサポートを外すには、 対応する行の最初に を入れてください。 理解していない行に対しては、# を追加したり削除しないでください。

デバイスやオプションのサポートを外すことは簡単で、 その結果、カーネルを壊すことがあります。 たとえば ata(4) ドライバをカーネルコンフィグレーションファイルから除くと、 ATA ディスクドライバを用いているシステムは起動しません。 確信が持てないものについては、 カーネルにサポートを残したままにしてください。

このファイルで与えられる説明の他に、 そのアーキテクチャの GENERIC と同じディレクトリにある NOTES にも説明があります。 アーキテクチャに依存しないオプションについては、 /usr/src/sys/conf/NOTES をご覧ください。

カーネルコンフィグレーションファイルの編集を終えたら、 ファイルのバックアップを /usr/src 以外の場所に保存してください。

または、カーネルコンフィグレーションファイルは他の場所において、 シンボリックリンクを張る方法もあります。

# cd /usr/src/sys/amd64/conf
# mkdir /root/kernels
# cp GENERIC /root/kernels/MYKERNEL
# ln -s /root/kernels/MYKERNEL

コンフィグレーションファイルでは include ディレクティブを利用できます。 コンフィグレーションファイルに他のファイルを取り込むことができるので、 すでに存在するファイルに対する小さな変更の管理が簡単にできます。 オプションやドライバの追加が少しだけの場合には、 以下の例のように GENERIC からの差分による管理が可能になります。

include GENERIC
ident MYKERNEL

options         IPFIREWALL
options         DUMMYNET
options         IPFIREWALL_DEFAULT_TO_ACCEPT
options         IPDIVERT

この方法では、ローカルのコンフィグレーションファイルには、 ローカルにある GENERIC カーネルとの差分が記述されています。 アップグレードが行われると、 GENERIC に追加された新しい機能は、 (nooptionsnodevice によって外されない限り) ローカルのカーネルにも反映されます。 コンフィグレーションの構成要素に関する包括的な一覧と説明は config(5) にあります。

利用可能なすべてのオプションを含むファイルを構築するには、 以下のコマンドを root 権限で実行してください。

# cd /usr/src/sys/arch/conf && make LINT

8.5. カスタムカーネルの構築とインストール

カスタムコンフィグレーションファイルを編集して保存したら、 カーネルのソースコードを以下の手順でコンパイルしてください。

Procedure: カーネルの構築

  1. 以下のディレクトリに移動してください。

    # cd /usr/src
  2. カスタムコンフィグレーションファイルの名前を指定して新しいカーネルをコンパイルします。

    # make buildkernel KERNCONF=MYKERNEL
  3. 指定したカーネルコンフィグレーションファイルでコンパイルされた新しいカーネルをインストールします。 以下のコマンドは、新しいカーネルを /boot/kernel/kernel に、 今までのカーネルを /boot/kernel.old/kernel という名前で保存します。

    # make installkernel KERNCONF=MYKERNEL
  4. 新しいカーネルを使うために、 システムをシャットダウンして再起動してください。 うまく行かない場合は、カーネルが起動しない を参照してください。

デフォルトでは、カスタムカーネルを構築すると、 すべてのカーネルモジュールが再構築されます。 カーネルのアップデートをより早く行いたい、または、 カスタムモジュールのみを構築したいといった場合は、 カーネルの構築を開始する前に、以下のように /etc/make.conf を編集してください。

例として、以下の変数は、 デフォルトのすべてのモジュールを構築する設定を変更し、 構築するモジュール一覧を指定します。

MODULES_OVERRIDE = linux acpi

また、以下の変数は、構築を行わないモジュールを指定します。

WITHOUT_MODULES = linux acpi sound

他の変数については、make.conf(5) を参照してください。

8.6. 問題が起きた場合には

カスタムカーネルを作る際に起こりうるトラブルは、 次の 4 種類に分けられます。

config コマンドの失敗

config で失敗した時には、 トラブルの起きた行番号が出力されます。 たとえば、次のように出力された場合には、 17 行目が正しく入力されているかどうか、 GENERICNOTES と比較して修正してください。

config: line 17: syntax error
make コマンドの失敗

make が失敗した場合には、 通常、カーネルコンフィグレーションファイルにおいて、 config がとらえられなかったような間違いをしています。 コンフィグレーションファイルを見直してください。 それでも問題を解決することができなければ、 FreeBSD general questions メーリングリスト へカーネルコンフィグレーションファイルを添付して送ってください。

カーネルが起動しない

新しいカーネルが起動しなかったり、 デバイスの認識をしない場合でもあわてないでください! さいわい、FreeBSD には利用できないカーネルから復帰する洗練されたメカニズムがあります。 FreeBSD のブートローダで起動したいカーネルを選択してください。 システムの起動メニューが表示されている時に、 "Escape to a loader prompt" オプションを選択するとアクセスできます。 プロンプトで boot kernel.old か他の正常に起動するカーネルを入力してください。

問題のないカーネルで起動した後、 コンフィグレー ションファイルを調べ、 再び構築を試みてください。 /var/log/messages にはすべての成功した起動時のカーネルメッセージの記録があり、 これは問題を解決するための助けになる情報の一つでしょう。また、 dmesg(8) は現在の起動時のカーネルメッセージを出力します。

カーネルの構築中にトラブルが起きた時には、 次回の構築で消されないように、 GENERIC のコピーや他の正常に起動するカーネルを別の名前で保存するようにしてください。 kernel.old は新しいカーネルをインストールする時に、 その一つ前にインストールした、 うまく動かないかもしれないカーネルで上書きされてしまうため、 起動するカーネルを保存しておくことは重要です。 できる限り早く以下のようにして、 正しく起動するカーネルを含むディレクトリ名に変更してください。

# mv /boot/kernel /boot/kernel.bad
# mv /boot/kernel.good /boot/kernel
カーネルは動きますが ps(1) は動きません!

システムユーティリティの構築されたバージョンと異るバージョンのカーネルをインストールした場合、 たとえば -CURRENT のソースから構築したカーネルを -RELEASE システム上にインストールするような場合には、 ps(1)vmstat(8) のような多くのシステムステータスコマンドは動かなくなります。 修正するには、カーネルと同じバージョンのソースツリーで world を再構築し、インストール してください。 カーネルとそれ以外で異なるバージョンを組み合わせてオペレーティングシステムを使用することは推奨されていません。


All FreeBSD documents are available for download at https://download.freebsd.org/ftp/doc/

Questions that are not answered by the documentation may be sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.