マルチブートの仕方(Linux中級編)

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

 


LILOを使いこなす

 Linuxは論理領域にも置いても、第2ハードディスク以降に置いても、起動、また起動後のOSの動作上全く問題ない。制約の多いWindows系OSとの共存時にはこのLinuxの自由度が役に立つ。貴重な基本領域をLinuxのために消費する必要がないからだ。

 これらは勿論LinuxというOSの柔軟性に負うところが大きいのだが、現在その標準ローダとなっているLILOの多機能性にも大きく依存している。欠点も非常に多いローダであり、最近はGRUBを標準にしたディストリビューションも出てきているようだが、まだまだLinux標準ブートローダとしての位置は揺らいでいない。だからやはりこのLILOを使いこなさずして、Linuxマルチブートの極めたとはいえないだろう。このLinux中級編のページはすなわちLILOの使いこなすことを目指そう。

 さて、LILOを使いこなすにはまずその使い勝手の向上を図る必要があると思うが、その点に関してはLILOの使い勝手の向上に譲る。一応このページは後回しでも構いないが、遅かれ早かれ読んでおく必要があると思う。

 以下に、以前、実際に私が構築した構成を紹介する。ハードディスクは20GBのものが2つ。ここにWindows系OSは6つ(図には現れていないが、NTLDRからWindows2000がProfessionalとServer、それとWindowsNT4.0を起動)、Linuxは4つのディストリビューションをインストールしてある。開発アプリケーションのテストの関係上、必要最低限のOS群でした。まあ特別OSの数が多い訳ではないが、この構成の中にはマルチブートのテクニック、特にLILOのテクニックがふんだんに利用されている。

 実はテストの関係上、ハードディスクAとハードディスクBはしばしばBIOSからみた順序を変更する。ハードディスクAはUltraATA66カードのプライマリーマスターに接続してあり、ハードディスクBはマザーボードのノーマルIDEのプライマリーマスターに接続している。UltraATA66カードはSCSIカードとして認識されるので、BIOSのブートシーケンスで、SCSIを先にしたり、IDEを先にしたりといった変更を行って、ハードディスクの順序を変更する。

 メインはハードディスクAで、そこ第1基本領域にインストールしたWindows2000Proが最も利用頻度が高いのだが、他のOSの起動する機会も多く、ハードディスクBを第1ハードディスクにする頻度も高い。そこでハードディスクの順序の如何に関わらず、10個のOSを問題なく、しかも手間無く、起動するための構成を模索した訳で、その結果が上記の構成ということになる。

 ざっと起動の流れを説明すると、ハードディスクAのMBRにはフリーツール編でも説明するMBMというブートローダを置いている。だからハードディスクAを第1ハードディスクにしている時はまずこのMBMが起動する。MBMは基本領域と拡張領域を起動できる * ので、各基本領域とハードディスクAの拡張領域を起動する(赤矢印の流れ)。MBMが基本領域1のブートセクターをチェーンロードすると、その先にはNTLDRがあり、3つのNT系OSを起動する。その他の基本領域にはWindows9x系があり、直接MBMがチェーンロードする。ハードディスクAの拡張領域の拡張PBRをMBMがチェーンロードすると、そこにはLILOがあって、このLILOで4つのLinuxディストリビューションの各カーネルをロードする(黒矢印の流れ)。以上がハードディスクAが第1ハードディスクである場合の起動の流れだ。

 *注 この時点でMBMは論理領域起動はできなかったが、現バージョンは可能だ。ただここの説明ではこのままMBMが論理領域起動ができないほうが、若干説明に都合がいいので、そのままにしている。またあとで出てくるWindowsME起動問題も現時点では解決しているのであしからず。

 一方ハードディスクBが第1ハードディスクになっている場合、MBRにはやはり「フリーツール編」で紹介するext-IPLというブートローダを配置してある。ext-IPLは論理領域を起動できるので、各基本領域とLinuxの入ったハードディスクAの論理領域3と4、及びハードディスクBの論理領域2と3のブートセクターをチェーンロードする(青矢印の流れ)。各Linux領域のブートセクター(Linuxでは普通スーパーブロックと呼びます)にはそれぞれのカーネルをロードするLILOが配置されており、これらが各カーネルをロードする。

 メインのハードディスクAのMBRにMBMを配置してメインのブートローダとして使っている理由はMBMの区画エディタなどの機能の有効性と、MBMのグラフィックメニュー機能が私のお気に入りだからだ。しかしMBMは論理領域起動ができないので拡張PBRにLILOを配置して、Linuxの起動は全般的にLILOに任せる。

 またMBMは第2ハードディスク以降からWindowsMEの起動に問題があるため、MBM起動時にはWindowsMEが第1ハードディスクになければならない。だから、ハードディスクBが第1ハードディスクの場合、第2ハードディスク以降のWindowsMEを問題なく起動できるext-IPLをMBRに配置している。ext-IPLは拡張領域起動ができない一方で論理領域起動が可能なので、MBMとは違い、直接それぞれの論理領域のブートセクターをチェーンロードして、そこからカーネルのロードはLILOに引き継ぐ形になる。上図で黄色の部分にはLILOがあることを示している。

 つまりこの構成ではLILOは全部で6箇所に存在する。各論理領域のLILOはその領域をルートしているディストリビューションが起動時に作成し、役割は主にそのディストリビューションのカーネルの起動だ。一応他のカーネルもロードできるようにしているがあまり使わない。

 またパーティションAの拡張PBRにインストールしたLILOはハードディスクAの論理領域3にインストールしたTurboLinux上で作成するが、目的は全ディストリビューションのカーネルの起動だ。ハードディスクBの拡張PBRにもLILOを一応入れてますが、これは実際は必要ないので、特に説明しない。また各LILOからはWindowsも起動できるようにする。もしからしたらLILOに移った後で、気が変わるかもしれないからだ。

 さて、この構成でマルチブート的にポイントとなるのは以下だ。

  1. 複数のハードディスクをサポートした、特にWindows系の第2ハードディスク以降の起動が可能なブートローダを使うこと。
  2. 8GB対応のブートローダを使うこと。
  3. 拡張領域起動、または論理領域起動のいずれかが可能であるブートローダを使うこと。

 実際他にもいろいろあるが、このページではマルチブート全般の話はメインではないので、これらの点は機能編や各ブートローダの説明の項に譲るとして、ここではLILOのテクニックについて説明しよう。

 上記の構成で使われているLILOのテクニックは以下のようなものだ。

  1. LILOを拡張PBRに配置する。数あるブートローダの中で拡張PBRに配置できるローダは殆どない。
  2. 他のパーティションをルートとしたOSのカーネルの起動。
  3. ハードディスクの順序の指定。
  4. 同一マップインストーラでの複数のLILOの作成。
  5. 第2ハードディスク以降のWindows系OSの起動。
  6. アクティブ切り替え。

 個々の説明に入る前に、まずこの構成を司るLILO達を作成する設定ファイル/etc/lilo.confを見てみよう。まずはハードディスクAの拡張PBRに置かれるメインのLILOの場合だ。このLILOはMBRにあるMBMからチェーンロードされて、全てのディストリビューションのロードを司る。因みにハードディスクAはUltraATA66カードのプライマリマスターに接続されているため、デバイススペシャルファイル名は/dev/hdeとなる。ハードディスクBはノーマルのIDEのプライマリマスターなので/dev/hdaだ。

[1. ハードディスクAの拡張PBRに置くLILOのためのTurboLinux上のlilo.conf]
boot=/dev/hde3
map=/boot/map
prompt
timeout=1000
lba32
keytable = /boot/jp106.ktl
menu-title="Turbo Menu EPBR"
menu-scheme=Cb:kc:Gb:Yb

disk=/dev/hde
    bios=0x80
disk=/dev/hda
    bios=0x81

image=/boot/vmlinuz
    label="Turbo Linux 6.0"
    root=/dev/hde7
    initrd=/boot/initrd
    read-only

image=/mnt/debian/boot/vmlinuz
    label="Debian"
    root=/dev/hde8
    initrd=/mnt/debian/boot/initrd
    read-only

image=/mnt/redhat/boot/vmlinuz-2.2.14-5.0
    label="Red Hat 6.2J"
    root=/dev/hda6
    initrd=/mnt/redhat/boot/initrd-2.2.14-5.0.img
    read-only

image=/mnt/slack/vmlinuz
    label="Slackware 7.1"
    root=/dev/hda7
    read-only

other=/dev/hde1
    label="Windows2000"
    table=/dev/hde
    change
      partition=/dev/hde1
        activate
      partition=/dev/hde2
        deactivate


other=/dev/hde2
    label="WindowsME"
    table=/dev/hde
    change
      partition=/dev/hde1
        deactivate
      partition=/dev/hde2
        activate


other=/dev/hda1
    label="Windows98"
    table=/dev/hda
    change
      partition=/dev/hda1
        activate
      partition=/dev/hda2
        deactivate
    map-drive=0x80
      to=0x81
    map-drive=0x81
      to=0x80


other=/dev/hda2
    label="Windows95"
    table=/dev/hda
    change
      partition=/dev/hda1
        deactivate
      partition=/dev/hda2
        activate
    map-drive=0x80
      to=0x81
    map-drive=0x81
      to=0x80


 注目してほしいのは赤色の部分と青色の部分だ。赤色の部分はLILO全般、またはLinuxカーネル起動における注目点で、青色の部分はWindows系OS起動時に重要となる設定部分である。それぞれの説明は後ほど行うが、ポイントはこのLILOはハードディスクAが第1ハードディスクである場合にだけ、実行されるということである。

 次にハードディスクBの論理領域2のブートセクターに置かれ、Redhat上から作成されるLILOのための設定ファイルの例だ。色分けの意味は1番と同じである。1番と何が違うかを見て、その違いがどこから来るものなのかを理解をしてほしい。

[2. ハードディスクBの論理領域2に置くLILOのためのRedhat上のlilo.conf]
boot=/dev/hda6
map=/boot/map
prompt
timeout=700
lba32
keytable = /boot/jp106.ktl
menu-title="Redhat Menu"

disk=/dev/hde
    bios=0x81
disk=/dev/hda
    bios=0x80

image=/boot/vmlinuz-2.2.14-5.0
    label="Red Hat 6.2J"
    root=/dev/hda6
    initrd=/boot/initrd-2.2.14-5.0.img
    read-only

image=/mnt/slack/vmlinuz
    label="Slackware 7.1"
    root=/dev/hda7
    read-only

image=/mnt/turbo/boot/vmlinuz
    label="Turbo Linux 6.0"
    root=/dev/hde7
    initrd=/mnt/turbo/boot/initrd
    read-only

image=/mnt/debian/boot/vmlinuz
    label="Debian"
    root=/dev/hde8
    initrd=/mnt/debian/boot/initrd
    read-only

other=/dev/hde1
    label="Windows2000"
    table=/dev/hde
    change
      partition=/dev/hde1
        activate
      partition=/dev/hde2
        deactivate
    map-drive=0x80
      to=0x81
    map-drive=0x81
      to=0x80

other=/dev/hde2
    label="WindowsME"
    table=/dev/hde
    change
      partition=/dev/hde1
        deactivate
      partition=/dev/hde2
        activate
    map-drive=0x80
      to=0x81
    map-drive=0x81
      to=0x80


other=/dev/hda1
    label="Windows98"
    table=/dev/hda
    change
      partition=/dev/hda1
        activate
      partition=/dev/hda2
        deactivate


other=/dev/hda2
    label="Windows95"
    table=/dev/hda
    change
      partition=/dev/hda1
        deactivate
      partition=/dev/hda2
        activate

 この設定ファイルの場合もポイントとなるのはこちらはハードディスクBが第1ハードディスクである場合にのみ実行されるということである。

 最後にハードディスクAの論理領域3のブートセクターに置かれるLILOをTurboLinux上から作成する場合の設定ファイルの例だ。

[3. ハードディスクAの論理領域3に置くLILOのためのTurboLinux上のlilo.conf]
boot=/dev/hde7
map=/boot/map7

prompt
timeout=500
lba32
keytable = /boot/jp106.ktl
menu-title="Turbo Menu"
menu-scheme=Cb:kc:Gb:Yb

disk=/dev/hde
    bios=0x81
disk=/dev/hda
    bios=0x80

image=/boot/vmlinuz
    label="Turbo Linux 6.0"
    root=/dev/hde7
    initrd=/boot/initrd
    read-only

image=/mnt/debian/boot/vmlinuz
    label="Debian"
    root=/dev/hde8
    initrd=/mnt/debian/boot/initrd
    read-only

image=/mnt/redhat/boot/vmlinuz-2.2.14-5.0
    label="Red Hat 6.2J"
    root=/dev/hda6
    initrd=/mnt/redhat/boot/initrd-2.2.14-5.0.img
    read-only

<以降は上記Redhatのものと同じ>

 

 TurboLinux上で作成するのに記述は1番のものではなく、2番のRedhat上で作成する場合の設定ファイルの方に近い理由も考えてほしい。やはりポイントはこのLILOがハードディスクBが第1ハードディスクだった場合にのみ実行されることである。また1番と3番はいずれもTurboLinux上で作成される。同じマップインストーラで2つのLILOを作る必要があるのだが、その場合の注意点も確認してほしい。

 上記のほかにハードディスクAの論理領域4のdebian上のLILOや、ハードディスクBの論理領域3のSlackware上のLILOもあるが、それぞれ3番、2番と似ているので省略する。

 このページを読み終わればあなたもこのような設定ファイルを記述してLILOを作成し、同様の構成を自分で作成することができるようになるはずだ。それがこのページの目的である。

 


他のパーティションのカーネルの起動

 Linuxには数多くのディストリビューションがあるので一つのPCに、あるいは一つのハードディスクに複数のディストリビューションをインストールしたいと思う場面も多いだろう。そのような場合、それぞれのディストリビューションをどのように起動しようと考えるだろうか。結局これは複数のOSをインストールするのと同じことになる。

 一つにはそれぞれのOSを別の基本領域にインストールし、LILOをそれぞれのルートパーティションに置いて、MBRに別途ブートローダを用意して、2つのLILOを起動し分けるかもしれない。今、あるIDEハードディスクの第1基本領域にTurboLinuxを第2基本領域にRedhatをインストールし、それぞれのLILOをそれぞれの基本領域の先頭セクターにインストールして、MBRにMBMなどのブートローダを置いてLILOを起動する場合を考えてみる。以下にその場合のそれぞれのOSでのlilo.confを示す。

[TurboLinuxのlilo.conf]
boot = /dev/hda1
map = /boot/map
prompt
timeout = 100

image = /boot/vmlinuz
  label = turbo
  root = /dev/hda1

[Redhatのlilo.conf]
boot = /dev/hda2
map = /boot/map
prompt
timeout = 100

image = /boot/vmlinuz
  label = redhat
  root = /dev/hda2

 これで2つのOSを起動し分けることができるのだが、これではブートローダが2段構成になってしまう。別のブートローダを使わず、LILOだけで両方のOSをダイレクトに起動するようにすることはできないのだろうか? 勿論可能だ。その時には当然LILOのインストール先を/dev/hdaにする、つまりIDEハードディスクのMBRにインストールするなどの変更が必要で、更に一つのLILOから両方をダイレクトに起動するのだから、上記のlilo.confを統合する必要がある。以下にTurboLinux側のlilo.confに統合した場合を示す。

[TurboLinuxとRedhatを統合したlilo.conf]
boot = /dev/hda
map = /boot/map
prompt
timeout = 100

image = /boot/vmlinuz
  label = turbo
  root = /dev/hda1

image = /boot/vmlinuz
  label = redhat
  root = /dev/hda2

 さて、これだけでいいのだろうか? 実はこれでも、まだだめなのである。問題はRedhat側だが、見ての通りカーネルイメージがTurboLinuxと同じものを指してしまっている。従ってこのままではTurboLinuxのカーネルが起動して、ルートを第2基本領域にするという変則的な起動をしてしまうのだ。まあ上記例ではたまたま同じものだったのだが、もし同じでなかったらエラーになるのが普通だろう。Redhat側のカーネルはTurboLinux側からみたら/boot/vmlinuzではないのである。

 ちゃんとRedhat側はRedhatのカーネルが起動されるようにしなければいけない。それにはTurboLinuxが起動している状態でもRedhat側のカーネルが見えるようにしておき、そのTurboLinuxから見える形で指定しなければいけない。たとえばRedhat側のルートパーティションである第2基本領域をTurboLinuxでは「/mnt/redhat」にマウントしてみる。その上で以下のようにlilo.confを変更する。

[Redhatカーネルを起動できる正しいlilo.conf]
boot = /dev/hda
map = /boot/map
prompt
timeout = 100

image = /boot/vmlinuz
  label = turbo
  root = /dev/hda1

image = /mnt/redhat/boot/vmlinuz
  label = redhat
  root = /dev/hda2

 これでRedhatが、本来の自分のカーネルで起動される。この例ではTurboLinux側に統合してみたが、これをRedhat側に統合した場合でも同じだ。その場合、TurboLinuxの第1基本領域をRedhat側でどこかにマウントして、TurboLinuxのカーネルを明示的に指定する必要がある訳である。

 またこのことはカーネルに限った話ではないことも記憶しておいて頂きたいと思う。結局lilo.confに指定する各データはカーネルに限らず、マップインストーラ(liloコマンド)を実行する時点で見える形で指定する必要があるということだ。

 


LILOが『LI』で止まる訳

 Linuxをいじり倒していて、起動時にLILOがLIとだけ表示して、止まってしまうのを経験したことのない人は非常に少ないのではないだろうか? 最もよく起こるLILOのトラブルの一つだ。また上記の他にLだけで止まったり、LIL-LIL?となってしまうことも含めると、これらを経験したことのない人は皆無に近いのではないだろうか? 一体このトラブルは何なのだろうか。これを説明するにはLILO起動時の表示「LILO」の意味を説明する必要がある。また根本原因であるところのLILOの絶対番地依存の性質も説明する必要があるだろう。

 LILO起動時に表示される「LILO」という文字列はどこかのロジックで一度に表示している訳ではなく、実はいくつかのロジックが進むごとに1文字ずつ表示している。従ってこの表示状況によって、どこでエラーが起きて止まっているのかがある程度推測することができる。以下にそれぞれの文字を表示するステージを示す。

 詳細は「ブートローダメッセージ」を参照して欲しいのだが、ここでは今回の主題である最も典型的な『LI』で止まる場合を詳しく説明する。上記を見ると「LI」だけで止まるということは2番目の「L」が表示できない訳だから、LILOの1st Boot Loaderが、2nd Boot Loaderをロードは出来たが、その実行が開始できないのだ、ということが分かると思う。

 上図で言うと、1st BLが2nd BLを見つけてメモリにロードし、実行制御を移したのだが、正しく実行されなかったというものだ。なぜ実行に失敗するのかと言えば、そもそも2nd Boot Loaderのロードに成功したと言っても、実際は正しく(正しいものが)ロードされていない場合が殆どである。

 2nd Boot Loaderの実体は通常/boot/boot.bというファイルだ(厳密にはこのファイルの一部だ)。マップインストーラ実行時に1st Boot Loaderの内部にこの2nd Boot Loaderの位置がハードディスクディスク上の絶対番地で記録される。1st Boot Loaderは実行時に自分の内部に記録された2nd Boot Loaderの絶対番地を頼りに2nd Boot Loaderをロードする(正確にはその絶対番地をBIOSに示してロードしてもらう)。

 しかし、何らかの理由で2nd Boot Loaderが無くなってしまうか、移動させられると、その絶対番地には別のものがあるか、または何のデータもないかもしれない。1st Boot Loaderはそのデータが実際は2nd Boot Loaderで無かろうが、なんであろうが、お構いなしにメモリにロードして、自分のすべきことは終わったとして、「I」と表示する。そして1st Boot Loaderが2nd Boot Loaderだと思っているそのデータに制御を移し、実行する段になって続行不能になり、停止することになる訳だ。

 このように、1st Boot Loaderが2nd Boot Loaderがあると思ってロードした場所に実際には2nd Boot Loaderが無かったというのは一体どういう時に起こるのだろうか。それは非常にいろいろな場面があると思うが、いくつか典型な例を挙げ、その対処法にも触れてみたいと思う。
 

 まずはLinuxの単独インストールの時は勿論、Windowsとのマルチブートの場合でも、LILOをメインのブートローダとして利用している場合、LILOをMBRにインストールすることが多いだろう。このシチュエーションでは1st Boot LoaderがMBRにあり、2nd Boot LoaderはLinuxルートパーティションにあるということになる。つまり距離的には結構離れて存在する訳だね。こういう場合に、Windowsだけの単独ブートに戻したい場合や、新たにWindows NT/2000をインストールするために、Linuxのパーティションを削除したり、再フォーマットなどすると2nd boot loaderが無くなってしまい、この障害が起こることになる。まあ当たり前といえば当たり前だが。

 新たにインストールするOSが、Windows9x/MEWindows XPの場合はインストーラがMBRに強制的にIBMブートストラップローダを書き込むので、LILOは1st boot loaderを含め、跡形もなく消え去るためこの問題は起きない。しかしWindows NT/2000のインストーラは行儀がいいのか、気が利かないのか、意見が分かれるところだが、MBRに一切触れないので、この「LI」停止問題に直面することになる。

 この場合の対処法としてはやはり一人MBRに取り残された形になった1st boot loaderを削除する(正確にはMBRをIBMオリジナルのブートストラップローダに戻す)他ないだろう。方法はこのサイトでもいろいろな所で言及してきたが、DOSWindows9xの起動ディスクで起動してfdisk /mbr」コマンドを実行するか、Windows2000の回復コンソールfixmbr」コマンドを実行してほしい。

 
 次に、上記のように完全に2nd boot loaderが無くなってしまったという場合ではなくても、たとえば少しでも「/boot/boot.b」を移動したら、たちまち同現象が起こる。それは「/boot/boot.b」を「/root/boot.b」へ移動したとかではなく、単に別のところへ移して、また「/boot/boot.b」に戻しても、物理的なハードディスク上の絶対番地など保証などされないのだから、やはり絶対番地不一致が起きて「LI」で止まる。

 ただ「/boot/boot.b」などLILOを構成するファイルは実際はあまり更新することもないだろうし、更新時はマップインストーラを実行するので、普通の使い方をしているぶんには更新による絶対番地の不一致は起き難いはずである。

 それよりも多いと思われるのがハードディスクの構成変更による絶対番地の変更だ。例えば以下のlilo.confを見てほしい。
boot = /dev/hda
map = /boot/map
prompt
timeout = 100

image = /boot/vmlinuz
  label = linux
  root = /dev/hdc1

other = /dev/hda1
  label = windows
  table = /dev/hda

 この設定ファイルを見てLILOを構成する各データがどこに配置されているか、読み取れる人はどれくらいいるだろうか。もっとも/etc/fstabなども見てみないと正確なところは分からないが、次のような構成を想像できると思う。

 プライマリマスター(/dev/hda)に繋がったハードディスクに少なくとも一つの基本領域があって、ここにWindowsがインストールされている。セカンダリマスター(/dev/hdc)に繋がったハードディスクに少なくとも一つの基本領域があって、そこにLinuxがインストールされている。LILOの1st Boot LoaderはプライマリマスターのHDDのMBRにある。たぶんLinuxデータはすべてセカンダリマスターのHDDにあると思われるので、LILOのその他のデータ(2nd Boot Loaderやマップファイルなど)やカーネルなども皆このハードディスク上にある。

 さて、ここで上記2つのハードディスクは全く触れることもなく、単にプライマリスレーブ(/dev/hdb)にハードディスクを一つ増設したとしよう。関係のないディスクの増設に過ぎないから、何事もないと期待するかもしれない。ところがどっこい、忽ち「LI」でLILOが止まって起動不能に陥る。これはハードディスクの絶対番地にはハードディスクの番号も含まれており、この番号がハードディスクの増設によってずれてしまったからだ。

 LILOはBIOSに依頼してハードディスクからデータを読むため、BIOSが認識できるようなハードディスクの管理しかできない。BIOSではハードディスクをプライマリマスターとかセカンダリスレーブとかの接続場所を正確に管理しているのではなく、単に見つけた順に番号を振った連番で管理しているだけである。

 たとえば上記設定ファイル例では/dev/hdaが第1ハードディスク、/dev/hdcが第2ハードディスクとして、LILOの各データには記録されている。この時点ではBIOSも同様の認識なので問題ない。ところが/dev/hdbが増設されるとBIOSから見るとこちらが第2ハードディスクとなり、/dev/hdcが第3ハードディスクになってしまう。

 このままLILOを更新せずに実行すると、まだLILOはデータが第2ハードディスクにあると思っているから、BIOSとLILOで認識の食い違いが起こる訳だ。BIOSに依頼してデータを読む以上、この認識の齟齬は致命的である。例では2nd Boot Loader/dev/hdcにあると思われるので、/dev/hdaにある1st Boot Loaderが、もはや第3ハードディスクになってしまった/dev/hdcにある2nd Boot Loaderをロードできず(BIOSには第2ハードディスクのデータの読み込みを依頼するので、増設したハードディスクの方を読みに行って、ロードできたと思っている)、そちらに制御を移しても正常に実行されず「LI」で止まる訳だ。

 一応この問題はあらためてマップインストーラを実行し、LILOの各データに「/dev/hdcは第3ハードディスク」であるとして記録しなおせば解決する。まあ大抵はこのようにマップインストーラの再実行で治るものが多いのだが、起動しないと再実行も当然できない訳で、やはりLILOの絶対番地依存の性質は大きな欠点と言わざるをえない。ブートディスクを手放すことができない訳である。

 更に上記例はマップインストーラの再実行で回避できる訳だが、単なる再実行では回避できない問題もある。それについては次項で説明する。

 因みにGRUBはこの絶対番地依存の度合いが非常に低いので、各データの変更に対して非常に柔軟だ。また絶対番地依存の部分も起動時に変更して起動するといったことが可能なので、殆ど起動不能になることはない。

 


BIOSから見たハードディスクの順序

 LILOはBIOSにハードディスクのデータの読み込みを依頼するため、BIOSと同様のハードディスク管理しかできないと説明した。これは実際は大きな問題ではない。少なくともLILOに限定された問題ではない。すべてのブートローダが抱えている問題である。

 問題なのはLILOがハードディスクの順序を決めるにあたってBIOSと相談している訳でもなく、デバイススペシャルファイル名(/dev/hdaとかいう名称)を見て、勝手にハードディスクの順序を決めてしまっていることだ。従って、少しでもイレギュラーな順序にしているとうまく動作しない。例えば/dev/hdaは第1ハードディスクで、/dev/hdbが第2ハードディスクと決めてしまっている。だから何らかの事情で、/dev/hdbを第1ハードディスクにしている場合、不都合が生じる。

 以下にIDEハードディスクを考えられる全てのパターンで接続させて、LILOが認識するハードディスクの順序(ドライブID)を調べてみた。ドライブIDが0x80が第1ハードディスク0x81が第2ハードディスクなどとなる。因みにBIOS(実験環境はASUS P2L97 AWARD BIOS 1010だ)ではPrimary-Mastor、Primary-Slave、Secondary-Mastor、Secondary-Slaveの順序で(これは不動)、接続されているものだけ、0x80から順にIDが振られます。

[LILOが認識するドライブID]

 

Primary-Mastor
/dev/hda

Primary-Slave
/dev/hdb

Secondary-Mastor
/dev/hdc

Secondary-Slave
/dev/hdd
1 0x80 - - -
2 - 0x81 - -
3 - - 0x80 -
4 - - - 0x81
5 0x80 0x81 - -
6 0x80 - 0x81 -
7 0x80 - - 0x82
8 - 0x81 0x80 -
9 - 0x81 - 0x81
10 - - 0x80 0x81
11 0x80 0x81 0x82 -
12 0x80 0x81 - 0x83
13 0x80 - 0x81 0x82
14   0x81 0x80 0x81
15 0x80 0x81 0x82 0x83

 太字がBIOSの認識と一致しているものだ。特徴としてはスレーブに接続したハードディスクは決して第1ハードディスクにならないね。結局全てのハードディスクに対してBIOSの認識と一致するパターンは1番、3番、5番、6番、10番、11番、13番、15番ということになる。それ以外(2番、4番、7番、8番、9番、12番、14番)はBIOSとLILOで認識が一致しない。

 またLILOはSCSIハードディスクは常にIDEより後だと決めてかかっている。最近はPC/AT互換機でもBIOSの設定ブートシーケンスを変更できるようになっているので、IDE、SCSI混在環境で、SCSIを先に設定した場合なども、当然LILOの認識とBIOSの認識する実際のハードディスクの順序に食い違が生じる。


 LILOとBIOSの認識に食い違いがLILOの動作不能の原因になることは前項で説明した。またこれはマップインストーラが上記のような動作をするのだから、このままでは何度マップインストーラを実行し直しても、一向に改善はされない。

 これを回避するために、LILO(マップインストーラ)に明示的に、このハードディスクが第1ハードディスクで、あっちの方が第2ハードディスクであるなど、BIOSが認識する順序(ドライブID)を教えてあげる必要がある。

 これはグローバルセクションdisk」オプションbios」サブオプションで指定する。「disk」オプションにはハードディスクのデバイス名を、「bios」サブオプションには第1ハードディスクなら0x80を第2ハードディスクなら0x81を指定する。

[BIOSから見たハードディスクの順序の設定]
boot = /dev/fd0
prompt
timeout = 100
disk = /dev/sda
  bios = 0x80
disk = /dev/hda
  bios = 0x81

image = boot/vmlinuz
  label = lin
  root = /dev/hda4

other = /dev/hda1
  label = win95
   ・
   ・

 これでBIOSとの認識の違いは是正することができる。

 


同じマップインストーラで複数のLILOを作る

 あるOSを起動している状態で、マップインストーラ(liloコマンド)でLILOを作った後で、設定ファイルを書き換えて、またマップインストーラを実行した場合、前の設定ファイルのLILOはどうなるだろうか?

 基本的には無効になる。ではたとえばインストール先をフロッピーにしたものとMBRにしたものを2つ作り、いずれも有効に利用することは同じOS上の同じマップインストーラからではできないのだろうか? 実はこのように使い分けをするために、インストール先を分けて複数のLILOを同じマップインストーラから作成することは可能である。

 本来この説明をするにはLILOのデータ構造を解説する必要があるのだが、その解説抜きに掻い摘んで説明する。インストール先は「boot」文で記述する訳だが、あとはinstall」文で記述するマップファイルを別のものにするだけで問題なく、使い分けができる。つまり競合を避けなければいけないはマップファイルだけだということである。まあ簡単だね。

[フロッピーにLILOをインストールするための設定ファイル]
boot = /dev/fd0
install = /boot/fdmap

[ルートにLILOをインストールするための設定ファイル]
boot = /dev/hda2
install = /boot/rootmap

[MBRにLILOをインストールするための設定ファイル]
boot = /dev/hda
install = /boot/mbrmap

 このようにしておけば、それぞれ有効なLILOとして問題なく動作する。因みに「install」文は省略するとデフォルトで「/boot/map」が使用されるので注意してほしい。

 


第2ハードディスク以降からのLinuxの起動

 Linuxの場合、アクティブでない基本領域からでもたとえ論理領域でも、また第2ハードディスク以降からでも基本的に問題なく起動することができる。Linuxはインストール位置に対して非常に柔軟なOSだ。

 しかしこれはあくまで最初からそこにLinuxをインストールした場合の話で最初に第1ハードディスクにインストールしたものを後から第2ハードディスクにする場合は問題である。インストール後に変更した場合は前述したようにLILOの絶対番地依存の性質によって、たちまち起動不能に陥る。

 ただしこれも前述したようにブートディスクなら起動できるから、これで起動してLILOを作り直せば大丈夫だ。またやはり前述のようにGRUBで起動してもいいだろう。

 しかしこれもハードディスクの接続は変えずに単にBIOSの設定などでBIOSからみたハードディスクの順序を変えただけ場合の話に過ぎない。例えばIDEのプライマリーマスターに接続していたものをプライマリースレーブやセカンダリマスターに変更するといった接続方法そのものを変える場合は実は話が簡単ではない。

 何度か述べているようにLinuxの場合、例えばIDEのプライマリーマスター「/dev/hda」というデバイス(スペシャル)ファイル名で表現される。プライマリスレーブ「/dev/hdb」になる。ハードディスクの接続を変えた場合、このデバイスファイル名が変わることになる。

 カーネルが存在する位置のデバイスファイル名が変わると、たとえブートディスクでも起動できなくなる。これはブートディスクにカーネルの位置としてデバイスファイル名で記録されてしまっているからだ。

 ただしGRUBを利用すればカーネルのロードは行うことはできる。これはGRUBは起動時に起動方法を柔軟に変更できたり、現在は存在しないブートエントリを作成しておくことも可能だからだ。起動時にGRUB Shellで手動で変わってしまったカーネルの位置を指定したりとか、予めエントリを作っておいてデバイスファイル名が変わった場合に備えておけばいいだろう。

 しかしこれでもまだ問題がある。GRUBで首尾よくカーネルがロードできても、その後のLinuxの起動プロセスの中でファイルシステムのマウントに失敗してしまうのだ。これはマウントするパーティションがデバイスファイル名でベタ書きされたデータがあるからである。それは/etc/fstab」ファイルだ。

 幸い通常デバイスファイル名がベタ書きされたデータはこの「/etc/fstab」ひとつだけだ。ではこれを書き換えてしまえばいいのはないだろうか。しかし問題はまだ残る(結構しつこい)。これをどのタイミングで書き換えるかである。結論から述べるといくつかの方法があり可能だ。

 しかしとても危険なので、万が一の場合に備え、レスキューディスク(ブートディスクではないだよ)は用意してほしい。それもちゃんとハードディスクの/etc/fstabを編集できるようにviなどのエディタが使えるレスキューディスクだ。別にレスキューディスクでなくても構いない。要は起動しなくなってしまったLinux上のデータを編集できる方法を用意しておけばいいのである。たとえば1FD Linuxを用意するとか、別のハードディスクから起動できるLinuxを用意しておいてもいいだろう。手段は問わない。この方法が用意できない人は危険なのでやらないでほしい。

 またGRUBが使えないといけないので、GRUBの全体構造をよく理解し、更にGRUBの詳細を熟読してGRUB Shellが使えるようにする必要がある。決して難しくないが、非常に簡単という訳でもない。GRUB Shellは必ずしも必要ないのだが、失敗時の対応のために是非ともマスターしておいてもらいたい。

 具体的に、最初にプライマリマスター(/dev/hda)にインストールしたものをプライマリスレーブ(/dev/hdb)に移してLinuxを起動する場合を例にとって説明しよう。カーネルのある/bootが第1基本領域(/dev/hda1)、ルートが第1論理領域(/dev/hda5)、swapが第2論理領域(/dev/hda6)ということにしよう。

  1. GRUBのブートディスクを作成する。
  2. プライマリマスターに接続している時に当該Linuxを起動する。
  3. /etc/fstabを編集して、/dev/hda/dev/hdbに書き換える。
  4. システムをシャットダウンする。
  5. ハードディスクをプライマリスレーブに繋げ変える。
  6. GRUBブートディスクで起動する。
  7. プライマリスレーブのカーネルをロードする。
  8. プライマリスレーブからLinuxが正常に起動する。

 手順は以上になる。それぞれをもう少し詳しく説明しよう。

 まずGRUBのブートディスクだが、GRUBの詳細を参考にして作ってほしい。メニューから起動できるようにmenu.lstも作った方がいいだろう。例えば以下のようなmenu.lstになるはずである。

[設定ファイル「/boot/grub/menu.lst」の記述例]
timeout 30
default 0

title Turbo Linux 6.0 Workstation
kernel (hd0,0)/vmlinuz root=/dev/hda5
initrd (hd0,0)/initrd

 さらに予めプライマリスレーブに接続した時のためのエントリも作っておこう。正しく作っておけばGRUB Shellを使う必要がなくなる。

[環境変更後のエントリも加えたmenu.lstの記述例]
timeout 30
default 0

title Turbo Linux 6.0 Workstation hda
kernel (hd0,0)/vmlinuz root=/dev/hda5
initrd (hd0,0)/initrd

title Turbo Linux 6.0 Workstation hdb
kernel (hd1,0)/vmlinuz root=/dev/hdb5
initrd (hd1,0)/initrd

 (hd1,0)の部分はもし接続を変えるだけで、プライマリマスターに何か別のディスクを接続する訳ではないのなら、ハードディスクのBIOSから見た順序は変わらないので、元のままでいい。もっともプライマリマスターに別のディスクを接続する予定がないのにプライマリスレーブに接続替えすることは普通ないだろうが。

 次に移行前の状態でLinuxを起動し、/etc/fstabを書き換える。何しろ書き換えたら今度は現環境では起動しなくなるのでここは慎重にやりたいところだ。間違えて現環境も新環境も起動できないようなものに書き換えてしまったら、前述のようにレスキューディスクなどのお世話になることになる。

 例の場合、元の/etc/fstabは以下のようなイメージだと思う。

[/etc/fstabの記述例]
/dev/hda1           /boot              ext2        defaults               1     1
/dev/hda5           /                    ext2        defaults               1     1
/dev/cdrom         /mnt/cdrom     iso9660    noauto,owner,ro   0     0
/dev/fd0             /mnt/floppy      auto        noauto,owner,ro   0     0
none                   /proc              proc       defaults               0     0
none                   /dev/pts          devpts   gid=5,mode=620     0     0
/dev/hda6           swap               swap       defaults               0     0

 これをプライマリスレーブ(/dev/hdb)用に書き換えると以下のようになるだろう。

[変更後の/etc/fstab]
/dev/hdb1           /boot              ext2        defaults               1     1
/dev/hdb5           /                    ext2        defaults               1     1
/dev/cdrom         /mnt/cdrom     iso9660    noauto,owner,ro   0     0
/dev/fd0             /mnt/floppy      auto        noauto,owner,ro   0     0
none                   /proc              proc       defaults               0     0
none                   /dev/pts          devpts   gid=5,mode=620     0     0
/dev/hdb6           swap               swap       defaults               0     0

 まあ、hdaとなっている部分をhdbに変えるだけなのでまず間違えることはないだろう。このように変更すると今度はもはやプライマリマスター接続では起動できなくなる。

 後はシャットダウンして、繋ぎ変えて起動だね。起動はGRUBブートディスクで行い、予め作っておいたhdb用のエントリから起動する。

 以上でうまくプライマリースレーブに引越したTurboLinuxが起動したはずである。起動後は新環境用にLILOを作成しなおしてもいいし、そのままGRUBディスクで起動してもいいし、GRUBを正式にハードディスクに導入してもいいだろう。

 


第2ハードディスク以降からのWindowsの起動

 MicrosoftのOSは第2ハードディスク以降からの起動は何かと問題がある。そもそも普通は第2ハードディスク以降にインストールすることはできない。一旦第1ハードディスクにインストールして、接続替えするということになる。この問題については「機能編」を参照してほしい。

 ただし前述のLinuxの場合のように接続位置を保持しているデータはないので、インストール後の接続替えは逆に楽だ。もっとも最初から第2ハードディスク以降にインストールできないので、接続替えができなかったら万事休すである。

 MicrosoftのOSを第2ハードディスク以降から起動するには「機能編」でも説明しているように、いくつか方法があるようだが、LILOの場合は最も一般的なドライブスワップ方式を採用している。これは第2ハードディスク以降と第1ハードディスクをBIOSレベルで入れ替えてしまってOSを騙してしまう方法である。

 それはmap-drive」オプションto」サブオプションで指定する。「map-drive」オプションには元のデバイスのBIOSが認識する順序(1番なら0x80)、「to」サブオプションにはそのパーティションが存在する本当のハードディスクのBIOSが認識する順序(2番なら0x81)を指定する。入れ替え(スワップ)なので、(0x81から0x80)も合わせて指定しておかないと正しく動作しない。

[ドライブスワップの設定]
boot = /dev/hda
prompt
timeout = 100

image = boot/vmlinuz
  label = lin
  root = /dev/hda4

other = /dev/hdb1
  label = win95
  map-drive = 0x80
   to = 0x081

  map-drive = 0x81
   to = 0x080

  table = /dev/hdb

other = /dev/hdb2
  label = winnt
  map-drive = 0x80
   to = 0x081

  map-drive = 0x81
   to = 0x080

  table = /dev/hdb
   ・
   ・

 これで第2ハードディスクにあるMicrosoft系のOSの起動も多少は可能になる。しかしそもそも第2ハードディスクからの起動を想定して作られたOSではないので、まくいかない場合もある。

 たとえばWindows9xは第2ハードディスクだった場合、先頭のパーティションでないとうまく起動しないことがある。このあたりの事情はLILO側ではどうしようもない。どんなブートローダを使っても同じことだ。あまりWindows系OSの第2ハードディスク以降からの起動に関し、多大な期待はしないほうがいいだろう。

 


アクティブ属性の変更

 複数のWindows系OSとマルチブートを行っていく場合、どうしても必要になるのがアクティブ属性の切り替え機能である。このことについての内容的な詳細は「機能編」を参照してほしい。

 LILOにはちゃんと特定のOSを起動した場合、特定のパーティションをアクティブにしたり、別のパーティションを非アクティブにしたりする機能が用意されている。change」オプションとそのpartition」サブオプションと更にそのactivate」サブオプション(アクティブ化)、deactivate」サブオプション(非アクティブ化)を使う。

[アクティブ属性の切り替え]
boot = /dev/hda
prompt
timeout = 100

image = boot/vmlinuz
  label = lin
  root = /dev/hda4

other = /dev/hda1
  label = win95
  change
   partition = /dev/hda1
    activate
   partition = /dev/hda2
    deactivate
   partition = /dev/hda3
    deactivate
  table = /dev/hda

other = /dev/hda2
  label = winnt
  change
   partition = /dev/hda1
    deactivate
   partition = /dev/hda2
    activate
   partition = /dev/hda3
    deactivate
  table = /dev/hda

other = /dev/hda3
  label = win98
  change
   partition = /dev/hda1
    deactivate
   partition = /dev/hda2
    deactivate
   partition = /dev/hda3
    activate
  table = /dev/hda

 図の例ではLinuxの他、Windows95WindowsNTWindows98がそれぞれ別の基本領域にインストールされており、LILOによってマルチブートを行う場合を示している。またWindows系OSはそれぞれ、自分が起動されると自分の領域をアクティブにするとともに、他のWindows系OSがインストールされているパーティションを非アクティブ化している。

 因みにこの「change」オプションはそのサブオプションとともに、other」セクション(つまりLinux以外のOSのセクション)にしか指定できない。「image」セクション(Linuxのセクション)に指定するとエラーになる。つまりLinuxを起動するときには他のパーティションのアクティブ属性を変更できないのだ。これはLinuxは別に他のパーティションのアクティブ属性がどうなっていようと起動に何の支障もないので、その必要がないからだろう。もっともLinux起動時にも他のパーティションのアクティブ属性を変更したいという要望は皆無ではないので、用意してほしかったね。

 ところで「change」オプションパーティションテーブルの情報を書き換えるオプションなので、一応危険視されており、LILOコマンドのデフォルトでは利用できないことになっている(少なくともReadmeにはそう書いてある)。この機能を利用するにはREWRITE_TABLE」環境変数を定義して、LILOコマンドをmakeし直す必要がある。

 もっともLILO Ver21のmakefileはデフォルトで上記環境変数が定義されていた。最近のディストリビューションに入っているLILOなら、最初から利用できるものが多いようだ。もし利用できないようなら自分でmakeし直してほしい。

 


隠しパーティション

 最初の私が構築した設定ファイル例にはなかったが、Windows系OSのマルチブートにおいて、アクティブ属性の変更とともに重要なのが隠しパーティションである。このことについての内容的な詳細も、「機能編」を参照してほしい。

 やはり「change」オプションの孫サブオプションにset」サブオプションがあり、設定するパーティションタイプを指定する。ただし多くのパーティションタイプはデフォルトでは未定義なので、あらかじめグローバルオプションchange-rules」オプションで定義しておく必要がある。

 type」サブオプションで、パーティションタイプ名を定義し、normal」サブオプションで通常の値を指定し、hidden」サブオプションで隠しパーティション時の値を指定する。値の指定は16進数でも10進数でもかまいないが、こういう値は習慣的に16進数だろう。

[パーティションタイプの定義]
boot = /dev/hda
prompt
timeout = 100
change-rules
  type = fat32
   normal = 0x0b
   hidden = 0x1b
  type = ntfs
   normal = 0x07
   hidden = 0x17

image = boot/vmlinuz
  label = lin
  root = /dev/hda4

other = /dev/hda1
  label = win95
   ・
   ・

 パーティションタイプの中で、FAT12FAT16(Small)、及びFAT16(Big)の3つだけは既に以下のように定義されている。

type = DOS12
  normal = 0x01
  hidden = 0x11

type = DOS16_Small
  normal = 0x04
  hidden = 0x14

type = DOS16_Big
  normal = 0x06
  hidden = 0x16

 そして各otherセクションの「change」オプション「parttition」サブオプションのサブオプションとしてset」オプションで、そのOSを起動した時に、どのパーティションをどういうパーティションタイプに設定するかを記述する。

 値は定義したパーティションタイプ名_{normalまたはhidden}という形式になる。

[隠しパーティションの設定]
boot = /dev/hda
prompt
timeout = 100
change-rules
  type = fat32
   normal = 0x0b
   hidden = 0x1b
  type = ntfs
   normal = 0x07
   hidden = 0x17

image = boot/vmlinuz
  label = lin
  root = /dev/hda4

other = /dev/hda1
  label = win95
  change
   partition = /dev/hda1
    activate
    
set = DOS16_big_normal
   partition = /dev/hda2
    deactivate
    
set = ntfs_hidden
   partition = /dev/hda3
    deactivate
    
set = fat32_hidden
  table = /dev/hda

other = /dev/hda2
  label = winnt
  change
   partition = /dev/hda1
    deactivate
    
set = DOS16_big_hidden
   partition = /dev/hda2
    activate
    
set = ntfs_normal
   partition = /dev/hda3
    deactivate
    
set = fat32_hidden
  table = /dev/hda

other = /dev/hda3
  label = win98
  change
   partition = /dev/hda1
    deactivate
    
set = DOS16_big_hidden
   partition = /dev/hda2
    deactivate
    
set = ntfs_hidden
   partition = /dev/hda3
    activate
    
set = fat32_normal
  table = /dev/hda

 例ではたとえば、/dev/hda2WindowsNTを起動した場合、同パーティションは通常のNTFSに設定され、Windows95Windows98のパーティションはそれぞれFAT16FAT32隠しパーティションに設定されている。これだけきめ細かい設定は市販ツールでもできないものが多い。

 


←前へ(Windows中級編)  次へ(その他のOS編)→

 


目次へ