WindowsとLinuxのマルチブートあれこれ

なんか書き始めたら超長くなった。

OSのブートシーケンス

まず簡単にOSのブートプロセスを反芻。

bios -> MBR -> ブートローダ (-> チェインロード * n) ->OS

こういう流れ。
実際のところたいていブートローダはMBRに収まりきらないので、2段階ステップになっている。
MBRにはブートローダの本体を呼び出すだけのシンプルなローダ(grubでいうところのstage1)が配置され、そこから呼び出された本体(grubでいうところのstage2。まあgrubは1.5が間にはいるけど)からOSを起動する感じ。

ブートローダの種類

で、ブートローダの種類としては

  • Windows NT/2000/XP/Server 2003 — ntldr + boot.ini
  • Windows Vista/7/Server 2008 — bootmgr/win7ldr + bcd
  • Linux — LILO or GRUB

っていうかんじだろうか。
9xはほっとく。
まあ原理的には同じ。

ファイルシステムへの対応状況

んで、各ブートローダによってブートできるファイルシステムが異なる。
M$系は当然Linux系ファイルシステムなんて知ったこっちゃない路線なんで、ext3やext4ファイルシステムなんぞ認識できるわけがない。

GRUBはext4は対応していなかったが最近対応したっぽい。
GRUB2はext4対応済み。
ただし、Debian/sidでは今のところdmraidにgrub-pcのインストールが対応していないっぽい。(grub-mkdevicemapがインストール時に強制的に走らされるようで、そのときに/dev/mapperをみてくれない。まあmkdevicemapがそうなのは昔からだが)
ext4なファイルシステムをブートするにはgrub-pcがいるわけで、つまりdmraidなext4だと困ったことになりそう。
GRUBにgrub-pcが追加されたのは最近なので、バージョンをlennyにでもholdしておけばdmraidなext3はいける。
GRUB2はしらねっていうかたぶんgrub-pcのインストールを潜り抜ければ、devicemap手書きでどっちもいけるんだろう。
ちなみにWindowsとのデュアルブートとかでよくみるchainloader +1ってのは、そのパーティションの先頭から1ブロック目(つまりPBR)はじいてブートローダをチェインロードするってやつ。
これで認識できないファイルシステムでも間接ブートできるようになるわけだ。

LILOはファイルシステムを問わない。
というか、ファイルシステムを理解しない。
ほかのブートローダと根本的に違う部分はここ。
ほかのブートローダは、ファイルシステムを認識して、ファイル名からファイルポインタを取得して、そのアドレスをたたいてOSを起動させる。
LILOはハードウェア上の物理的なアドレス情報を格納しておいて、そのアドレスを直接はじく。
なもんで、たとえばHDDを換装した場合なんかを考えると、GRUBならOSをまるまるcpなんかでこぴぺでもファイルパスから物理アドレスが取れるので起動できるが、LILOはddコマンドとかできっちり物理アドレスも一致させておかないと起動しなくなる。
その代わり、ファイルシステムを問わないので、どんな未知のファイルシステムやRAID、LVM等による冗長化構成なんかでもシステムとして正常であれば問答無用で起動できる。

WindowsのブートローダからLinuxを起動する

Windows君はオレオレなので、OSをインストールすると何が何でもMBRに自分のブートローダのgrubでいうところのstage1をつっこむ。
LILOやGRUBはPBRも選択できる。
なので、デュアルブートなんかを考えている場合はMBRは素直にWindows君に譲ってあげたほうがいい、といいたいところだけれども、そのくせLinux系ファイルシステムが認識できない上にGRUBみたいなチェインロードの仕組みも持ってないもんだから、Windows系のブートローダからLinuxを起動するのには工夫が必要。

とりあえず、WindowsをLinuxよりも後に入れると、MBRはWindowsによって書き換えられ、強制的にブートローダはWindowsのものを使用することが強要される。
まあ、grubなんかはそのMBRをまたちゃんとstage1.5をみるように

grub > root(hd0,0)
grub > setup(hd0)

とかすれば元に戻せるんだけど。

んで、Windowsのブートローダは前述のとおりファイルシステム読めないわgrub的チェインローダー機能もないわなので、橋渡しをしてあげなければならない。
やり方としては、grubのstage1相当のイメージをWindowsの理解できるファイルシステム上に用意してあげてそこからチェインロードする感じになる。
例として、以下のような構成で考える。

sda — Windowsのブートローダ
sda1 — Linux — ext3
sda2 — Windows — NTFS

この場合

BIOS -> sda MBR-> sda2のntldr or bootmgr -> sda2のgrub/stage1相当品 -> sda1のgrub/stage2 -> お好きにどうぞ

っていう感じにすればいける。
適当に共用ファイルシステムとしてsda3にFAT32とか作っておいてそこにstage1相当品を放り込んでおくのもひとつの手だ。

んで、そのstage1相当品の用意だけども、二通り。

  1. stage1をそのまま抜き出す
  2. 用意してくれたのを使う

1の方法について。
まず、stage1をMBRに入れていたときはWindowsに上書きされているのでまた作らないといけません。
レスキューでもLiveCDでもなんでもいいんで気合でgrubをたたいて

grub > root(hd0,0)
grub > setup(hd0,0)

とかってやってsda1のPBRにつっこみましょう。
ちなみにgrubのパッケージに含まれているstage1ファイルをぱくってきちゃだめなの?っていうのがあるかもしれないけどだめです。
stage1は次にアクセスするべきstage1.5もしくはstage2の場所の情報が必要なので。
ファイルシステム上にstage2をおく場合(普通はそうなるだろう)は、ファイルシステムに応じたstage1.5がないとstage2の配置されたファイルシステムを認識できないので、普通はstage1.5の場所が必要に。
で、まあsda1のPBRにstage1が無事あるとすると、これをイメージ化すればいい。
イメージ化はddコマンドで

# dd if=/dev/sda1 of=grub.stage1 bs=512 count=1

とかやればできる。
で、こいつを気合でWindowsの認識できるファイルシステム上に配置する。
ntfsprogsとか使えばlinuxからこぴぺできるけどそうじゃない場合はフロッピーやらUSBメモリやらを経由してsda2におくか、sda3としてFAT32パーティション用意してそこにおくかってかんじに。
DDforWindowsを使うのも手。
まあC直下においたとする。
ここまでくるとWindowsのブートローダからみえるようになったわけなので、後はそれを指定してブートするエントリを作ってやれば、そのエントリを選択したときはsda1上のgrubのstage2が起動するようになる。
ntldrの場合はboot.iniの[Operationg Systems]セクションにLinuxブート用のエントリを記述。

C:grub.stage1=”Linux”

みたいにすればいいだろう。
bcdの場合は少々めんどくさい。
XPなんかが入っていてntldr(レガシーローダ)を使う場合はコマンドプロンプトから以下のように。

bcdedit /copy {ntldr} /d “Linux”
bcdedit /set {作ったGUID} device partition=C:
bcdedit /set {作ったGUID} path grub.stage1
bcdedit /displayorder {作ったGUID} /addlast

ブートセクタ(real-mode boot sector)指定する場合は以下のように。

bcdedit /create /d “Linux” /application BOOTSECTOR
bcdedit /set {作ったGUID} device boot
bcdedit /set {作ったGUID} path grub.stage1
bcdedit /displayorder {作ったGUID} /addlast

ああめんどくさい。

で、その2。
stage1をもってくんのがめんどいっていう人のために用意されてる素敵なものを使う場合。
GRUB4DOSってのがとりあえずある。
4DOSっていう割りにNTFSとかもいけちゃう。
実のところgrubの場合はstage1を引っこ抜くなんてやらないでこれ使ったほうが楽。
ほかのブートローダの場合は対応するやつを知らないのでやっぱりイメージ作ることになるけど。
で、どうするかっていうととりあえず解凍してgrldrとgrldr.mbrをC直下に置く。
あとはエントリを作ってやればいい。

boot.iniの場合

C:grldr=”GRUB4DOS”

bcdの場合

   bcdedit /create /d "GRUB4DOS" /application bootsector
   bcdedit /set {id} device boot
   bcdedit /set {id} path grldr.mbr
   bcdedit /displayorder {id} /addlast

多少はしょってるが詳しい話はwiki読めばわかる。
ext4対応はとりあえず明示されていないので、ext4なんかの場合はイメージを抜いたほうが無難。
ちなみにMBRやPBRにGRUB4DOSを入れる方法もあるが、その辺をしたい人は説明しなくてもわかるだろうから割愛。

LinuxのブートローダからWindowsを起動する

構成は以下のような場合。

sda — Linuxのブートローダ
sda1 — Linux — ext3
sda2 — Windows — NTFS

長々しかったWindowsブートローダから起動するのと違ってあっさり。

GRUBの場合

/boot/grub/menu.lstに以下を追記してupdate-grub

title Windows
rootnoverify (hd0,1)
chainloader +1

LILOの場合

/etc/lilo.confに以下を追記して/sbin/lilo

other=/dev/sda2
    label=Windows
    table=/dev/sda

Windowsと比べて簡単すぎるだろ女子高生。。。。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>