Bootstrap

先達たちに、「どこからUnixをHackすれば良いのでしょうか?」と聞いた場合、「最初はlocoreからやん」と言う言葉が良く返ってくる。 自分も、その言葉に従ってlocore.sを見ていましたが、その途中いくつか疑問がわいてきました。それは、次のような疑問でした。

これらの事柄は、「もっと前のレベルでlocoreのプログラムをロードするための処理が動いていると言うことに他ならない。」と思い、ネット上で検索すると、PCは電源立上げ時にBootstrapと呼ばれるプログラムをロードして走らせ、この処理がOSを立上げるための処理を起動するらしいと言うことがボンヤリと理解できました。

この辺の処理は、PCを長いこと使っているが良く理解できていなくて、「MBRって言う所を書き換えるとマルチブートが出来るんだよね」のレベルだったので、もっと理解を深めるために調べてみました。

PCの一般的な起動プロセス

一般的なOS起動プロセスは次のようになります。

電源ON

PCの電源を入れた時、マザーボード上のBIOS[Basic Input Output System]にある初期化プログラムが最初に動作します。BIOSとは、コンピューターの基本的なハードウェア(キーボード、マウス、プリンター、ディスク等の入出力装置)を制御するプログラムであり、基本的なハードウェア(キーボー ド・マウス・プリンター・ディスク等の入出力装置)の原始的な制御を行います。

そして、OSはBIOSに命令を出すことでこれらのハードウエアをコントロールを行っています。このBIOS内にある初期化プログラムは、下に述べるような処理を行なうことになります。

HWの初期化(POST[Power On Self Test])

BISOの初期化プログラムはPOST[Power On Self Test]と呼ばれる診断テストを行ないます。POSTではCPUやメインメモリ、ディスクコントローラ、グラフィックスコントローラ、シリアル/パラレルポート、キーボードコントローラなど、マザーボード上の各デバイスに関する診断が実行されます。

POSTの途中で障害が発見されると、その結果がディスプレイ表示されたり、ディスプレイ表示が行えない場合には、ビープ音を鳴らしたりして、障害の原因を報告します。

起動ドライブの検索

ハードウェアの初期化が終了すると、BIOSは起動可能なデバイスの検索を始めます。起動可能なデバイスとして、FD・HDD(IDE,SCSI)・CD・DVD・ZIPと色々なメディアが存在しますが、これらの検索順位は、BIOSメニューの「Boot sequence」項目で指定できるのが最近のマザーボードでは一般的です。

先頭セクター(MBR)の読込み

起動ドライブがHDDに決定と仮定すると、BIOSはHDDの先頭セクターから512Byteのデータを読取り、メモリ上の0000:7c00番地にロードを行います。

この512ByteのデータはMBR[Master Boot Record]と呼ばれ、OSの起動に必要なBootStrap Loaderプログラムや、パーティションテーブルの情報が格納されています。

BIOSが先頭セクターから読出したMBRは、次のような構成になります。

MBRの構成
MBRの構成
Master Bootstrap Loderの実行

MBRをロードすると、BIOSはMBRの中にあるMBR Program(Master Bootstrap Loder)と呼ばれるプログラムを実行し、これに制御を移します。

MBR Programは主に次のような処理を行います。

  1. パーティション シグネチャーの検査
    正当なMBRであるか、シグネチャーの値(0xAA55)を検査する。
  2. パーティションテーブルの検査
    4つのパーティションテーブルをチェックし起動可能な基本領域があるかチェックする。
  3. 指定されたパーティションの先頭に存在する、PBR[Partition Boot Record]をロードする。
  4. ロードした、PBRにあるBootstrap Loaderに処理を移す。

PBRは、各パーティションの先頭セクターに存在し、この512byteのデータは、OSにより異なった形式になっています。OpeBSDのPBRは下記のようになっており、WindowsのBoot Sectorとほぼ同じ構成になっているようです。

OpenBSDのBoot Sector構成
OpenBSDのPBR構成
Bootstrap Loaderの読込と実行

電源立上げ時PCは、リアルモードで動作中であり、A20もcloseの状態にあります。また、ハードウェアの初期化も不十分であるので、OSをロードする前にこれらの処理をしたいところですが、Bootstrapのプログラムでは、サイズが小さいためこれらを行うことが出来ません。そのためOSによっては、Boot Loaderプログラムを読込み、OSを立上げるための前処理とOSのロードを行うプログラムを実行します。

Boot Loaderの読込と実行
Boot LoaderではKernelを読込む前に必要なHWの初期化や、Kernelロードオプションの入力処理を行います。
OSの読込み
Boot LoaderからOSがロードされ、無事OSが立ち上がる。

OpenBSDの起動の流れ

ここまでは、一般的なbootの流れを説明しましたが、簡単にOpenBSDのbootの流れを説明したいと思います。まず、OpenBSDをIDE HDDの領域を全てを使い下図のようにインストールしたとします。

OpenBSDの起動の流れ
OpenBSDの起動の流れ

このOpenBSDがインストールされたPCの電源をONにすると、

  1. BIOSはHDD内にあるMBR領域をメモリに読込み、Master Bootstrap Loderを実行する。
    読込まれるMBRはインストール時に/usr/mdec/mbrの内容と同じものがHDDのMBR領域に書込まれる。
  2. 次にMBRは、起動可能なHDDの領域にあるPBRを読込み、PBR内のBootstrap Loaderが実行される。
    PBRの領域には、/usr/mdec/biosbootがインストール時にinstallbootによって書込まれる。
  3. biosbootは"/boot"を読込み、boot処理に移行させる。
    bootプログラムは、CPU/HWの初期化などの処理を行う。
  4. bootプログラムが初期化を終了して、kernelが実行出来る状態になったら、kernelを読込み処理をkernl側に移行させる。

kernelが読込まれ処理が開始されるとき、最初に動くのが"locore.S"なのだ。と言うことは「hackはlocoreから」と言う格言はあながち間違いでは無いですが、bootの仕組みをわかっていないと、私みたいに「???」と言うことになってしまうかもしれない。

Last modified: Tue Jan 22 15:39:18 2008 JST