マルチブートの仕方(豆知識編)

2001/08/05
目次
  1. プロローグ
  2. Windows初級編
  3. Linux初級編
  4. 機能編
  5. Windows中級編
  6. Linux中級編
  7. その他のOS編
  8. フリーツール編
  9. 市販ツール編
  10. 裏技編
  11. 特別編
  12. 特殊環境編
  13. 究極編
  14. 豆知識編

 ここではブートローダの動作や、その他の知っていて損のない、様々なことについて解説する。通常ブートローダを使っていくにはあまり必要のない知識かもしれないが、もしあなたが本格的にマルチブートを行おうと思うなら、動作原理や、昔からの決まりや暗黙の了解事項などの理解はブートコンセプトの設計、ブートローダの選択に重要な役割を果たすことになる。

 動作原理を知っていたら、自分のやりたいことの実現にとって、最適なコンセプトとツールが選択することができたのに、それを知らないがゆえに、不満足な状態にあまんじている人もいるのではないだろうか。またフリーツールで十分自分の目的が達成できるにも関わらず、高い市販品を購入していたとか。

 また、なんでこんな決まりになっているのか。動作上問題あるのか、単なる習慣なのかによって、こちらの構え方も変わってくる訳である。

 どこまで解説していけるか、分からないが、私自身ブートローダの選択に必要だと思った知識や、疑問に思ったことについてはできる限り解説していきたいと思う。

 


データ配置

 ローダにとって、プログラムコードや動作に必要なデータがどこに配置されるかは動作上極めて重要な要素になる。またパーティションのきり直しやOSの再インストールなどの構成変更によって受ける影響の大きさ、決して触れてはいけないファイルはどれなのか、そしてトラブルが起きたときの原因は何かなどを知る重要な手がかりにもなる。

1.IBMオリジナルブートストラップローダ
 

 まずIBMオリジナルのブートストラップローダの場合、データがMBR内にのみ配置されていることは言うまでもないと思う。実際は「マスターブートレコード」でも説明している通り、MBR内の先頭446bytesに置かれている。このような小さなプログラムなので凝ったことは殆どできず、アクティブなパーティションの先頭セクターをロードして、そちらのOSのIPLへ制御を渡す(所謂チェーンロード)のみとなる。

 しかしロード作業はあくまで公共の場である、MBRのパーティションテーブルの情報を元に行われるので、環境の変化には非常に強い訳だ。パーティションがどのような書き換えられようと、フォーマットされようと、アクティブな基本領域さえあれば動作に支障はない。

 因みに上の図の青の矢印はパーティションテーブルの情報を元にチェーンロードしていることを示している。
 

2.MBRオンリー型
 

 次にIBMオリジナルブートストラップローダに、パーティション選択機能を付け加えただけのローダがこれになる。やはりMBRの先頭446bytesに収める必要があるため、見栄えのするメニューや便利な機能を実装することはできないが、1番同様、環境の変化には非常に強いものとなる。データアクセスも同様にパーティションテーブルの情報を唯一のものとして動作する。選択後のOSのIPLのロードはこの場合でもチェーンロードである。

 しかし、現在このスタイルをとるローダはbooteasybootactvくらいだろうか。バージョン4まではext-IPLもこの構造に拘っていたが、後述する2ステージ型の方が、殆どの面で優れているため、多くのローダがそちらに移行した。

 

3.2ステージ型1(MBR後続セクター利用)
 

 さて、多くのローダが移行した2ステージ型がこれだ。このサイトでも何度か説明してきたが、現在のPC/AT互換機の仕様では先頭のパーティションは第2トラックから割り当てることになっており、ハードディスクの先頭トラックはその先頭セクターであるMBR以外、後続が空きとなっている。1トラックは現在、殆どのハードディスクで63セクターと決まっている。(なぜそう決まっているかはここでは説明しない) 従って、MBRの後ろの62セクター31,744bytesが空きになっていて自由に利用できる。

 約32kbytesある訳だが、これだけあればかなり思い切ったプログラムコードを書くことができる。見栄えのするメニューも表示できるし、いろいろな便利な機能を付加することができる。また多くのデータを保管することもできる訳だ。その上、パーティションのきり直しやフォーマットとも無縁であるという点ではMBRと違いがないため、環境変化への強さはMBRオンリー型とほとんど変わらない。

 実際MBRにはMBR後続セクターに配置したローダ本体を呼び出すだけの簡単なローダを配置する。BIOSからはMBRが読み込まれるので、ここにデータを全く配置しない訳にはいかないからである。このMBRに置かれたデータはローダによっていろいろな呼ばれ方がするが、一般的に1st ブートローダとかStage1 ローダなどと呼ばれる。

 一方MBR後続セクターに配置されたローダ本体は対してStage2ローダと呼ばれたりするが、実際はプログラムコードが書かれたローダのほかに各種データが保管されたデータベースも含んでいる場合が多いだろう。

 Stage1ローダから、ローダ本体へのアクセスはStage1ローダ自身に記録された絶対位置を基礎にアクセスする。図の黒の矢印は絶対位置依存のアクセスであることを表現している。通常の操作ではここのデータが破壊されることはないので絶対位置依存でも全く問題ない。

 あえてMBRオンリー型と比べた場合のデメリットを挙げるとすれば、一応MBRの後続セクターは62セクターが保証されたものではないということだ。古いハードディスクではもっと少ない場合もある。勿論逆に多い場合もあるが。従って例えばこのセクターを30セクターほど使うローダがあり、古いハードディスクでここが20セクターほどしかない場合、このローダは使えないということになる。しかし現在発売されているハードディスクはすべて1トラック63セクターとなっているので、殆ど気にする必要はない。

 このようなMBR後続セクターを使った2ステージ型はMBRオンリー型と比べ殆どデメリットがなく、多大な利点を持っているので現在多くのローダがこの方式をとっている。

 MBM(グラフィックメニューを除く)、extIPLSBMGAGSyMonOS-BS、などがこのスタイルをとっている。ただしOSのロードはIBMオリジナルローダから変わらずチェーンロード主体ということになる。
 

4.2ステージ型2(パーティション内領域利用)
 

 同じ2ステージ型でも、どうしても62セクターではコードもデータも足りないという場合、どこかのパーティションにデータを配置せざるを得ない。しかしパーティション内はOSがいろいろといじくりまわすため、データの絶対位置が保証されないので、パーティション内データに絶対位置を基礎にアクセスするという動作は環境の変化に極めて弱いものとなってしまう。

 従って現在このスタイルをとるブートローダは殆ど存在せず、LILOくらいである。LILOがちょっとしたことで「LI」で止まるのはこの構造に依存している。更にLILOはカーネルのアクセスも絶対位置依存なので、始末が悪い。
 

5.3ステージ型
 

 高機能を実現するためにはデータの肥大は避けられない。その場合、パーティション内にデータを配置するということは必須となってくる。そこで起きた4番の問題を、少しでも解決しようとした構造がこの3ステージ型となる。この構造の特徴はMBR後続セクターに中間ローダを配置したことだ。この中間ローダの主な役割はファイルシステムの理解となる。それによってローダ本体をパーティション内領域に配置しつつも、絶対位置依存でアクセスするのではなく、ファイルシステム経由でアクセスするのである。図の赤の矢印はファイルシステム経由のアクセスを意味している。

 ファイルシステム経由だとどういうメリットがあるかというと、パーティション内にあるローダ本体や各種データをバックアップしてレストアしたり、またはこのパーティションをデフラグメントしたり、データを更新したりといった、データのハードディスク上の絶対位置が変わってしまうような作業を行っても、動作に支障がないことだ。これによって環境の変化に対して格段に強くなる。

 ファイルシステムの理解にはどうしても多くのコードが必要になる。そのため、MBRのローダだけでは無理なので、同様に環境変化に強いMBR後続セクターをファイルシステム理解のためのコード、つまり中間ローダを配置する場所として利用する訳である。

 ただし、環境に強いとはいっても、パーティションにデータを置く以上、そのパーティションのフォーマットやパーティションのきり直しなどの大きな環境変化に対してはその影響を受けざるをえない。この点は2ステージ型1までよりは環境変化に弱いといえる。従って、この方式をとるブートローダはバックアップ機能を備えているものが多い。

 またこの構造の副産物という訳でもないだが、ローダ本体のロードにファイルシステムアクセスが可能なのだから、その後のローダがOSロードするにあたってもファイルシステムアクセスが利用できる。そのためチェーンロード以外にもそのファイルシステム上のカーネルのロードを行ったり、Multi-FAT機能をサポートしたりといった、より高機能なブート作業を行うことができる。

 現在この3ステージ型をとっていることが明らかなのはGRUBをハードディスクにインストールした場合だ(フロッピーにインストールした場合、2ステージ型)。また動作仕様が公開されていないので明らかではないのだが、各種実験から、XOSLBootMagicSystemCommanderSystemSelectorBootWareBootIt、などがこの構造をとっていると推測される。

 もっともファイルシステム経由とはいっても、対応しているのは殆どFAT(16及び32)だけである。現在のところGRUBだけがFATのほか、ext2Minix fsReiserFSBSD ffsなど合計5つのファイルシステムに対応しており、その柔軟性を際立たせている。

 


LBA時代のCHS

 ブートローダにとって、BIOSのハードディスクアクセスの仕様は非常に重要であり、特にLBA対応か、ジオメトリ(CHS)アクセスしか出来ないかは大容量ハードディスクが使えるか否かを決定する重要な要素になっている。「8GBの壁を越える」でも言及しているように、現在BIOSによるハードディスクアクセスはもやはLBAアクセスが完全に主流となっている。

 しかし、これまでのページでも私は何度か「パーティションはシリンダー境界で切らねばならない」とか、「先頭パーティションは第2トラックから割り当てることになっている」とか、ジオメトリ(CHS)を前提にしたようなことを言及してきている。突っ込みの厳しい読者なら、LBAになったのなら、もはやこれは関係ないのでは?と疑問に思ったかもしれない。つまりLBA時代には上記のような決まりはないのではないか、あくまでそれはジオメトリアクセスをしていた時代の話ではないのかと。

 しかし現在でもジオメトリの概念は生きている。確かにLBAアクセスしているシステムにおいても、パーティションはシリンダー境界で切る必要があり、たしかに先頭トラックはパーティションに割り当てられていない。では一体、LBAシステムにおけるジオメトリとは何なのだろうか。

 これは単なるセクターのグループ、ブロック化と理解して頂くのが一番いいだろう。ハードディスクの全セクター数をシリンダーという名のある一定数のセクターで括られたグループに分けていると考えてほしい。名前はシリンダーだが、物理的なシリンダーとは全く関係のないものである。

 現在BIOSに対して、「このハードディスクのジオメトリは何ですか?」と尋ねると、殆どのBIOSが今、「そのハードディスクのジオメトリはXXXXシリンダー、255ヘッド63セクターです」と答える。物理的に考えたらナンセンスであることは明らかである。255ヘッドということはプラッター数128枚にも及び、現在主流の3.5インチのあの筐体に入る訳がない。つまり1シリンダーの255ヘッドと63セクター(トータル16065セクター)は現在のハードディスクのお決まりであり、シリンダーとは単なる16065個のセクターで構成された一種のセクターグループと言える論理的な概念に過ぎない。

 そしてパーティションはこのグループ単位で割り当てるというのが、暗黙の了解となっている(少なくともIBMの技術書にはそうすべきと明記されている)訳だ。だから実際パーティション境界とシリンダー境界は一致していると言っても、物理的にはシリンダーはおろか、トラックの途中でパーティションが変わっていることの方が遥かに多いだろう。


 ところで、もう少し技術的な話をする、BIOSに対しハードディスクのジオメトリを尋ねる時、通常はDISK BIOS(INT13H)のFunction 08Hを使う。これに対する回答が現在殆どのBIOSが1023シリンダー、255ヘッド、63セクターの範囲内で返してくる。従って8GBを超えるハードディスクの場合はシリンダー値が常に不正となる。これに対し、DISK BIOSのFunction 48Hというものがあり、このFunctionによってLBA値を取得することができる。このLBA値の総セクター数を、255と63で割って、そのをシリンダー値として扱うのが、現在の正しいジオメトリの取り扱いになる。

 ところが、IDEハードディスクの場合はこのLBA値取得のためのFunction 48Hがちょっと曲者で、こいつもジオメトリを返してくる(SCSIはFunction 48Hではジオメトリを返さない)。しかもFunction 08Hとは違うヘッド数で返してくる場合がある。ハードディスクのラベルシールにCHSが書いてあることがあるが、恐らくそのヘッド数を返すのであろう。しかしこれはハードディスクによって返す場合と返さない場合がある。従って、Function 48Hが返すジオメトリは不安定な値なので、本来使用すべきではないのだが、これを利用するシステムがあり、混乱の元になっている。私の知る範囲では昔のLinuxのfdiskや、Solarisのインストーラなどがこれにあたる。


 因みに、どうして現在もジオメトリがこうして残っているのだろうか? その理由は簡単だ。どのような規格にもある下位互換性のためである。LBAアクセスに対応したシステムでも、依然ジオメトリアクセスが可能なように、ジオメトリという概念をBIOS側もハードディスク側も残している訳だ。どちらかが古いシステムであってもアクセスに支障が無いようにしている訳である。

 


休止状態からの起動

 Windows2000にはシャットダウンモードに休止状態というものがある(Windows98 SEやWindowsMEにもあるのだが、私の環境では有効になるものがないので、ここではWindows2000に限った話だけにしておく)。これはノートPCなどでは昔からよく行われていたハイバネーションと呼ばれるものとほぼ同じで、現在のメモリの内容ハードディスクに書き出して終了し、起動時にはこの書き出したデータをメモリに戻して起動するというものだ。

 シャットダウンの直前の状態をほぼ完全に復元できるので、たとえば編集途中のファイルがあっても、そのままシャットダウンできるため、不意にバッテリがなくなってしまうようなノートPCでの作業中に重宝する機能ということで、かなり前からノートPCでは採用されていた技術である。

 ノートPCのハイバネーション機能はノートPCのハードベンダーが独自に組み込んだもので、OSが用意した機能ではない。Windows2000ではこれをOSの標準機能として用意した訳だ。

 作業途中でシャットダウンができるというのはデスクトップコンピュータにとっても決して意味のないことではない。また「休止状態」はシャットダウンも復帰起動も非常に高速なので、通常の起動、終了が遅いWindows2000などではそういった意味でも、なかなか有用な機能で、私などは手放せないものに既になっている。ここではこの休止状態でシャットダウンした時の復帰起動について説明する。

 休止状態からの復帰起動シーケンス図を以下に示す。

[Windows2000の「休止状態」からの復帰起動シーケンス]

 NTLDRまでは通常のWindows2000/NTの起動を同じである。ざっと解説すると以下のような説明になる。

  1. Windows2000のNTLDRはboot.iniを読み込み前に、まずカレントディレクトリに「hiberfil.sys」というファイルがあるか探す。
  2. あったらそのファイルの先頭4バイトに「hibr」という文字列(小文字である必要あり)があるか確認する。
  3. この文字列があったらHiberfil.sysに組み込まれた復帰ブートプログラムに制御を移する。
  4. この後はこのブートプログラムによって復帰起動が行われます。

 1番の動作があるため、休止状態からの復帰起動の場合、ブートメニューが表示されない。つまりNTLDRによるマルチブートを行っている場合でも選択起動はできない。選択起動をしたい場合は一旦通常のシャットダウンを行う必要がある。

 「休止状態」でシャットダウンを行うと、現在のメモリ内容をhiberfil.sysファイルに書き込むと共に、このファイルの先頭4バイトにhibrという文字列を埋め込み、特別な復帰ブートプログラムもやはりファイルの先頭の方に埋め込む。そのため次の起動時に上記のようなブートシーケンスになる。

 復帰起動を行うと、hiberfil.sysファイルからメモリにその内容が復元されると共に、このファイルに埋め込まれたhibr文字列や復帰ブートプログラムがNULLクリアされる。通常シャットダウンとを行うと、hiberfil.sysファイルがこのまま(先頭にhibr文字列もブートプログラムも組み込まれていない状態)になるので、2番の時点でhibr文字列がないため、通常のWindows2000/NTのブートシーケンス(boot.iniを内容を見てメニューを出す必要があれば出す)になるという寸法だ。

 試しに休止状態でシャットダウンした後、Hiberfil.sysの先頭を例えば「hibs」などに書き換えると、通常起動が行われるので、なるほどこの「hibr」という文字列を確認しているのだなということが分かる。またこのファイルの名前を変更しても、通常起動になるので、1番の確認がされていることが分かる。

 またWindows2000のNTLDRをバイナリダンプしてみると、「hibr」という文字列や「hiberfil.sys」という文字列の存在を確認できる。WindowsNTのNTLDRではそのような文字列は見つからない。これらのことからWindows2000のNTLDRからこの機能が組み込まれたことが分かる。

 マルチブートにはあまり関係のないことかもしれないが、知っておいて損のない話だったと思う。

 


おせっかいBIOS

 通常、BIOSは起動ハードディスクと決めたドライブのMBRをロードするにあたって、MBRの有効性のチェックは最終2バイトのブートシグニチャ0xAA55であるかを検査する。そしてその値が正しければMBRをロードし、そのブートプログラムに制御を渡す。正しい値でなければ、そこでブートシーケンスは停止することになる。これはそこに変なプログラムがあって、コンピュータが暴走してしまうのを防ぐ正当な動作である。

 ところがBIOSの中にはブートシグニチャだけでなく、パーティションテーブルを調べて、アクティブパーティションが存在しない場合もブート作業をやめてしまうものがある。本来はパーティションのチェックはMBRのブートプログラムの仕事であり、BIOSが行う必要はない。

 このようなBIOSを業界(ブートプログラムの作者)ではおせっかいBIOSと言って、嫌われている。嫌われる理由は以下のような実害があるからだ。

 Microsoftの一部のOSは第2ハードディスク以降から起動する場合、第1ハードディスクのMS-DOS基本領域のアクティブフラグをすべてクリアする必要がある。それはそうしないと第2ハードディスク以降にあるOSのブートプログラムが、第1ハードディスクのアクティブなMS-DOS基本領域をCドライブだと思って行動して、意図したものが起動できないか、そもそも全く起動に失敗してしまうためである。

 そのようなOSの第2ハードディスク以降からの起動のために、ブートローダが第1ハードディスクのブートフラグを全部クリアして起動した場合、次回の起動時におせっかいBIOSがブートローダに制御を移してくれなくなってしまうので、ブートローダとしては何もできなくなってしまう訳だ。

 これに対する対策として、ブートローダでは第1ハードディスクにMS-DOS基本領域以外の領域(拡張領域なり、MSのOSの知らない領域)がある場合はそこをアクティブにして、第2ハードディスク以降のMSのOSのブートセクターを実行する。こうすることで、MSのOSの誤作動を防止すると共におせっかいBIOSのおせっかい行動を抑止することができる。

 勿論第1ハードディスクに拡張領域か、LinuxのパーティションなどのMS-DOS基本領域以外のパーティションが存在しなければならない。

 


←前へ(究極編)

 


目次へ