第3章 システムの初期化

目次

3.1. ブートストラッププロセスの概要
3.1.1. 1段目: BIOS
3.1.2. 2段目: ブートローダー
3.1.3. 3段目: ミニ Debian システム
3.1.4. 4段目: 通常の Debian システム
3.2. SysV-スタイル init
3.2.1. ランレベルの意味
3.2.2. ランレベルの設定
3.2.3. ランレベル管理例
3.2.4. 各 init スクリプトのデフォールトのパラメーター
3.2.5. ホスト名
3.2.6. ファイルシステム
3.2.7. ネットワークインターフェースの初期化
3.2.8. ネットワークサービスの初期化
3.2.9. システムメッセージ
3.2.10. カーネルメッセージ
3.3. udev システム
3.3.1. カーネルモジュール初期化

Debian システムが以下に起動され設定されるかの知っていることはシステム管理者として賢明です。正確で詳細な情報がインストールされたパッケージのソースや文書中にあるとは言え、我々の大部分にとってはちょっと大変過ぎます。

著者などの過去の知見に基づき Debian システムの要点とそれらの設定の簡単な参考となる概論を提供するように勤めました。Debian システムは動く標的なので、システムの状況が変わっているかもしれません。システムに変更を加える前に、各パッケージの最新文書を参照下さい。

[警告] 警告

本章は、2013年にリリースされた Debian 7.0 (Wheezy) に基づいているため、内容が陳腐化しつつあります。

コンピューターシステムは、電源投入イベントからユーザーに機能の完備したオペレーティングシステム (OS) を提供するまでブートストラッププロセスを数段通過します。

単純化のため、デフォールトのインストールをした典型的な PC プラットフォームに限定し議論します。

典型的なブートストラッププロセスは4段ロケットのようです。各段のロケットは次の段のロケットにシステムのコントロールを引き継ぎます。

もちろん、これらに関して異なる設定をすることはできます。例えば、自分自身で専用カーネルをコンパイルした場合、ミニ Debian システムのステップをスキップできます。自分自身で確認するまでは、あなたのシステムがこの様になっていると決めつけないで下さい。

[注記] 注記

非伝統的 PC プラットフォームの SUN とか Macintosh システム等では、ROM 上の BIOS やディスク上のパーティション (「ディスクパーティション設定」) が非常に異なっているかもしれません。そのような場合にはプラットフォーム特定の文書をどこかで求めて下さい。

BIOS は電源投入イベントが引き起こすブートプロセスの1段目です。CPU のプログラムカウンターが電源投入イベントで初期化され、読出し専用メモリー (ROM) 上にあるBIOS が特定のメモリーアドレスから実行されます。

BIOS はハードウエアーの基本的な初期化 (POST: 電源投入時自己診断) を行い、システムのコントロールをあなたが提供する次のステップにシステムのコントロールを引き継ぎます。BIOS は通常ハードウエアーによって供給されます。

BIOS 初期画面はどのキーを押すと BIOS 設定画面に入って BIOS の挙動を設定できるかを通常表示しています。よく使われるキーは F1 や F2 や F10 や Esc や Ins や Del です。もし BIOS 初期画面が洒落た画像表示で隠されている場合、Esc 等の何らかのキーをおすとこれを無効にできます。こういったキーはハードウエアーに大いに依存します。

BIOS が起動するコードのハードウエアー上の場所や優先順位は BIOS 設定画面から選択できます。典型的には最初に見つかった選択されたデバイス (ハードディスクやフロッピーディスクや CD-ROM 等) の最初の数セクターがメモリー上にロードされこの初期コードが実行されます。この初期コードは次のいずれでもよろしい。

  • ブートローダーコード

  • FreeDOS のような踏み石 OS のカーネルコード

  • この小さな空間に収まればターゲット OS のカーネルコード

典型的にはプライマリハードディスクの指定されたパーティションからシステムが起動されます。伝統的 PC のハードディスクの最初の2セクターにマスターブートレコード (MBR) が含まれます。ブート選択に含まれるディスクのパーティション情報はこの MBR の最後に記録されています。BIOS から実行される最初のブートローダーコードは残りの部分を占めます。

ブートローダーは BIOS によって起動されるブートプロセスの2段目です。それはシステムのカーネルイメージと initrd イメージをメモリーにロードし、それらにコントロールを引き継ぎます。この initrd イメージはルートファイルシステムイメージで、そのサポートは使われるブートローダー次第です。

Debian システムは通常 Linux カーネルをデフォールトのシステムカーネルとして使っています。現在の 2.6/3.x カーネルにとっての initrd イメージは技術的に言うなら initramfs (初期 RAM ファイルシステム) イメージです。initramfs イメージはルートファイルシステム中のファイルの gzip された cpio アーカイブです。

[警告] 警告

上記は新しいマルチセグメントの initramfs では正しくありません。Bug #790100参照ください。

Debian システムのデフォールトインストールでは、GRUB ブートローダーの1段目のコードを PC プラットホームの MBR の中に置きます。多くのブートローダーと設定の選択肢が利用可能です。


[警告] 警告

grub-rescue-pc パッケージのイメージから作ったブート可能なレスキューメディア (CD かフロッピー) 無しにブートローダーを試してはいけません。これさえあると、ハードディスク上に機能するブートローダーが無くともシステムの起動ができます。

GRUB Legacy のメニューの設定は "/boot/grub/menu.lst" にあります。例えば、次のような内容です。

title           Debian GNU/Linux
root            (hd0,2)
kernel          /vmlinuz root=/dev/hda3 ro
initrd          /initrd.img

GRUB 2 のメニューの設定は "/boot/grub/grub.cfg" にあります。 "/etc/grub.d/*" の雛形と "/etc/default/grub" の設定から "/usr/sbin/update-grub" を使って自動的に作られます。例えば、次のような内容です。

menuentry "Debian GNU/Linux" {
        set root=(hd0,3)
        linux /vmlinuz root=/dev/hda3
        initrd /initrd.img
}

これらの例で、これらの GRUB パラメーターは次の意味です。


[注記] 注記

GRUB legacy プログラムが使うパーティション値は Linux カーネルやユーティリティーツールが使う値より1つ少ない数字です。GRUB 2 プログラムはこの問題を修正します。

[ヒント] ヒント

UUID (「UUID を使ってパーティションをアクセス」参照下さい) は、"/dev/hda3" のようなファイル名に代わるブロックの特定デバイスを確定するのに使え、例えば "root=UUID=81b289d5-4341-4003-9602-e254a17ac232 ro" です。

[ヒント] ヒント

もし GRUB が使われている場合には、カーネルブートパラメーターは /boot/grub/grub.cfg 中に設定されます。 Debian システム上では、/boot/grub/grub.cfg を直接編集するべきではありません。/etc/default/grub 中の GRUB_CMDLINE_LINUX_DEFAULT の値を編集するべきで、update-grub(8) を実行することで /boot/grub/grub.cfg を更新すべきです。

[ヒント] ヒント

チェインロード (連鎖導入) とよばれる技術を使うと、あるブートローダーから他のブートローダーを起動できます。

"info grub" と grub-install(8) を参照下さい。

ミニ Debian システムはブートローダーによって起動されるブートプロセスの3段目です。メモリー上でルートファイルシステムとともにシステムカーネルを実行します。これはオプションの起動プロセスの準備段階です。

[注記] 注記

"ミニ Debian システム" は著者がこの3段目のブートプロセスを本文書中で記述するために作った言葉です。このシステムは一般に initrd とか initramfs システムと呼ばれています。類似のメモリー上のシステムは Debian インストーラーでも使われています。

"/init" スクリプトはこのメモリー上のルートファイルシステムで最初に実行されるプログラムです。それはユーザー空間でカーネルを初期化し次の段階にコントロールを引き継ぐシェルプログラムです。このミニ Debian システムは、メインのブートプロセスが始まる前にカーネルモジュールを追加したり、ルートファイルシステムを暗号化されたファイルシステムとしてマウントする等のブートプロセスの柔軟性を提供します。

"break=init" 等をカーネルブートパラメーターとして与えると、本部分のブートプロセスに割り込み root シェルを獲得できます。この他の割り込み条件は "/init" スクリプトを参照下さい。このシェル環境はあなたの機器のハードウエアーを詳細に検査できるだけ十分洗練されています。

この機能を削ったミニ Debian システムで利用可能なコマンドは、主に busybox(1) という GNU ツールで提供されます。

[注意] 注意

読出しのみのルートファイルシステム上では、mount コマンドには "-n" オプションを使う必要があります。

通常の Debian システムはミニ Debian システムによって起動されるブートプロセスの4段目です。ミニ Debian システムのシステムカーネルはこの環境ででも実行され続けます。ルートファイルシステムはメモリー上から本当にハードディスク上にあるファイルシステムに切り替えられます。

多くのプログラムを起動する主ブートプロセスを行う init プログラムは、PID=1 で最初のプログラムとして実行されます。init プログラムのデフォールトのファイルパスは "/sbin/init" ですが、"init=/path/to/init_program" のようなカーネルブートパラメーターにより変更できます。

デフォルトの init プログラムは変化してきています:

  • squeeze 以前の Debian は、単純な SysV-スタイル init を使用します。

  • wheezy の Debian は、LSB ヘッダーを用いブート順決めブートスクリプトを並列起動をする改良された SysV-スタイル init を使用します。

  • jessie の Debian は、イベントドリブンで並列初期化のために systemd にデフォルトの init を切り替えました。

[ヒント] ヒント

"/etc/init.d/rc" と "/etc/init.d/rcS" と "/usr/sbin/update-rc.d" と "/usr/sbin/invoke-rc.d" のスクリプトによって全てのブートメカニズムには互換性があります。

[ヒント] ヒント

あなたのシステム上の実際の init コマンドは "ps --pid 1 -f" コマンドで確認できます。


[ヒント] ヒント

ブートプロセスを高速化する最新のティップは Debian wiki: BootProcessSpeedup を参照下さい。

[注意] 注意

現行のデフォルト Debian システムは SysV-スタイルの init を使いません。最近の systemd に基づく init のための他の資料を読んでください。The Debian Administrator's Handbook を参照ください。

本セクションは古き良き sysV-スタイル init がどのようにしてシステムをブートするかを記述します。あなたの Debian システムはここに書かれたとおりには機能しませんが、より新しい init システムは等価の機能を提供する傾向があるのでこの基本を知ることは非常に勉強となります。

SysV-スタイルの起動プロセスとは、本質的に以下を実行することです。

  1. Debian システムはランレベル N (無し) に入り、"/etc/inittab" の記述にしたがいシステムを初期化します。

  2. Debian システムはランレベル S に入り、シングルユーザーモード下でハードウエアーの初期化等を完了するシステム初期化をします。

  3. Debian システムは指定されたマルチユーザーランレベル (2〜5) の内の1つに入り、システムサービスをスタートします。

マルチユーザーモードで使われる最初のランレベルランレベルは、"init=" というカーネルブートパラメーターもしくは "/etc/inittab" の"initdefault" 行で指定されます。インストールされたままの Debian システムはランレベル 2 でスタートします。

init システムが実行する全ての実際のスクリプトファイルは "/etc/init.d/" ディレクトリーの中にあります。

詳細説明は、 init(8)inittab(5) と "/usr/share/doc/sysv-rc/README.runlevels.gz" を参照ください。

ランレベルはその設定に1つのディレクトリーを使い次に記す特定の意味があります。


コンソールからランレベルを、例えば4に、次のようにして変更できます。

$ sudo telinit 4
[注意] 注意

Debian システムは2から5のランレベル間で如何なる意味の違いも事前に付与しません。Debian システムのシステム管理者はこれに変更を加えられます。(つまり Debian は、Red Hat Linux とも Sun Microsystems 社の Solaris とも Hewlett Packard 社の HP-UX とも IBM 社の AIX とも…違います。)

[注意] 注意

Debian システムは7から9のランレベルに対応するディレクトリーをパッケージインストール時に充足することはありません。伝統的な Unix バリアントはこれらのランレベルを使いません。

init(8)telinit(8) コマンドがランレベルを "<n>" に変更すると、システムは基本的に次のスクリプトを実行します。

  1. "/etc/rc<n>.d/" 中の "K" で始まるスクリプト名が、"stop" のみを引数としてアルファベット順に実行されます。(サービス停止)

  2. "/etc/rc<n>.d/" 中の "S" で始まるスクリプト名が、"start" のみを引数としてアルファベット順に実行されます。(サービス開始)

例えば、ランレベルのディレクトリーに "S10sysklogd" と "S20exim4" があった時に、"../init.d/exim4" にシムリンクされた "S20exim4" の前に、"../init.d/sysklogd" にシムリンクされた "S10sysklogd" が実行されます。

この単純なシーケンシャル初期化システムは古典的 System V スタイルのブートシステムで、 Debian lenny システムまで使われていました。

これに代わり、最近の Debian システムでは初期化スクリプトを同時並行で実行するように最適化されています。

[警告] 警告

メンテナよりあなたのほうが知識があるのでもなければ "/etc/rcS.d/" の中のシムリンクに変更を加えようとするのはお勧めできません。

例えば、次に示す Red Hat Linux のようなランレベルを設定してみます。

  • init はデフォールトとしてランレベル =3 でシステムを起動します。

  • init はランレベル =(0,1,2,6) で gdm3(1) を起動しません。

  • init はランレベル =(3,4,5) で gdm3(1) を起動します。

これは、"/etc/inittab" ファイルをエディターで変更して起動するランレベル変更し、sysv-rc-confbum 等の使いやすいランレベル管理ツールを使ってランレベルを編集することでできます。こうする代わりにコマンドラインだけを使うなら、(gdm3 パッケージをデフォールトでインストールしディスプレーマネージャーとして選択した後に) 次に示すようにします。

# cd /etc/rc2.d ; mv S21gdm3 K21gdm3
# cd /etc ; perl -i -p -e 's/^id:.:/id:3:/' inittab

xdmgdm3sddmwdm 等のディスプレーマネジャーデーモンを起動する際には "/etc/X11/default-display-manager" ファイルが確認されます。

[注記] 注記

startx(1) コマンドを使えば、どのコンソールシェルからも X が起動できます。

"/etc/init.d/" の中の各 init スクリプトのデフォールトパラメーターは、"/etc/default/" の中の環境変数のアサインメントのみを含む対応ファイルによって与えられます。このディレクトリー名の選択は Debian システム特定です。それは、Red Hat Linux や他のディストリビューションで使われる "/etc/sysconfig" ディレクトリーにほぼ相当します。例えば、"/etc/default/cron" を使うと "/etc/init.d/cron" がどう機能するかを制御できます。

"/etc/default/rcS" ファイルを使うと motd(5)sulogin(8) 等のブート時のデフォールトをカスタム化できます。

もしそのような変数の変更で希望の挙動が得られない場合には、init スクリプト自体を変更することができます。これらスクリプトは管理者が編集可能な設定ファイルです。

多くのネットワークサービス (6章ネットワークアプリケーション参照下さい) はブート時に、例えば "/etc/init.d/exim4" にシムリンクされている "/etc/rc2.d/S20exim4" (RUNLEVEL=2 の場合) 等という、マルチユーザーモード下の init スクリプトによってデーモンプロセスとして起動されます。

ネットワークサービスの一部はスーパーサーバーinetd (もしくはその同等) を用いて必要に応じて起動されます。inetd は、"/etc/init.d/inetd" にシムリンクされた "/etc/rc2.d/S20inetd" (RUNLEVEL=2 の場合) によってブート時に起動されます。基本的に、inetd は一つの実行デーモンにより複数の他デーモンを起動できるようにすることで、システムのロードを下げます。

サービス要求がスーパーサーバー inetd に到達する度に、そのプロトコルとサービスが "/etc/protocols" と "/etc/services" というデーターベースを照覧することで確認されます。さらに inetd は、"/etc/inetd.conf" の中にある通常のインターネットサービスか、"/etc/rpc.conf" の中にある Sun RPC 準拠サービスを照覧します。

時々、inetd が対象となるサーバーを直接起動せずに、対象となるサーバー名を "/etc/inetd.conf" 中に引数とし記載したTCP デーモンラッパープログラム tcpd(8) を起動することがあります。この様な場合には、tcpd は要求を記録し "/etc/hosts.deny" や "/etc/hosts.allow" を用いた追加確認後で適切なサーバープログラムを起動します。

システムのセキュリティーのためにできるだけ多くのネットワークサービスを無効にします。「サーバーのサービスへのアクセスの制限」を参照下さい。

inetd(8)inetd.conf(5)protocols(5)services(5)tcpd(8)hosts_access(5)hosts_options(5)rpcinfo(8)portmap(8) と "/usr/share/doc/portmap/portmapper.txt.gz" を参照下さい。

Linux カーネル 2.6以降 では、udev システムがハードウエアーの自動検出と初期化のメカニズムを提供します (udev(7) 参照下さい)。カーネルが各デバイスを発見すると、udev システムは sysfs ファイルシステム (「procfs と sysfs」参照下さい) からの情報を使いユーザープロセスを起動し、modprobe(8) プログラム (「カーネルモジュール初期化」参照下さい) を使ってそれをサポートする必要なカーネルモジュールをロードし、対応するデバイスノードを作成します。

[ヒント] ヒント

もし "/lib/modules/<kernel-version>/modules.dep" が何らかの理由で depmod(8) によって適正に生成されていなかった場合には、モジュールは udev システムによる期待にそってロードされないかもしれません。これを修正するには、"depmod -a" を実行します。

デバイスノード名は "/etc/udev/rules.d/" の中のファイルによって設定できます。現在のデフォールトのルールは、cd とネットワークデバイス以外は非静的なデバイス名となる動的生成名を作る傾向があります。cd やネットワークデバイスと同様のカスタムルールを追加することで USB メモリースティック等の他のデバイスにも静的なデバイス名を生成出来ます。"Writing udev rules" か "/usr/share/doc/udev/writing_udev_rules/index.html" を参照下さい。

udev システムは少々動くターゲットなので、詳細は他のドキュメントに譲り、ここでは最小限の記述に止めます。

[ヒント] ヒント

"/etc/fstab" 中のマウントルールでは、デバイス名が静的なデバイス名である必要がありません。"/dev/sda" 等のデバイス名ではなく UUID を使ってデバイスをマウントできます。「UUID を使ってパーティションをアクセス」を参照下さい。

modprobe(8) プログラムは、ユーザープロセスからカーネルモジュールを追加や削除することで実行中の Linux カーネルの設定を可能にします。udev システム (「udev システム」参照下さい) は、その起動を自動化しカーネルモジュールの初期化を補助します。

"/etc/modules" ファイル中にリストしてプリロードする必要のある (modules(5) 参照下さい) 次に記すような非ハードウエアーや特殊ハードウエアーのドライバーモジュールがあります。

modprobe(8) プログラムのための設定ファイルは、modprobe.conf(5) で説明されているように "/etc/modprobes.d/" ディレクトリーの下にあります。(あるカーネルモジュールが自動ロードされるのを避けるには、"/etc/modprobes.d/blacklist" ファイル中にブラックリストします。)

depmod(8) プログラムによって生成される "/lib/modules/<version>/modules.dep" ファイルは、modprobe(8) プログラムによって使われるモジュール依存関係を記述します。

[注記] 注記

ブート時に modprobe(8) を使ってのモジュールロードの問題に出会った場合には、"depmod -a" として "modules.dep" を再構築をするとこの様な問題が解消できるかもしれません。

modinfo(8) プログラムは Linux カーネルモジュールに関する情報を表示します。

lsmod(8) プログラムは "/proc/modules" の内容を読みやすい形式にして、どのカーネルモジュールが現在ロードされているかを表示します。

[ヒント] ヒント

あなたのシステム上の正確なハードウエアーを特定します。「ハードウエアーの識別」を参照下さい。

[ヒント] ヒント

ブート時に期待されるハードウエアー機能を有効となるように設定もできます。「ハードウエアー設定」を参照下さい。

[ヒント] ヒント

あなたのデバイスのサポートは、カーネルを再コンパイルすれば追加できます。「カーネル」を参照下さい。