![]() | 注意 |
|---|---|
ここではx86システムでのブートプロセスについて検討します。アーキテクチャによってはブートプロセスが違うことがありますが、システムがカーネルを見つけてロードすれば、デフォルトのRed Hat Linuxブートプロセスはすべてのアーキテクチャでまったく同じです。x86以外のシステムのブートプロセスについては他のアーキテクチャの起動プロセスにおける違い項を参照してください。 |
コンピュータをブートするとき、プロセッサはシステムメモリの最後部でBIOS(Basic Input/Output System)を検索し、実行します。BIOSプログラムは読み込み専用の不揮発メモリに書き込まれ、いつでも実行可能な状態になっています。BIOSは周辺機器に対する最低レベルのインターフェイスを提供し、ブートプロセスの最初のステップを制御します。
BIOSはシステムを検査し、周辺機器の検索とチェックを行い、システムをブートするために使用するドライブを調べます。BIOSは通常、フロッピーディスクドライブ(最近のシステムではCD-ROMドライブも)が存在すればそれをチェックし、次にハードディスクドライブを調べます。ブートするために使用されるドライブの順序は、通常、そのシステム上の具体的なBIOS設定によって制御されます。Red Hat Linuxがシステムのハードディスクドライブにインストールされていると、BIOSは、先頭ハードディスクドライブの先頭セクターからマスターブートレコード(MBR)の検索を開始し、その内容をメモリにロードし、制御を渡します。
このMBRには、インストールしたブートローダーに応じて、GRUB、LILO(LInux LOader)いずれかのロード方法に関する命令が含まれています。MBRにブートローダーがインストールされていれば、MBRは次にブートローダーをロードし、ブートローダーはこのプロセスを引き継ぎます。Red Hat Linuxのデフォルト設定では、GRUB、LILOのいずれかがMBRの設定に基づいてブートオプションを表示し、実際に起動するオペレーティングシステムについてユーザー入力によって決めさせます。
しかしこの場合、MBRが読み込まれたときに何をするかということをMBR内のブートローダーがどのようにして知るかということが問題になります。実は、LILOはすでにliloと/etc/lilo.conf設定ファイルを使って、そこに命令を書き込んでいるのです。GRUBも/boot/grub/grub.conf設定ファイルに命令を書き込んでいます。GRUBの詳細については、第5章を参照してください。
新しくインストールしたオペレーティングシステムをブートしなければならない場合や、新しいカーネルを使用するような場合を除いて、ハードディスクドライブ上のマスターブートレコードを変更する必要はほとんどないでしょう。LILOを使用するが別の設定を使用する新しいMBRを作成する必要が生じた場合は、/etc/lilo.confを編集し、再度liloを実行しなければいけません。
![]() | 警告 |
|---|---|
もし/etc/lilo.confを編集するのであれば、少しでも変更を加える前に必ずこのファイルのバックアップコピーを作成しておきます。また、必ず作業用ブートフロッピーディスクを用意しておき、問題がある場合にシステムをブートしてMBRに変更を加えることができるようにしておきます。ブートディスクの作成に関する詳細については、マニュアルのmkbootdisk関するページを参照してください。 |
ファイル/etc/lilo.confはliloコマンドで使用されます。これによって、どのオペレーティングシステムを利用するか、どのカーネルを起動するかが決められ、またシステムのインストール先が決められます(たとえばIDEハードディスクドライブの先頭のMBRでは/dev/hdaなど)。サンプルファイル/etc/lilo.confは以下のようになっています。
boot=/dev/hda 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/hda最初のIDEコントローラで先頭のハードディスクを調べるように、LILOに指示しています。
map=/boot/mapマップファイルの場所を示します。通常、このファイルを変更してはいけません。
install=/boot/boot.b指定したファイルを新しいブートセクターとしてインストールするように、LILOに指示します。通常、このファイルを変更してはいけません。install行がないと、LILOは、デフォルトの/boot/boot.bを使用すべきファイルとみなします。
prompt存在すると、LILOは、message行で参照されるものをすべて表示します。prompt行の削除はお勧めできませんが、この行がない場合には、マシンのブート中Shiftキーを押しっぱなしにすると、promtの機能が実行されます。
timeout=50LILOがdefault行エントリをブートする前にユーザー入力を待機する時間を設定します。その単位は10分の1秒で、デフォルトは50です。
message=/boot/messageブートするオペレーティングシステムやカーネルをユーザーに選択させるために表示する画面を示します。
lba32ハードディスクのジオメトリをLILOに教えます。ここで別の一般的エントリ、linearがあります。自分のしていることの意味をよくわかっているユーザー以外は、この行を変更してはいけません。これを変更すると、システムがブート不可能な状態になってしまうおそれがあります。
default=linuxLILOがこの行の後に一覧表示されているオプションからデフォルトでブートするオペレーティングシステムを示します。linuxというネームは、各ブートオプションの後にあるlabel行を示します。
image=/boot/vmlinuz-2.4.0-0.43.6linuxカーネルに対してこのブートオプションでブートするように指示します。
label=linuxLILO画面内のオペレーティングシステムオプションを指定します。これはまた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が唯一のオプションとして表示されます。SMPカーネルサポートをインストールしている場合には、オプションとしてlinux-upが表示されます。他のオペレーティングシステムもブートできるようにLILOをセットアップしている場合は、この画面でどのオペレーティングシステムをブートするかを選ぶことになります。ブートしようとするオペレーティングシステムを矢印キーで強調表示にし、Enterキーを押します。
LILOに対するコマンドをコマンドプロンプトで入力したい場合は、Ctrl-Xキーを押します。LILOは画面にLILO:プロンプトを表示し、既定の時間内はユーザーによる入力を待機します(LILOが待機する時間は/etc/lilo.confファイルのtimeout行で設定されます)。ユーザーの/etc/lilo.confがLILOでオペレーティングシステムを選択できるように設定されていると、ここでブートしようとするオペレーティングシステムのラベルを入力することができます。
LILOがLinuxをブートする場合は、まずカーネルがメモリにロードされますが、そのカーネルは/bootディレクトリにあるvmlinuzファイル(これにバージョンナンバーがついて、たとえば)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/clockファイルの情報を使用してクロックを初期化します。初期化する必要のあるシリアルポートがある場合には、rc.sysinitがrc.serialを実行することもあります。
次にinitは、/etc/inittabスクリプトを実行します。このファイルには、各ランレベルでシステムをどのようにセットアップするかが記述され、デフォルトのランレベルが設定されています(initランレベルの詳細についてはInitランレベル項を参照してください)。このファイルには、ランレベルの開始時には必ず/sbin/updateを実行する必要があることが記述されています。updateプログラムは、変更されたデータを含むバッファをディスクへフラッシュバックします。
ランレベルが変化すると、initは/etc/rc.d/init.dのスクリプトを使用して、ユーザーのWebサーバーやDNSサーバーなどのようなさまざまなサービスの起動と停止を必ず行います。まず、initはシステム用のソースファンクションライブラリを設定します(一般には/etc/rc.d/init.d/functions)。このライブラリには、プログラムを起動、停止する方法やプログラムのPIDを見つける方法が記述されています。次に、initは現在のランレベルと直前のランレベルを調べます。
続いて、initは、そのランレベル用のrcディレクトリ(/etc/rc.d/rc<x>.d、<x>は0-6の番号)を検索して、システムが動作するために必要なバックグラウンドプロセスをすべて起動します。initはあらゆるkillスクリプト(ファイル名はKで始まっている)をstopパラメータで実行します。次に、initは適切なランレベルディレクトリのすべてのstartスクリプト(ファイル名はSで始まっている)をstartで実行し、こうしてすべてのサービスとアプリケーションが正しく起動されます。また、システムのブートが終了してから、rootとしてログインする/etc/rc.d/init.d/httpd stopやservice httpd stopのようなコマンドによって、これらの同じスクリプトを手動で実行することができます。これでhttpdサーバーを停止します。
![]() | 注意 |
|---|---|
サービスを手動で起動するとき、ユーザーはrootでなければいけません。service httpd stopを実行するとエラーになるのであれば、/root/.bashrc(あるいは使っているシェルのための正 しい.rc)で、パスに/sbinを指定していないかもしれません。/sbin/service httpd stopという完全なコマンドを入力するか、あるいはexport PATH="$PATH:/sbin"をユーザーのシェルの.rcファイルに追加しなければいけません。ユーザーのシェル設定ファイルを編集する場合は、ログアウトしてからrootとしてログインして、変更したシェル設定ファイルを有効にします。 |
サービスの起動と停止を行うスクリプトはいずれも、実際には/etc/rc.d/rc<x>.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 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-nwe, 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 最後に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 -r nowを実行するように指示されます。さらに、/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で標準の、ブート時のソフトウェアの起動を制御するプロセスです。標準になっているのは従来のBSD initよりもパワフルでフレキシブルだからです。
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は、各initランレベルをそれぞれ独立のディレクトリで表し、実際にシステムがランレベル間を移動するときに、各ディレクトリの中の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ファイルを編集する際には十分注意してください
ブートローダーとしてLILOを使用している場合には、再起動し、Ctrl-Xキーを押してboot:プロンプトに切り替え、以下のように入力すればinittabファイルを修正することができます。
boot: linux single |
ブートローダーとしてGRUBを使用している場合には、以下のステップを実行すればinittabファイルを修正することができます。
グラフィカルGRUBブートローダー画面で、Red Hat Linuxブートラベルを選択し、eキーを押して編集します。
カーネル行に進み、eキーを押して編集します。
プロンプトが表示されたら、singleと入力して、Enterキーを押します。
カーネル情報が表示されているGRUB画面に戻ります。bキーを押してシステムを起動しシングルユーザーモードにします。
こうすれば当然シングルユーザーモードで起動するはずですから、inittabを再度編集して元の値に戻すことができます。
次に、起動時にさまざまなシステムサービスに使用されるパラメータを定義している、/etc/sysconfig内のファイルに含まれる情報について検討します。