この連載も,いよいよ最終回となりました。これまでの連載で,Linuxカーネルの構造とさまざまな機能に関して解説してきました。最後に,Linuxの起動処理について解説します。

 起動処理の解説を最終回に持ってきたのは,偶然ではありません。というのも起動処理は,これまで解説してきた機能とは本質的に異なる面があるからです。

 例えば,これまで解説してきた機能は,いわばカーネルが「通常の状態」で提供する機能です。これに対し,起動処理は起動時にしか実施されない特別な処理です。Linuxが動作するときに一度は実施する処理ですが,一度だけしか行わない処理でもあります。

 また,Linuxカーネルはイベント駆動型のソフトウエアだと連載の最初の回で解説しました。つまり,自ら能動的には動作せず,ユーザー・プロセスからのシステム・コールや,ハードウエアからの割り込みによって動作するソフトウエアなのです。しかし起動処理は唯一,Linuxカーネルが能動的に実施する処理です。そういう意味でも非常に例外的であると言えるでしょう。

起動処理の概略

 Linuxが起動するときに,最初に動作するプログラムがカーネルです。カーネルはハードウエアやメモリーの初期化処理を行い,ユーザーのアプリケーションを動かす環境を整えます。Linuxカーネルの仕事は,ハードウエアを制御し,アプリケーションの実行環境を整えることです。この仕事を行うには,どのプログラムよりも早く,カーネルが動き始めなければなりません。システムが起動するときに最初に動作して,さまざまな初期化処理を行う必要があるからです。

 初期化処理を終えた後,カーネルは「init」というプロセスを起動します。initにはプロセス番号1が割り当てられ,以後に作成されるすべてのプロセスの親(祖先)になります。initは初期化スクリプトを実行し,各種デーモンの起動などを行います。最終的に画面にログイン・プロンプトが表示され,システムの起動が完了します。カーネルが自発的に仕事を行うのは,このinitの起動までです.init起動後は,システム・コールや割り込みなどによって受動的に仕事をします。

カーネルが動き始めるまで

 カーネルはLinuxが起動するときに一番初めに動くプログラムであると書きましたが,厳密に言うとこれは間違いです。カーネルも単なるソフトウエアですから,これを稼動させるためのプログラムが別途必要になるのです。

 それでは,どのようにカーネルは起動されるのでしょうか。システムの起動処理は,ハードウエア・アーキテクチャによって大きく違いますので一概には言えません。そこでここでは,広く普及しているPC AT互換機を例に解説します。

 PC AT互換機では,コンピュータの電源を入れて最初に動くのは,BIOSというプログラムです。BIOSとは,Basic Input/Output Systemの略で,コンピュータのハードウエアに付属するソフトウエアです。名前の通り基本的な入出力機能を備えており,ディスプレイへの画像や文字の出力,キーボードからの入力などの処理を行うプログラムが含まれています。

 BIOSが動き始めると,まず初めにハードウエアがきちんと動くかどうか診断します。この動作を電源投入時自己診断テスト(Power On Self Test, POST)と言います。POSTが終わると,BIOSは,ハード・ディスクの先頭(Master Boot Record,MBR)に書き込まれているプログラムを起動します。

 このMBRには一般に,ブート・ローダーと呼ばれる「カーネルを読み込んで実行するためのプログラム」が書き込まれています。「そんな面倒なことしなくても,MBRに直接カーネルを置いて起動すればいいじゃないか」と思われるかもしれません。しかし,MBRの大きさは互換性を維持するために通常512バイトに制限されています。そのため非常に小さなプログラムしか書き込めません。

 そこで,ブート・ローダーという特別なプログラムが必要になるのです。ブート・ローダーは機能が限定されていますから,カーネルよりもサイズを小さくできます。といっても,ブート・ローダーのようなプログラムですら,512バイトにはなかなか収まりません。そこで,ほとんどのブート・ローダーでは,プログラム本体を読み込むための初期ローダーを用意し,それをMBRに書き込む方式を採用しています。

 Linuxでは主にLILO(Linux Loader)か,GNU GRUBのどちらかのブート・ローダーが利用されています。最近では,より便利で多機能なGNU GRUBの方が一般的に使われています。

 LILOもGNU GRUBも,起動するOSやカーネルをメニューで選択し分けたり,起動パラメータを入力できたりと豊富な機能を備えています。そのため,プログラム・サイズを512バイト以下にはできません。そこで,初期ローダーに当たるプライマリ・ブート・ローダーと,ブート・ローダー本体となるセカンダリ・ブート・ローダーにプログラムを分割しています。

 ブート・ローダーが呼び出すことで,やっとカーネルが起動します。ブート・ローダーは,カーネルがハード・ディスクのどの位置に保存されているかの情報を持っています。例えば,LILOの場合はハード・ディスクのセクター情報を,GNU GRUBの場合はファイル・システムのパス情報を保持しています。