ソースコード・リテラシーのススメ

第13回 起動の仕組みを読む

この記事を読むのに必要な時間:およそ 6.5 分

前回は/etc/rc.d/rc.sysinitという起動時に実行されるスクリプトを読んでみました。その際に簡単に触れたように,ほとんどのLinuxディストリビューションではsysvinitと呼ばれるソフトウェアを使ってシステムの起動処理を行っています。

sysvinitはSystemV initの略で,UNIX SystemV(システムファイブ)と呼ばれるAT&T社謹製の古典的なUNIXが採用した起動メカニズムと同じ動作をするように設計されたソフトウェアです。SystemV系のinitの特徴はランレベルという概念を持つことで,ランレベルの設定によりシステムの振舞いを柔軟に変えることができます。Linuxを始め,最近のほとんどのUNIX系OSではこのSystemV initを採用していますが,BSD系のUNIXではランレベルという概念を持たない独自のinitを伝統的に利用しています。

このsysvinitの処理を含めた起動時の流れを把握しておけば,何らかのトラブルが発生して正しく起動しなくなった場合にも原因追求が容易になるでしょう。そこで今回はsysvinitが起動するまでの流れを解説し,その際に使用される各種設定ファイルを読んでみます。

Linuxの起動の流れ

あらかじめお断りしておきますが,筆者はx86系(いわゆるIBM-PC互換機)以外のハードウェア(組み込み環境とか大型コンピュータとか)については無知なので,今回紹介する話題はx86系のハードウェアを前提とした話になります。カーネルの起動以後の処理はそれほど違いはないはずですが,カーネルをロードするための仕組みはハードウェア環境に大きく依存しているため,組み込み用のLinuxや大型コンピュータ用のLinuxでは今回紹介するgrubとは異なる,それぞれ独自の仕組みが用意されているはずです。本連載ではそれらについては扱わないので別途適切な資料を探してください。

さて,いわゆるPC互換機の環境では,システムの起動は「ブートローダ段階」,「カーネル段階」,「/sbin/init段階」の3つのステップに分けることができます。ブートローダ段階とは,電源ONからliloやgrubといったブートローダソフトウェアが起動し,指定されたカーネルイメージをメモリに読み込む段階,カーネル段階とはメモリ上に読み込まれたカーネルが起動し,CPUやメモリ,周辺機器の認識や初期化を行う段階,/sbin/init段階とはハードウェアの初期化を終えたカーネルから処理を委ねられた/sbin/initが/etc/inittabの設定に従ってシステムの動作に必要な各種サービスを起動していく段階を言います。以下ではこれら3つのステップそれぞれについて,制御する設定ファイルなどを読みながら紹介していくことにします。

ブートローダ段階

PC互換機の電源を入れると,まずマザーボード上のフラッシュメモリに書き込まれたBIOS(Basic Input/Output System)と呼ばれるソフトウェアが動き始めます。BIOSはマザーボード上のCPUやメモリ,接続されている各種拡張カードを認識,初期化していきます。接続されたハードウェアの初期化処理を完了すると,最初のHDDの先頭のセクタMBR:マスターブートレコードに書き込まえたソフトウェアを起動して以後の処理を委ねます。このMBRの512バイトの部分に書き込まれているのがブートローダと呼ばれるソフトウェアです。

MS-DOSの時代には,BIOSはBasic Input/Output Systemの名称の通り,画面表示やハードディスクの読み書きなど,接続されているさまざまなメーカ製のハードウェアに対する操作を抽象化するために使われていました。しかし,BIOSはもともと16ビットCPU用に設計されているため,LinuxやWindows 95以降の32ビットCPU用のOSからは使用しづらく,それらのOSではBIOSを利用せずに直接ハードウェアを操作するようになったため,現在のBIOSは電源投入直後の周辺機器の初期化のためにのみ使われる程度になっています。一方,最近ではBIOSに代るEFI(Extensible Firmware Interface)と呼ばれる新しい規格が提案され,Intel版MacやIA-64(Itanium)など過去との互換性がそれほど重視されない環境ではPC互換機に先駆けて採用されています。

ブートローダはOSごとに異なり,Linuxの中でもliloやgrubなどいくつかの種類がありますが,今回は最も広く使われているgrubを取りあげます。

grubは起動するカーネルやカーネルパラメータを対話的なメニューから指定したり,さまざまな種類のファイルシステムを理解してカーネルをファイル名で読み出すことができるなど高機能なブートローダです。一方,MBRは512バイト分しか使えないので大規模なソフトウェアを保存することはできません。そのためgrubでは機能を分割し,本来の機能はstage2と呼ばれる部分に置いてファイルシステム上に保存し,MBRにはstage2を読み込むだけの機能を持ったstage1と呼ばれる部分を置くようになっています。

stage2はカーネルをファイル名で読み込めますが,stage1はstage2をHDD上の物理的な位置情報を用いて(BIOS経由で)読み込みます。そのためcpやmvでstage2の位置を変更すると,ファイルは存在していてもstage1が正しくstage2を読み込めなくなり,grubの起動に失敗することがあります。

MBR上のstage1がHDD上のstage2を正しく読み込めば,stage2はgrub.confという設定ファイルを使って起動メニューを表示します。以下では前回同様,Fedora Core9のβ版の環境を元に設定ファイルの内容を紹介します(リスト1)。Fedora Coreではgrub.confは/boot/grub/grub.confに実体が置かれ,/etc/grub.confにそこへのシンボリックリンクが置かれています。

リスト1 grub.confの内容

 1  # grub.conf generated by anaconda
 2  #
 3  # Note that you do not have to rerun grub after making changes to this file
 4  # NOTICE:  You have a /boot partition.  This means that
 5  #          all kernel and initrd paths are relative to /boot/, eg.
 6  #          root (hd0,0)
 7  #          kernel /vmlinuz-version ro root=/dev/VolGroup00/LogVol00
 8  #          initrd /initrd-version.img
 9  #boot=/dev/sda
10  default=0
11  timeout=5
12  splashimage=(hd0,0)/grub/splash.xpm.gz
13  #hiddenmenu
14  
15  title Fedora (2.6.25-0.163.rc7.git1.fc9.i686)
16          root (hd0,0)
17          kernel /vmlinuz-2.6.25-0.163.rc7.git1.fc9.i686 ro root=/dev/VolGroup00/LogVol00 rhgb quiet
18          initrd /initrd-2.6.25-0.163.rc7.git1.fc9.i686.img
19  title Fedora (2.6.25-0.121.rc5.git4.fc9)
20          root (hd0,0)
21          kernel /vmlinuz-2.6.25-0.121.rc5.git4.fc9 ro root=UUID=7b908992-10bd-46d3-95b6-1e04548399ed rhgb quiet
22          initrd /initrd-2.6.25-0.121.rc5.git4.fc9.img

grub.confも他のほとんどの設定ファイル同様,#(シャープ)以降は行末までコメントと解釈されるので,1行目から9行目,13行目はコメントとして無視されます。コメント以外の部分は大きく2つに分けることができ,10行目から12行目がgrubの動作全体を制御する設定,15行目からが起動すべきカーネルごとの設定になります。

10行目のdefault=0は,起動すべきカーネルが指定されなかった場合に起動するカーネルの指定で,数字はtitle行で指定された順番を意味し,0 ならば最初に現われたtitle行(今回は15行目)のカーネルを起動します。

timeout=5はメニュー画面を5秒間表示する指定,splashimage=(hd0,0)/grub/splash.xpm.gzはメニュー画面の背景に表示する画像ファイルの指定です。ここにも出てきていますが,grubではHDDやパーティションを/dev/hda1のような形ではなく,(hd0,0)(最初のHDDの最初のパーティション)の形式で指定しますのでご注意ください。

15行目からが起動すべきカーネルの設定で,15行目から18行目と19行目から22行目がそれぞれ異なる2つのカーネルを起動するための設定になります。

title行はgrubのメニュー画面に表示されるメッセージになると同時に,起動すべきカーネルとその設定を区別するためのラベルになります。

root行はルートパーティションになるパーティションの指定で,今回の例では(hd0,0)で最初のHDDの最初のパーティションを指定しています。この設定によりカーネルのファイル名を/vmlinuz-2.6.25.0...のように,パス名で指定できるようになります。

最近のfedoraでは,インストーラの自動設定でLinux用のパーティションを作成すると,カーネルや起動用ramdisk(initrd)を保存するための200Mバイトほどのパーティションを最初に確保した上で,残りはLVM用のボリュームグループに割りあてるようになっています。確保された最初のパーティション(grubで言う(hd0,0))はハードディスク上の物理的なパーティションなのでgrubから直接読み出すことができますが, 残りの部分はカーネルのLVM機能を利用しないと読み出すことができません。

kernel行は起動するカーネルの指定で,(hd0,0)で指定されたパーティションの直下にあるカーネルイメージファイル/vmlinuz-2.6.25-0.163.rc7.git1.fc9.i686をメモリに読み込むことを指定しています。カーネルのファイル名の指定以降は読み込んだカーネルに渡すパラメータの設定で,ルートファイルシステムとそのマウント方法(ro root=/dev/VolGroup00/LogVol00),起動時にはグラフィカルなブート画面を表示し(rhgb),詳しいメッセージは表示しない(quiet)ことをカーネルに指示しています。

/dev/VolGroup00/LogVol00は最近のFedoraで採用されているLVM(Logical Volume Manager)上のファイルシステムの指定です。LVMとは従来のようにHDD上の物理的なパーティションを直接指定するのではなく,物理的なパーティションを抽象化した論理ボリューム上にファイルシステムを構築する仕組みです。LVMを使えば論理ボリュームを追加することでファイルシステムを必要に応じて拡張することが可能です。

また,ルートファイルシステムは21行目のようにUUID=7b908992..のように,そのファイルシステムを作成する時に付けたID番号で指定することも可能です。

initrd行はカーネルと共に読み込む初期化用ramdisk(INITtial RamDisk)イメージの指定で,上記の例ではカーネルと同じ場所にある/initrd-2.6.25-0.163.rc7.git1.fc9.i686.imgというファイルを指定しています。この初期化用ramdiskはシステムのインストール時に作成され,HDDやルートファイルシステムを読み込む際に必要となるモジュールドライバが組み込まれています。

grubはこの設定ファイルに従って指定されたカーネルと initrdをメモリ上に読み込み,指定されたパラメータをカーネルに渡して以後の処理をカーネルに委ねます。

著者プロフィール

こじまみつひろ

Plamo Linuxとりまとめ役。もともとは人類学的にハッカー文化を研究しようとしていたのが,いつの間にかミイラ取りがミイラになってOSSを仕事にするようになってしまいました。最近はスペシャリスト養成を目的とした専門職大学院で教壇に立ったりもしています。

URLhttp://www.linet.gr.jp/~kojima/Plamo/index.html

コメント

コメントの記入