2013年1月21日月曜日

GRUBとEFIの組み合わせで使うときのメモ またはEFI全般のtips

EFI移行でやらかしたバカ話について2つ記事を書きました( 1 2 )

しかし実はこれは12月13-14日の出来事。もうEFIに移行して1月です。
そこでいくつかtipsというかメモを残します。
ほぼ推測に近いので
間違いがありありな気がするので指摘があれば是非どうぞ ちょっと補足しました
(ちゃんとドキュメント読め)



まず、構成について。

UEFIを使用するときには、ストレージの第一パーティションをUEFIのシステムパーティションとします。
BIOSの時はHDDやパーティションの先頭512バイト(いわゆるMBRやPBR)にgrubのステージ1を
インストールしていたかと思います。このステージ1のバイナリが、
/bootのあるパーティションのステージ2のバイナリを読みこむわけです。
つまりステージ1のバイナリはファイルシステムから見えないとこに書きこむわけですね。

ところがUEFIはステージ1のバイナリはUEFIシステムパーティションに書き込みます。
このシステムパーティションはNTFS (FAT32でした.指摘ありがとうございます) でフォーマットされ、
Windows8のインストーラだと128MBほど確保されます。
これだと普通にステージ1のバイナリも簡単に取り扱えます。けっこう便利。
一つのOSを起動するBootloaderを複数同時に存在させることも簡単。(GRUBとSyslinuxとELILOと…等)

Windows8のブートローダーは、このパーティションの
\EFI\Microsoft\Boot\bootmgrw.efi (x64)
\EFI\Microsfot\Boot\bootmgr.efi (x86)
にインストールされる模様。

そして、これが一番驚いたのですが、
EFIのブートローダはEFIそのものに登録できます。
どういうことかというと、x121eだとBIOSの設定で選択するブートデバイスの一つとしてブートローダを登録できるのです。
これはびっくりしました。
Windows8は初回起動時に登録するみたいです。
EFI ShellやLinuxのefibootmgr(後述)でWindows8のブートローダのエントリを消しても次に
Windows8を起動するとエントリが復活します。厄介。

登録したエントリーではなく起動デバイスを従来通りHDDを先頭にもってくると、
\EFI\Boot\bootx64.efi
をブートローダとして起動しました。おそらく、ここにブートローダではなくてUEFI用にEDKでビルドしたアプリケーションを配置するとそれが起動します。
x86だとおそらく
\EFI\Boot\boot.efi
でしょう


さて、LinuxでのUEFIの扱いについて。

LinuxをUEFIから起動するときは、/boot/efiにUEFIシステムパーティションをマウントします。
そして、GRUBはGRUB2を使用し,
$grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=<id-name> --recheck
 とインスールします。
すると、/boot/grubにいつも通りのGRUBの設定やローダーやフォントやモジュールといったファイル郡が置かれます。
そして、
/boot/efi/EFI/<id-name>/grubx64.efi
にステージ1のバイナリが置かれるのです。
このとき、efivarsというモジュールをロードしていると、
grubは自動でefibootmgrを実行してUEFIに勝手に<id-name>という名前でブートローダを登録してくれます。便利。
因みにこれを手動でやるには、
$efibootmgr -c -l \\path\\to\\loader -L "<id-name">
です。
GRUBの場合はefibootmgr -c -l \\EFI\\<id-name>\\grubx64.efi -L "<id-name>"ですね。
ここでのパスは、システムパーティションの先頭からのパスです。
また、/ではなく\を使います。(もしかしたら/でもいいかもしれません)

もし、この登録したエントリ番号が0x0008だった時、
$efibootmgr -b 0008 -B
とするとこのエントリを削除できます。
ほかにも、わざわざPC起動時にキーを連打してBIOS設定画面に入ってーなんてしなくても
ブートデバイス(登録したブートローダのエントリ含む)の優先順やタイムアウト時間もefibootmgrから設定することが出来ます。かなり便利。


最後に2つ。

まず、Windows8のブートローダについて注意点。
Windows Visata/7同様BCDを使ってますが、BCDEdit、bootmgr等でエントリを増やしてもGrub4dos等は起動出来ません。PEヘッダのあるバイナリしか実行できないようです。
つまり、Windows8のBoot ManagerはWindows7や8のwinload.efiを起動しますがこのwinload.efiは
Windows用バイナリなので逆にGRUBやEFI Shellからwinload.efiを起動しても失敗するだけです。
なのでWindows8のブートローダからはWindows関連のものしか起動できないのです。
マウスとか使えるし面白いので残念。

次に、起動できるものについて。
基本、UEFIは64bitで起動したら64bitの、32bitで起動したら32bitのバイナリのみ実行できます。
なので、grub-efiからはフロッピーに入れたMS-DOS等が実行できないです。
以前紹介したLinuxからBIOSをアップデートの方法も使えないのです。
まあGRUBからじゃなくてそもそもリムーバブルデバイスそのものからブートしてしまえば、
そのリムーバブルデバイスのブートローダのバイナリが実行できると思いますが。
ただ、前みたいにとりあえずGRUB起動してそこからGRUBのShellでなんでも起動とはいかなくなったというだけではあります。

それにこの起動できるバイナリはOSロード以前の段階のはなしなので、一度カーネルを読んでしまえばあとはそのOSの機能(Wow64, multilib)があれば64bitOSから32bitバイナリは実行できるので安心を。