第12章 FreeBSD の起動のプロセス

12.1. この章では

計算機を起動しオペレーティングシステムをロードするプロセスは、 "ブートストラッププロセス" もしくは "ブート" と呼ばれます。 FreeBSD の起動プロセスを使えば、 システムをスタートするときに起きることをかなり柔軟にカスタマイズできます。 同じ計算機にインストールされた別のオペレーティングシステムを選択することもできますし、 同じオペレーティングシステムの異なるバージョンを選択することも、 インストールされた別のカーネルを選択することさえできます。

この章では、指定できる設定オプションついて詳しく説明します。 FreeBSD カーネルがスタートし、デバイスを検出し、 init(8) を起動するまでに起きることすべてを含む FreeBSD の起動プロセスのカスタマイズ方法について説明します。 これは、起動メッセージのテキストの色が、 明るい白から灰色に変わるまでに起きています。

この章を読むと、以下のことが分かります。

  • FreeBSD のブートストラップシステムの構成およびそれらが互いにどう関係しているのか

  • 起動プロセスを制御するために FreeBSD のブートストラップの各要素に付加できるオプション

  • device hints の基本的な記述方法

  • シングルユーザもしくはマルチユーザモードでの起動方法、 および FreeBSD システムのシャットダウンの方法

この章では Intel x86 および amd64 システム上で動作する FreeBSD の起動プロセスだけを扱います。

12.2. FreeBSD の起動プロセス

計算機の電源を入れ、オペレーティングシステムをスタートさせるのには、 おもしろいジレンマがあります。定義により、 計算機は、オペレーティングシステムが起動するまでは、 ディスクからプログラムを動かすことも含めて、 何をどうすればよいかまったく知りません。 計算機はオペレーティングシステムなしにディスクからプログラムを実行することができず、 オペレーティングシステムのプログラムがディスク上にあるのなら、 どうやってオペレーティングシステムを起動するのでしょうか?

この問題はほらふき男爵の冒険 という本の中に書かれている問題ととてもよく似ています。 登場人物がマンホールの下に半分落っこちて、 靴紐 (ブートストラップ) をつかんで自分を引っぱり、持ち上げるのです。 計算機の黎明期には、ブートストラップ という用語でオペレーティングシステムをロードする機構のことを指していました。 いまはこれを縮めて "ブート (起動)" と言います。

x86 ハードウェアでは、基本入出力システム (Basic Input/Output System: BIOS) にオペレーティングシステムをロードする責任があります。 BIOS はハードディスク上のマスターブートレコード (Master Boot Record: MBR) を探します。 MBR はハードディスク上の特定の場所になければなりません。 BIOS には MBR をロードし起動するのに十分な知識があり、 オペレーティングシステムをロードするために必要な作業の残りは、 場合によっては BIOS の助けを得た上で MBR が実行できることを仮定しています。

FreeBSD は古い標準の MBR、 または新しい GUID Partition Table (GPT) から起動できます。 GPT パーティションは、Unified Extensible Firmware Interface (UEFI) に対応したコンピュータで良く用いられます。 しかしながら、FreeBSD はレガシーな BIOS にのみに対応したコンピュータからも、gptboot(8) により、 GPT パーティションから起動できます。 UEFI からの直接の起動への対応は進行中です。

MBR 内部のコードは、 一般的に_ブートマネージャ_と呼ばれます。 とりわけユーザとの対話がある場合にそう呼ばれます。 通常ブートマネージャのもっと多くのコードが、 ディスクの最初のトラック、またはファイルシステム上におかれます。 ブートマネージャの例としては、Boot Easy とも呼ばれる FreeBSD 標準のブートマネージャの boot0、 多くの Linux® ディストリビューションが採用している Grub 等があります。

ディスク上にインストールされているオペレーティングシステムが 1 つの時は、MBR はディスク上の最初の起動可能な (アクティブな) スライスを探し、 そのスライスにあるコードを起動してオペレーティングシステムの残りをロードします。 ディスク上に複数のオペレーティングシステムが存在しているのなら、 複数のオペレーティングシステムの一覧を表示できて、 起動するオペレーティングシステムを選択できるような、 別のブートマネージャをインストールすることもできます。

FreeBSD のブートストラップシステムの残りは 3 段階に分かれます。 第 1 ステージは、 計算機を特定の状態にするために必要なことだけを知っていて、 第 2 ステージを起動します。 第 2 ステージでは、第 3 ステージを起動する前に、 もう少しできることがあります。 第 3 ステージでオペレーティングシステムのロード作業を完了します。 起動作業が 3 段階に分かれているのは、 MBR がステージ 1 とステージ 2 で実行できるプログラムのサイズに制限を課しているからです。 これらの作業をつなぎ合わせることによって、 FreeBSD はより柔軟なローダ (loader) を提供しているのです。

その後カーネルが起動し、デバイスの検出と初期化を開始します。 そしてカーネルの起動が終わると、制御はユーザープロセスの init(8) へ移されます。init(8) はディスクが利用可能であることを確認し、 ファイルシステムのマウント、 ネットワークで利用するネットワークカードのセットアップ、 そしてブート時に起動されるように設定されたプロセスの起動、 といったユーザーレベルでのリソース (資源) 設定を行ないます。

この章では、これらのステージについてより詳細に、また、FreeBSD ブートプロセスにおける対話的な設定方法について説明します。

12.2.1. ブートマネージャ

MBR のブートマネージャのコードは起動プロセスの_第 0 ステージ_と呼ばれることがあります。 デフォルトでは、FreeBSD は boot0 を使います。

FreeBSD のインストーラがインストールする MBR は、 /boot/boot0 を基にしています。 boot0 のサイズと機能は、 スライステーブルおよび MBR 末尾の識別子 0x55AA のため、 446 バイトの大きさに制限されます。 もし、boot0 と複数のオペレーティングシステムをインストールした場合、 起動時に以下のようなメッセージが表示されます。

例 1. boot0 のスクリーンショット
F1 Win
F2 FreeBSD

Default: F2

他のオペレーティングシステムは、 FreeBSD の後にインストールを行うと、既存の MBR を上書きしてしまいます。 もしそうなってしまったら、 もしくは既存の MBR を FreeBSD の MBR で置き換えるには、 次のコマンドを使ってください。

# fdisk -B -b /boot/boot0 device

device は起動するデバイス名で、 たとえば 1 番目の IDE ディスクは ad0、2 番目の IDE コントローラに接続されている 1 番目の IDE ディスクは ad2、 1 番目の SCSI ディスクは da0 などとなります。 MBR の設定をカスタマイズしたい場合は、 boot0cfg(8) を参照してください。

12.2.2. 起動ステージ 1 と起動ステージ 2

概念上、第 1 ステージと第 2 ステージはハードディスクの同じ領域上の同一のプログラムの部分部分です。 スペースの制約のため 2 つに分割されていますが、 いつも一緒にインストールされます。 FreeBSD のインストーラまたは bsdlabel は、 両者を 1 つにまとめた /boot/boot をコピーします。

これらの 2 つのステージは、ファイルシステムの外部、 起動スライスの最初のトラックに置かれ、 先頭が最初のセクタにきます。 boot0 またはその他のブートマネージャは、 起動プロセスを続けるために必要なプログラムがそこにあると想定しています。

最初のステージの boot1 は、 512 バイトの大きさでなければならないという制限があるので、 非常に単純なプログラムです。 このプログラムは boot2 を検索して実行するため、そのスライスの情報を保持する FreeBSD の BSD ラベル に関する最低限の情報だけを持っています。

次のステージの boot2 はもう少し高機能です。 これは FreeBSD のファイルシステム上でファイルを見つける機能を持ちます。 実行するカーネルやローダを指定するための簡単なインタフェースを提供します。 boot2 により起動される loader はさらに高機能で、 起動設定が行なえる手段を提供します。 ステージ 2 で起動プロセス中断した時には、 次のようながインタラクティブなが画面が表示されます。

例 2. boot2 のスクリーンショット
>> FreeBSD/i386 BOOT
Default: 0:ad(0,a)/boot/loader
boot:

インストールされた boot1boot2 を変更するには、 bsdlabel を使ってください。 以下の例では、diskslice は起動するディスクとスライスで、たとえば最初の IDE ディスクの 1 番目のスライスは ad0s1 となります。

# bsdlabel -B diskslice

ad0 のようにディスク名だけを指定すると、 bsdlabel は、スライスを持たない "危険な専用モード"を作成してしまいます。 これはおそらく、あなたが望んでいることではないでしょうから、 Return キーを押す前に、 diskslice の部分を二重にチェックしてください。

12.2.3. 起動ステージ 3

loader は三段階の起動プロセスの最終段階です。 これは通常、ファイルシステム上の /boot/loader として存在しています。

loader は、 よりさまざまなコマンド群をサポートした強力なインタプリタによって提供される組み込みコマンド群を利用することで、 インタラクティブな設定手段となるように設計されています。

loader は初期化の際にコンソールとディスクの検出を行ない、 どのディスクから起動しているかを調べます。 そして必要な変数を設定してからインタプリタを起動し、 スクリプトからコマンドを送ったり手でコマンドを入力したりできます。

loader は次に /boot/loader.rc を読み込み、通常、変数の標準値を定義した /boot/defaults/loader.conf と、そのコンピュータにローカルに変数を定義した /boot/loader.conf を読み込みます。 loader.rc はそれらの変数にもとづき、 選択されたモジュールとカーネルをロードします。

loader は最後に、 標準設定で 10 秒のキー入力待ち時間を用意し、 入力がなければカーネルを起動します。 入力があった場合、コマンド群が使えるプロンプトが表示され、 ユーザは変数を調整したり、すべてのモジュールをアンロードしたり、 モジュールをロードしたりすることができます。 その後、最終的な起動や再起動へ移行します。 ローダの組み込みコマンドでは、 もっともよく使われる loader のコマンドをまとめています。 利用可能なコマンドをすべて知りたい場合には、 loader(8) を参照してください。

表 1. ローダの組み込みコマンド
変数説明

autoboot seconds

seconds で与えられた時間内に入力がなければ、 カーネルの起動へと進みます。 カウントダウンを表示します。標準設定では 10 秒間です。

boot [-options] [kernelname]

すぐにカーネルの起動へ進みます。 オプション、カーネル名が指定されている場合は、 それらが使われます。 unload を実行後、 カーネル名をコマンドラインから指定することができます。 unload を実行しないと、 一度読み込まれたカーネルが使われます。 kernelname でパスが指定されていない時には、 /boot/kernel および /boot/modules から調べられます。

boot-conf

すべてのモジュールの設定を、 起動時と同じように指定された変数 (最も多いのは kernel) にもとづいて自動的に行ないます。 このコマンドは、変数を変更する前に、 最初に unload を行なった場合にのみ有効に働きます。

help [topic]

/boot/loader.help を読み込み、ヘルプメッセージを表示します。 topic に index が指定された場合、 利用可能な topic の一覧を表示します。

include filename …​

指定されたファイルを読み込み、行単位で解釈します。 エラーが発生した場合、 include の実行は直ちに停止します。

load [-t type] filename

指定されたファイル名のカーネル、 カーネルモジュール、あるいは type に指定された種類のファイルをロードします。 filename 以降に指定された引数はファイルへと渡されます。 filename でパスが指定されていない時には、 /boot/kernel および /boot/modules から調べられます。

ls [-l] [path]

指定された path にあるファイルを表示します。 path が指定されていなければ、ルートディレクトリを表示します。 -l が指定されていればファイルサイズも表示されます。

lsdev [-v]

モジュールがロード可能なすべてのデバイスを表示します。 もし -v が指定されていれば、 より詳細な出力がされます。

lsmod [-v]

ロード済みのモジュールを表示します。 -v が指定されていれば、 より詳細な内容が出力されます。

more filename

LINES 行を表示するごとに停止しながら指定されたファイルを表示します。

reboot

すぐにシステムを再起動します。

set variable, set variable=value

ローダの環境変数を設定します。

unload

すべてのロード済みモジュールを削除します。

次にあげるのは、ローダの実践的な使用例です。 普段使っているカーネルをシングルユーザモードで起動します。

 boot -s

普段使っているカーネルとモジュールをアンロードし、 古いもしくは別のカーネルをロードするには、 以下のように実行してください。

unload
load /path/to/kernelfile

インストール時のデフォルトカーネルを指定するには、完全修飾の /boot/GENERIC/kernel を使ってください。 また、システムをアップグレードしたり、 もしくはカスタムカーネルを設定した場合に、 直前にインストールされていたカーネルは、 /boot/kernel.old/kernel で指定できます。

普段のカーネルで使っているモジュールを指定したカーネルでロードする場合は、 次のようにします。 この場合は、完全修飾名を使う必要はありません。

unload
set kernel="mykernel"
boot-conf

カーネルの自動設定スクリプトをロードします。

 load -t userconfig_script /boot/kernel.conf

12.2.4. 最終ステージ

カーネルがデフォルトの loader もしくは loader を迂回して boot2 によって読み込まれると、 起動フラグが調べられ、それに応じて動作が調整されます。起動時のカーネルオプション には、 良く使われる起動フラグがまとめられています。 他の起動フラグの詳細については、 boot(8) を参照してください。

表 2. 起動時のカーネルオプション
オプション説明

-a

カーネル初期化中に、 ルートファイルシステムとしてマウントするデバイスを尋ねます。

-C

CDROM からルートファイルシステムを起動します。

-s

シングルユーザモードで起動します。

-v

カーネル起動時に、より詳細な情報を表示します。

カーネルの起動が完了すると、init(8) というユーザプロセスに制御が移されます。 これは /sbin/init、 もしくは loaderinit_path 変数で指定される場所にあります。 これは起動プロセスの最終ステージです。

起動シーケンスでは、 システム上で利用できるファイルシステムの一慣性を確認します。 もし UFS ファイルシステムにに問題があって fsck が不一致を修復できなければ、 管理者が問題を直接解決できるように、init はシステムをシングルユーザモードへと移行させます。 問題がなければ、システムはマルチユーザモードに移行します。

12.2.4.1. シングルユーザモード

このモードには、ユーザが起動時に -s を指定した場合、あるいは loader で boot_single 変数を設定することによって移行します。 マルチユーザモードから shutdown now を呼び出すことでもこのモードに移行できます。 シングルユーザモードは、以下のメッセージで開始します。

Enter full pathname of shell or RETURN for /bin/sh:

ユーザが Enter を入力すると、 システムは Bourne シェルを起動します。 別のシェルを使うには、シェルのフルパスを入力してください。

シングルユーザモードは、 通常ファイルシステムの一貫性に問題があって起動できないシステムを修復したり、 起動設定ファイルの間違いを修正するために使われます。 また、root パスワードがわからなくなった場合に、 リセットするために使うことも出来ます。 シングルユーザモードのプロンプトは、 ローカルファイルシステムおよび設定ファイルへのアクセスを与えてくれますが、 ネットワーク接続は出来ません。

シングルユーザモードは、システムの修復には有用ですが、 システムが物理的に安全な場所になければ、 セキュリティのリスクがもたらされます。 デフォルトでは、システムに物理的にアクセス可能なユーザは、 シングルユーザモードで起動後はシステムをすべてコントロールできます。

/etc/ttys でシステムの consoleinsecure に設定されている場合、 システムはシングルユーザモードに移行する前に root のパスワードを入力するように求めます。 root パスワードがわからなくなった場合のリセット機能が無効になっている間は、 セキュリティ対策が必要となります。

例 3. /etc/ttys の insecure コンソール
# name  getty                           type    status          comments
#
# If console is marked "insecure", then init will ask for the root password
# when going to single-user mode.
console none                            unknown off insecure

insecure コンソールとは、 コンソールが物理的に安全でない (insecure) と考えられるため、 root のパスワードを知る人だけがシングルユーザモードを使えるという意味です。

12.2.4.2. マルチユーザモード

init がファイルシステムが正常であると判断するか、 ユーザがシングルユーザモードでのコマンドを終了し、 exit を入力してシングルユーザモードを終了すると、 システムはマルチユーザモードへ移行し、 システムのリソースの設定を開始します。

リソース設定システムはデフォルト設定を /etc/defaults/rc.conf から、 また、システム独自の細かな設定を /etc/rc.conf から読み込みます。 そして /etc/fstab に記述されるシステムファイルシステムをマウントします。 その後、ネットワークサービス、さまざまなシステムデーモン、 そして最後に、ローカルにインストールされた package の起動スクリプトを実行します。

リソース設定システムについてもっと知りたい場合には、 rc(8) を参照してください。また、/etc/rc.d にあるスクリプトを実行してみてください。

12.3. Device Hints

システムの最初のスタートアップ時に、loader(8)device.hints(5) を読み込みます。 このファイルにはカーネル起動の環境変数が格納されており、 これらの環境変数は "device hints" と呼ばれることがあります。デバイスドライバは、 デバイスを設定するために "device hints" を使用します。

起動ステージ 3 で説明されているように device hints はステージ 3 ブートローダプロンプトでも設定できます。 変数は set を用いて追加したり、 unset を用いて削除できます。 show を用いて一覧を見ることもできます。 /boot/device.hints に設定されている変数は、 上書きすることもできます。 ブートローダで設定した device hints の効果は一時的なものなので、 次回起動するときには無効になります。

システムが起動すると、kenv(1) コマンドですべてのカーネル環境変数をダンプすることができます。

/boot/device.hints は 1 行につき一つの変数を設定でき、行頭の "#" はその行がコメントであることを示しています。 書式は次の通りです。

 hint.driver.unit.keyword="value"

ステージ 3 ブートローダ で設定するときの書式は次の通りです。

 set hint.driver.unit.keyword=value

ここで、driver はデバイスドライバの名前、 unit はデバイスドライバのユニット番号、 keyword はヒントキーワードです。 キーワードは以下のようなオプションです。

  • at: デバイスがどのバスに接続されているか指定します。

  • port: 使用する I/O ポートの開始アドレスを指定します。

  • irq: 使用する IRQ を指定します。

  • drq: 使用する DMA チャネルを指定します。

  • maddr: 使用する物理メモリアドレスを指定します。

  • flags: デバイスに対してさまざまなフラグを設定します。

  • disabled: 1 が設定されていると、そのデバイスは無効になります。

デバイスドライバはこのリスト以外の変数を設定できるかもしれませんし、 このリスト以外の変数を必要とするかもしれないので、 ドライバのマニュアルを読むことをおすすめします。 より多くの情報を知りたければ、device.hints(5), kenv(1), loader.conf(5) および loader(8) を参照してください。

12.4. シャットダウン動作

shutdown(8) を用いてシステムを意図的にシャットダウンした場合、 init(8)/etc/rc.shutdown というスクリプトの実行を試みます。 そして、すべてのプロセスへ TERM シグナルを送り、続いてうまく終了できなかったプロセスへ KILL シグナルを送ります。

電源管理機能を持ったシステムで稼働している FreeBSD では shutdown -p now によって、 直ちに電源を落とすことができます。FreeBSD システムを再起動するには、 shutdown -r now を実行してください。 shutdown(8) を実行するには、 root か、operator のメンバでなければなりません。halt(8)reboot(8) を利用することもできます。 より多くの情報を得るために、それらのマニュアルページや shutdown(8) を参照してください。

グループのメンバを変更するには、 「この章では」 を参照してください。

電源管理機能には acpi(4) がモジュールとして読み込まれるか、 カスタムカーネルにコンパイルされて静的に組み込まれている必要があります。


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>.