注意 | |
---|---|
このセクションではとくにx86ブートプロセスについて検討します。 ユーザーのシステムのアーキテクチャによっては、ユーザーのブートプロセスがわずかに違うことがあります。 しかし、システムがカーネルを見つけてロードすれば、デフォルトのRed Hat Linuxブートプロセスはすべてのアーキテクチャでまったく同じです。 x86でないブートプロセスの詳細についてはthe section called 他のアーキテクチャの起動プロセスにおける違いを参照してください。 |
コンピュータをブートするとき、プロセッサはシステムメモリの最後部で BIOS (Basic Input/Output System)を検索し、実行します。 BIOSプログラムは読み込み専用の不揮発メモリに書き込まれ、いつでも実行可能な状態になっています。 BIOSは周辺機器に対する最低レベルのインタフェースを提供し、ブートプロセスの最初のステップを制御します。
BIOSはシステムをテストし、周辺機器の検索とチェックを行ない、つづいてシステムをブートするために使用するドライブを調べます。 BIOSは通常、フロッピーディスクドライブ(最近のシステムではCD-ROMドライブも)が存在すればそれをチェックし、次にハードディスクドライブを調べます。 ブートするために使用されるドライブの順序は、通常、そのシステム上の具体的なBIOS設定によって制御されます。 Red Hat Linuxがシステムのハードディスクドライブにインストールされていると、BIOSは、先頭ハードディスクドライブの先頭セクタから マスタブートレコード (MBR)の検索を開始し、その内容をメモリにロードし、それに制御を渡します。
ついでこのMBRコードは先頭のアクティブパーティションを探し、そのパーティションのブートレコードを読み込みます。 ブートレコードには、ブートローダー、つまり LILO ( LI Nux LO ader)のロード方法に関する命令が含まれています。 (MBRにLILOがインストールされていれば)、MBRは次にLILOをロードし、LILOはこのプロセスを引き継ぎます。 デフォルトのRed Hat Linux設定では、LILOはMBRの設定に基づいてブートオプションを表示し、実際に起動するオペレーティングシステムについてユーザー入力によって決めさせます。
しかしこの場合、MBRが読み込まれたときに何をするかということをMBR内のLILOがどのようにして知るかということが問題になります。 実は、LILOはすでに Lilo と /etc/lilo.conf 設定ファイルを使って、そこに命令を書き込んでいるのです。
新しくインストールしたオペレーティングシステムをブートしなければならない場合や、新しいカーネルを使用するような場合を除いて、ハードディスクドライブ上のマスタブートレコードを変更する必要はほとんどないでしょう。 LILOを使用するが別の設定を使用する新しいMBRを作成する必要が生じた場合は、 /etc/lilo.conf を編集し、再度 Lilo を実行しなければなりません。
警告 | |
---|---|
もし /etc/lilo.conf を編集するのであれば、少しでも変更を加える前に必ずこのファイルのバックアップコピーを作成しておきます。 また必ず作業用ブートフロッピーを用意しておき、問題がある場合にシステムをブートしてMBRに変更を加えることができるようにしておきます。 ブートディスクの作成に関する詳細については、マニュアルの Mkbootdisk に関するページを参照してください。 |
ファイル /etc/lilo.conf は Lilo コマンドで使用されます。これによって、どのオペレーティングシステムを利用するか、どのカーネルを起動するかが決められ、またシステムのインストール先が決められます(たとえば先頭のIDEハードディスクドライブである /dev/had など)。 サンプルファイル /etc/lilo.conf は以下のようになっています。
boot=/dev/had map=/boot/map install=/boot/boot.b Prompt timeout=50 message=/boot/message lba32 default=linux image=/boot/vmlinuz-2.4.0-0.43.6 label=linux initrd=/boot/initrd-2.4.0-0.43.6.img read-only root=/dev/hda5 other=/dev/hda1 label=dos |
この例は、2つのオペレーティングシステム、Red Hat LinuxとDOSをブートするように設定されているシステムを示しています。 以下に、このファイルの数行をもっと詳しく調べてみましょう(ユーザーの /etc/lilo.conf はすこし違うかもしれません)。
boot=/dev/had は、最初のIDEコントローラで先頭のハードディスクを調べるように、LILOに指示しています。
Map=/boot/map はマップファイルの場所を示します。 通常、このファイルを変更してはいけません。
install=/boot/boot.b は、指定したファイルを新しいブートセクターとしてインストールするように、LILOに指示します。 通常、このファイルを変更してはいけません。 Install 行がないと、LILOは、デフォルトの /boot/boot.b を使用すべきファイルとみなします。
Prompt が存在すると、LILOは、 Message 行で参照されるものをすべて表示します。 Prompt 行の除去はお勧めできませんが、この行が除去されている場合には、マシンのブート中 Shift キーを押し下げておくと、promptの機能が実行されます。
timeout=50 は、LILOが Default 行エントリをブートする前にユーザー入力を待機する時間を設定します。 その単位は10分の1秒で、デフォルトは50です。
message=/boot/message は、ブートするオペレーティングシステムやカーネルをユーザーに選択させるために表示するスクリーンを示します。
lba32 は、ハードディスクのジオメトリをLILOに教えます。 ここで別の一般的エントリ、 Linear があります。 自分のしていることの意味をよくわかっているユーザー以外は、この行を変更してはいけません。 これを変更すると、システムがブート不可能な状態になってしまうおそれがあります。
default=linux は、LILOがこの行の後にリストされているオプションからデフォルトでブートするオペレーティングシステムを示します。 Linux というネームは、各ブートオプションの後にある Label 行を示します。
image=/boot/vmlinuz-2.4.0-0.43.6 は、linuxカーネルに対してこのブートオプションでブートするように指示します。
label=linux は、LILO画面内のオペレーティングシステムオプションを指定します。 これはまた Default 行によって参照されるネームでもあります。
initrd=/boot/initrd-2.4.0-0.43.6.img は、ブート時にカーネルのブートを可能にするデバイスを実際に初期化して起動するために使用される イニシアルラムディスク イメージを示します。 イニシアルラムディスクは、ハードディスクドライブを操作するために必要な、マシン固有のドライバとカーネルをロードするために必要な一切のものを含んでいます。 イニシアルラムディスクは、相互のハードウェア構成がまったく同一である場合以外は、複数のマシンで共有してはなりません({ハードウェア構成が}同一の場合でもやはり好ましくないことです)。
read-only は、ルートパーティションが変更不可能で、読み込み専用のものであると指定します(次の Root 行を参照)。
Root=/dev/hda5 は、どのディスクパーティションをルートパーティションとして使用するかをLILOに指示します。
次にLILOは、ブートするように設定されている別のオペレーティングシステムまたはカーネルのRed Hat Linux初期画面を表示します。 Red Hat Linuxだけしかインストールされていず、 /etc/lilo.conf にいっさい変更が加えられていない場合は、 Linux が唯一のオプションとして表示されます。 他のオペレーティングシステムもブートできるようにLILOをセットアップしている場合は、この画面でどのオペレーティングシステムをブートするかを選ぶことになります。 ブートしようとするオペレーティングシステムを矢印キーで強調表示にし、 Enter キーを押します。
LILOに対するコマンドをコマンドプロンプトで入力したい場合は、 Cntl-X キーを押します。 LILOは画面に LILO: プロンプトを表示し、既定の時間のあいだユーザーによる入力を待機します。 (LILOが待機する時間は /etc/lilo.conf ファイルの Timeout 行で設定されます。) ユーザーの /etc/lilo.conf がLILOでオペレーティングシステムを選択できるように設定されていると、ここでブートしようとするオペレーティングシステムのラベルを入力することができます。
LILOが Linux をブートする場合は、まずカーネルがメモリにロードされますが、そのカーネルは /boot ディレクトリにある Vmlinuz ファイル(これにバージョンナンバーがついて、例えば) located in the Vmlinuz-2.4.0-xx など)です。 つづいてカーネルは制御を Init に渡します。
この時点で、カーネルがメモリにロードされて作動状態になり、Linux が非常に基礎的なレベルですが始動しています。 しかし、カーネルを利用しているアプリケーションはなく、ユーザーはシステムに対して何らか意味ある入力を行なうことができず、この段階でできることは非常に限られています。 Init プログラムが、システムがその役割をはたすことをサポートする、各種のサービスを起動することによって、この問題を解決します。
カーネルは Init を /sbin で見つけ、それを実行します。これ以後は Init がひきついでブートプロセスを処理します。
Init が始動すると、それは、ユーザーのRed Hat Linuxシステム上で自動的に起動するすべてのプロセスの親または親の親になります。 それはまず、 /etc/rc.d/rc.sysinit スクリプトを実行します。これはパスの設定、スワッピングの開始、ファイルシステムのチェックなどを実行します。 基本的に rc.sysinit は、システム初期化時に行なっておく必要のあるすべてのことを取り扱います。 たとえば、ネットワークに接続したシステムの場合、 rc.sysinit は /etc/sysconfig/network ファイルの情報を使用してネットワークプロセスを初期化します。 ほとんどのシステムはクロックを使用するので、 rc.sysinit は /etc/sysconfig/clock ファイルを使用してクロックを初期化します。 初期化する必要のあるシリアルポートがある場合には、 rc.sysinit が Rc.serial を実行することもあります。
次に Init は、 /etc/inittab スクリプトを実行します。このファイルには、各 ランレベル でシステムをどのようにセットアップするかが記述され、デフォルトのランレベルが設定されています。 (init ランレベルの詳しいことについてはthe section called Init実行レベル を参照してください。) このファイルには、ランレベルの開始時には必ず /sbin/update を実行する必要があることが記述されています。 Update プログラムは、変更されたデータを含むバッファをディスクへフラッシュバックします。
ランレベルが変化すると、 Init は /etc/rc.d/init.d のスクリプトを使用して、ユーザーのウェブサーバやDNSサーバなどのような様々なサービスの起動と停止を必ず行ないます。 まず、 Init はシステム用のソースファンクションライブラリを設定します(一般には /etc/rc.d/init.d/functions )。このライブラリには、プログラムをStart/Killする方法やプログラムのPIDを見つける方法が記述されています。 次に、 Init は現在のランレベルと直前のランレベルを調べます。
つづいて、 Init は、そのランレベル用の Rc ディレクトリ( /etc/rc.d/rc <x> .d − < X > は0-6の番号が付いている)を検索して、システムが動作するために必要なバックグラウンドプロセスをすべて起動します。 Init はあらゆるKillスクリプト(ファイル名は K で始まっている)を Stop パラメータで実行します。 次に、 Init は適切なランレベルディレクトリのすべてのStart スクリプト(ファイル名は S で始まっている)を Start で実行し、こうしてすべてのサービスとアプリケーションが正しく起動されます。 また、システムのブートが終了してから、ルートとしてログインする /etc/rc.d/init.d/httpd stop や service httpd stop のようなコマンドによって、これらの同じスクリプトを手動で実行することができます。 これで Httpd サーバを停止します。
注意 | |
---|---|
サービスを手動で起動するとき、ユーザーはルートでなければなりません。 service httpd stop を実行するとエラーになるのであれば、/root/.bashrc (あるいはユーザー常用シェルのための正しい.rc )に/sbin をパッチしていないかもしれません。 /sbin/service httpd stop という完全なコマンドを入力するか、あるいはexport PATH="$PATH:/sbin"をユーザーのシェル.rcファイルに追加しなければなりません。 ユーザーのシェル設定ファイルを編集する場合は、ログアウトしてからルートとしてログインして、変更したシェル設定ファイルを有効にします。 |
サービスの起動と停止を行なうスクリプトはいずれも、実際には/etc/rc.d/init.dには存在しません。 /etc/rc.d/rc<x>.d中のすべてのファイルは、/etc/rc.d/init.d中に存在する実際のスクリプトを指すシンボリックリンクです。 シンボリックリンクは別のファイルを指しているファイルにすぎません。シンボリックリンクがここで利用されているのは、これらを作成したり、削除したりしても、サービスのKillやStartを行なう実際のスクリプトに影響が及ばないからです。 さまざまなスクリプトに対するシンボリックリンクは特定の順序で番号が付いており、それらのスクリプトはその順序でStartします。 サービスのStartやKillを実際に行なうスクリプトを指示するシンボリックリンクの名前を変えることによって、サービスがStartしたり、Killされたりする順序を変更することができます。 特定のサービスを別のサービスの直後や直前に起動したり、停止したりする場合は、当該のサービスのシンボリックリンクに別のサービスのシンボリックリンクと同じ番号を与えます。
たとえばランレベル5の場合、initが/etc/rc.d/rc5.dディレクトリを調べ、以下のような内容を見いだすかもしれません(ユーザーのシステムと設定によって異なります)。
K01pppoe -> ../init.d/pppoe K05innd -> ../init.d/innd K10ntpd -> ../init.d/ntpd K15httpd -> ../init.d/httpd K15mysqld -> ../init.d/mysqld K15pvmd -> ../init.d/pvmd K16rarpd -> ../init.d/rarpd K20bootparamd -> ../init.d/bootparamd K20nfs -> ../init.d/nfs K20rstatd -> ../init.d/rstatd K20rusersd -> ../init.d/rusersd K20rwalld -> ../init.d/rwalld K20rwhod -> ../init.d/rwhod K25squid -> ../init.d/squid K28amd -> ../init.d/amd K30mcserv -> ../init.d/mcserv K34yppasswdd -> ../init.d/yppasswdd K35dhcpd -> ../init.d/dhcpd K35smb -> ../init.d/smb K35vncserver -> ../init.d/vncserver K45arpwatch -> ../init.d/arpwatch K45named -> ../init.d/named K50snmpd -> ../init.d/snmpd K54pxe -> ../init.d/pxe K55routed -> ../init.d/routed K60mars-nwe -> ../init.d/mars-nwe K61ldap -> ../init.d/ldap K65kadmin -> ../init.d/kadmin K65kprop -> ../init.d/kprop K65krb524 -> ../init.d/krb524 K65krb5kdc -> ../init.d/krb5kdc K75gated -> ../init.d/gated K80nscd -> ../init.d/nscd K84ypserv -> ../init.d/ypserv K90ups -> ../init.d/ups K96irda -> ../init.d/irda S05kudzu -> ../init.d/kudzu S06reconfig -> ../init.d/reconfig S08ipchains -> ../init.d/ipchains S10network -> ../init.d/network S12syslog -> ../init.d/syslog S13portmap -> ../init.d/portmap S14nfslock -> ../init.d/nfslock S18autofs -> ../init.d/autofs S20random -> ../init.d/random S25netfs -> ../init.d/netfs S26apmd -> ../init.d/apmd S35identd -> ../init.d/identd S40atd -> ../init.d/atd S45pcmcia -> ../init.d/pcmcia S55sshd -> ../init.d/sshd S56rawdevices -> ../init.d/rawdevices S56xinetd -> ../init.d/xinetd S60lpd -> ../init.d/lpd S75keytable -> ../init.d/keytable S80isdn -> ../init.d/isdn S80sendmail -> ../init.d/sendmail S85gpm -> ../init.d/gpm S90canna -> ../init.d/canna S90crond -> ../init.d/crond S90FreeWnn -> ../init.d/FreeWnn S90xfs -> ../init.d/xfs S95anacron -> ../init.d/anacron S97rhnsd -> ../init.d/rhnsd S99linuxconf -> ../init.d/linuxconf S99local -> ../rc.local |
これらのシンボリックリンクはinitに、以下のプロセスをkillする必要があると指示します。 Pppoe 、 Innd 、 Ntpd 、 Httpd 、 Mysqld 、 Pvmd 、 Rarpd 、 Bootparamd 、 Nfs 、 Rstatd 、 Rusersd 、 Rwalld 、 Rwhod 、 Squid 、 Amd 、 Mcserv 、 Yppasswdd 、 Dhcpd 、 Smb 、 Vncserver 、 Arpwatch 、 Named 、 Snmpd 、 Pxe 、 Routed 、 Mars-new 、 Ldap 、 Kadmin 、 Kprop 、 Krb524 、 Krb5kdc 、 Gated 、 Nscd 、 Ypserv 、 Ups 、 Irda 。 すべてのプロセスがkillされると、initは同じディレクトリを除いて以下のプロセスのスタートスクリプトを検索します。 Kudzu 、 Reconfig 、 Ipchains 、 Portmap 、 Nfslock 、 Autofs 、 Random 、 Netfs 、 Apmd 、 Identd 、 Atd 、 Pcmcia 、 Sshd 、 Rawdevices 、 Xinetd 、 Lpd 、 Keytable 、 Isdn 、 Sendmail 、 Gpm 、 Canna 、 Crond 、 FreeWnn 、 Xfs 、 Anacron 、 Rhnsd 、 Linuxconf 。 最後にinitは/etc/rc.d/rc.localを実行し、このホストのために設定された特別なスクリプトがあれば実行させます。 この時点ではシステムはランレベル5と考えられます。
initがすべてのランレベルを経過すると、/etc/inittabは各ランレベル用の仮想コンソール(ログインプロンプト)についてgettyプロセスをフォークします(ランレベル2〜5では6個すべてを取得します。シングルユーザーモードであるランレベル1は、コンソールを1つだけ獲得します。ランレベル0と6は仮想コンソールを獲得しません。) 基本的に、gettyはttyラインを開き、そのモードを設定し、ログインプロンプトをプリントし、ユーザー名を取得し、そしてそのユーザーのログインプロセスを始動します。 これにより、ユーザーはシステムへの認証を獲得し、システムを使用できるようになります。
また/etc/inittabはinitに、コンソールでユーザーがCtrl-Alt-Deleteキーを打った場合の対処のしかたを指示します。 Red Hat Linuxではそのような場合すぐに電源切断−再投入を行わず、適切にシャットダウン−リスタートを適切に行わなければならないので、ユーザーがこれらのキーをたたくと、init に対しコマンド/sbin/shutdown -t3 -rnowを実行するように指示されます。 さらに、/etc/inittabには、システムにUPSユニットが接続されている場合、電源故障発生時にinitがなすべきことが書かれています。
ランレベル5では、/etc/inittabは/etc/X11/prefdmというスクリプトを実行します。 prefdmスクリプトは、/etc/sysconfig/desktopディレクトリの内容に基づき、優先のXディスプレイマネジャー(ユーザーがGNOMEを実行中であればgdm、KDEを実行中ならkdm、AnotherLevelを実行中であればxdm)を実行します。
ここではユーザーはログインプロンプトによく注意していなければなりません。 これらすべてのことが行われるのに2,3秒しかかからないのです。
これまで見てきたようにinitプログラムはブート時にカーネルによって実行されます。 このプログラムの仕事は、システムと一緒に立ち上げなければならないノーマルなプロセスのすべてを起動することです。 このようなプロセスにはユーザーをログインさせるgettyプロセス、NFSデーモン、FTPデーモン、その他ユーザーがマシンのブート時に実行しようとするものがすべて含まれます。
SysV initはLinuxワールドで標準の、ブート時のソフトウェアの起動を制御するプロセスです。(標準になっているのは)従来のBSDinitよりもパワフルブでフレキシブルだからです。
SysV initは設定ファイルが直接/etcに常駐しているのではなく/etc/rc.dに入っているという点でも、BSD initと違います。 /etc/rc.dにはrc、rc.local、rc.sysinit、さらに以下のディレクトリがあります。
init.d rc0.d rc1.d rc2.d rc3.d rc4.d rc5.d rc6.d |
SysV initは、各intランレベルをそれぞれ独立のディレクトリで表し、実際にシステムがランレベル間を移動するときに、各ディレクトリの中のinitとシンボリックリンクを使ってサービスの停止/起動を行います。
要約すれば、SysV initブートのためのイベントチェーンは以下のようになります。
カーネルが/sbinの中でinitを検索する
initが/etc/rc.d/rc.sysinitスクリプトを実行する
rc.sysinitがブートローダーのプロセスの大部分を処理した後、(あれば)rc.serialを実行する
initがデフォルトランレベルのすべてのスクリプトを実行する
initが/etc/rc.d/rc.localを実行する
デフォルトランレベルは/etc/inittab内に指設定されています。 先頭付近に以下のような行があるはずです。
id:3:initdefault: |
この例ではデフォルトランレベルは最初のコロンの後ろの数字、つまり3です。 変更したい場合は、/etc/inittabを手作業で編集することができます。 inittabファイルを編集する際には十分注意してください。 ミスをした場合には、再起動し、Cntl-Xキーでboot:プロンプトにアクセスし、以下のように入力すれば修正することができます。
boot: Linux single |
こうすれば当然シングルユーザーモードで起動するはずですから、inittabを再度編集して元の値に戻すことができます。
次に、起動時にさまざまなシステムサービスに使用されるパラメータを定義している、/etc/sysconfig内のファイルに含まれる情報について検討します。