一般的に、HDDの全てを使ってOpenBSDをインストールしている場合、mbr.Sで定義されているプログラムおよびデータがMBRには書かれていると思います。または、Linuxなど他のOSを別パーティションにインストールしてある場合は、FIFOなど別のMBRが書かれているかもしれません。
このプログラムおよびデータは、HDDのMBR(Master Boot Record)領域に書かれていて、PCの電源を入れたときにBIOSによって、自動的に0x07c00
番地にロードし、実行されます。
OpenBSDが提供しているMBRは非常に簡単で、OpenBSDのPBR[Partition Boot Record]をロードする為だけの機能しかなく、他のOSを切り替えてブートさせたりする機能は存在しない、非常にシンプルな構成になっています。
OpenBSD3.5までのMBRは、INT 13Hを使用していた為に8.4GBを超えたパーティションにあるOSをブート出来ませんでしたが、OpenBSD3.6からは拡張INT 13Hを使用するようになったので8.4GB超えの制限は無くなりました。
現在のMBRは、PBR(biosboot)の読出しに拡張INT 13Hを使用するようになり、OpenBSDのパーティションが8Gを超えた場所に存在していてもブートが可能となりました。しかし従来のINT 13Hでも読出せるようにフォールバックシーケンスも持っています。フォールバックさせるにはboot中にシフトキーを押下していれば、INT 13Hで読出すようになります。ここでの処理ははSHIFT key押下の検出を行ない読出し方法の決定を行ないます。
- SHIFT key押下検出
-
SHIFT key押下はINT 16Hを使用して検出を行います。INT 16H入出力は下記のようになります。
INT 16Hの入力パラメータ
入力 |
レジスタ |
内容 |
AH |
02h(GET SHIFT FLAGS) |
INT 16Hの出力パラメータ
出力 |
レジスタ |
内容 |
AH |
shift flags |
出力されたshift flagsの意味は下記の意味を持ちます。bit0かbit1が1ならばshift keyが押下された事になります。
shift flagsのビットアサイン
shift flags |
bit | 意味 |
0 | right shift key pressed |
1 | left shift key pressed |
2 | Ctrl key pressed (either Ctrl on 101/102-key keyboards) |
3 | Alt key pressed (either Alt on 101/102-key keyboards) |
4 | ScrollLock active |
5 | NumLock active |
6 | CapsLock active |
7 | Insert active |
- 検出時の処理
シフトキー押下が検出出来た場合は、ブザーを約1秒鳴らし検出出来たことをオペレータに知らせます。そして、flagsにMBR_FLAGS_FORCE_CHS検出bitをセットします。
PC/AT互換機のBIOSは、電源立上げ時に接続されているDisk drive の検索を行ないます。通常は、IDE Pri-Master → Pri-Slave → Sec-Master → Sec-Slave→ SCSI1 ID1 → ID2 → ID3 ...と言う順番で検出されますが、BIOSメニューで起動ドライブの変更を行なった場合は指定されたドライブが最初に検索されます。そしてBIOSは、見つかった順番にそれぞれ0x80,0x81...とユニークなdrive numberを振っていきます。
BIOSは最初にFDDからの起動をdrive number順に試みて(FDDのdrive numberは0x00,0x01...とIDが振られる)失敗した場合、0x80のdriveからdrive number順に起動を試みます。そして、起動されたデバイスのdrive numberはBIOSによってDL レジスタにセットされ、MBRプログラムに渡されます。
- HDDからのブートかチェック
- 起動したドライブのIDはDL レジスタにセットされBIOSから渡されので、HDDからのbootであるか(DL レジスタのbit7目が1か)チェックを行ないます。
- 不正な値の場合は画面に表示
-
FDDまたは不正な値の場合は(古いBIOSの場合値がセットされて来ない場合があるようです)、画面上に次のようなメッセージを表示します。
MBR on floppy or old BIOS
- 値の修正
-
不正な値が入っていた場合、DLレジスタに0x80を書込んで処理を続けます。DLの値を無理やり修正してしまってもdisk読出しの処理でエラーになるので問題無いのだと思います。
しかし、この処理だとセカンダリHDDからのブートは失敗してしまいますね。OpenBSDのMBRはプライマリHDDからのブートしか出来ないようです。
どのdeviceおよびPartitionからbootが行なわれたかを、画面に表示してオペレータに通知します。
- boot drive numberのdecimal変換
- boot drive numberが0x80の場合は'0'、0x81の場合は'1'とasciiに変換を行ないます。求めた値はdrive_numにセットします。
- Partition Noのdecimal変換
- boot Partition Noのasciiに変換を行なう。求めた値はpart_numにセットします
「パーティションを検索処理」で使用したCX レジスタのカウンタ値を利用し、'0' + (4-cx) ((4-cx)はループの回数)でboot Partition Noは求める事が出来きます。
- 画面表示
-
infoからpart_numまでの内容を画面に表示します。
例えば、boot driveが0x80でboot Partitionが4の場合と下記のように表示されます。
Using drive 0 , partition 4
SHIFT keyが押下され、MBR_FLAGS_FORCE_CHSが1の場合(INT 13Hで読込モード)、表示が多少異なり下記のように表示されます。(最初に"!"が付加される)
!Using drive 0 , partition 4
MBRのsignatureの値をクリアします。MBRのsignatureをチェックせずにクリアして良いのか??と思ったのですが、コメントを見ると下記のように書いてありました。
我々は、以前MBRをロードした場所にPBS(biosboot)をロードするだろう。
その後、ロードされた値をチェックを行なうが、自分自身(MBR)をチェックしないようにsignatureをクリアします。
つまりMBRの場所にbiosbootを読込むのだが、これらのsignatureは値が同じであるので、仮に読込みが失敗したとしても、現在ある内容がどちらであるか判別出来ません。これを回避するために読込む前にMBRのsignatureの値をクリアしておくと言うことなのでしょう。結局MBRのsignatureをチェックしないようです。
PBR[Partition Boot Record] (biosboot)読込み後は、次のような配置になります。
partition boot sector (biosboot)読込み後
読込んだbiosbootが正しいものか、または正しくLoadされているかチェックするために、biosbootのSignatureがDOSMBR_SIGNATUREと等しいかチェックします。Signatureが不正な値の場合は、画面に"No O/S"を表示してHALTさせます。
Using drive 0 , partition 4 ;
No O/S
bisobootの先頭番地 ( 0000:(BOOTSEG << 4))番地にジャンプし、biosbootに処理を移行する。