前回 、最近のマザーボードが採用しているUEFIと3TB以上のHDDを使う際に必要となるGPTの概要を説明し、UEFIではOSを起動するためのブートローダの扱いも従来のSystem BIOSとは異なっていることを紹介しました。
今回はUEFIがGPT形式のHDDからOSを起動する手順についてより具体的に説明し、Plamo Linuxがどういう形でUEFIに対応したかを紹介してみます。
ESPとブートローダ
前回、GPT形式のHDDでは、伝統的なMBR形式とは異なり、OSを起動するためのブートローダ用に専用のパーティション が用意されていることを紹介しました。このパーティションはEFIシステムパーティション (ESP)と呼ばれ、専用のパーティションIDが割り当てられ、FAT32形式でフォーマットするように規定されています。
たとえば、Windows8がインストールされたGPT HDDをLinuxのcfdiskで調べると図1 のように見えます。この例では/dev/sda2が100MBのESP になっています。
図1 GPT HDD上のESP
UEFIは接続されたHDD上にESPがあるかを調べ、ESPが見つかればそのパーティション上の\EFI\BOOT\ディレクトリ以下にあるブートローダを探します。UEFI用のブートローダは、.EFIという拡張子を持つ、PE形式のバイナリファイル です。
PE(Portable Executable)形式はWindowsが採用しているバイナリ形式で、現在のLinuxが採用しているELF(Executable and Linkable Format)形式と同様、System-V UnixのCOFF(Common Object File Format)形式を発展させたバイナリ形式です。
UEFIの仕様では、x86_64環境の場合は\EFI\BOOT\BOOTX64.EFI 、32ビットのx86環境の場合は\EFI\BOOT\BOOTIA32.EFI がデフォルトのブートローダと見なされます。しかし、ブートローダが1つしか使えないとOSを切り替えるにも不便なので、たいていのUEFIの実装では\EFI\以下のサブディレクトリにあるPE形式の.EFIファイルをブートローダと見なして、それらを選択できるようになっているようです。
さて、実際の環境ではどのようにブートローダが配置されているのか、LinuxとWindowsがデュアル・ブートできる環境で、ESPを/boot/efi/にマウントして調べてみました。
$ find /boot/efi/EFI/ -name "*efi" -a -exec file {} \;
/boot/efi/EFI/Boot/bootx64.efi: PE32+ executable (DLL) (EFI application) x86-64, for MS Windows
/boot/efi/EFI/Microsoft/Boot/bootmgfw.efi: PE32+ executable (DLL) (EFI application) x86-64, for MS Windows
/boot/efi/EFI/Microsoft/Boot/bootmgr.efi: PE32+ executable x86-64, for MS Windows
/boot/efi/EFI/Microsoft/Boot/memtest.efi: PE32+ executable x86-64, for MS Windows
/boot/efi/EFI/grub/grubx64.efi: PE32+ executable (EFI application) x86-64 (stripped to external PDB), for MS Windows
ESPの\EFIディレクトリ以下には.efiの拡張子を持つファイルが5つあり、そのうちの"EFI application"と認識されているbootmgfw.efiとgrubx64.efiがそれぞれWindowsとLinux用のブートローダです。もう一つのEFI applicationであるbootx64.efiはサイズから見てbootmgfw.efiのコピーのようです。
これらのブートローダを読み込んだASUS B85M-EのUEFIは起動デバイスの選択肢として、"grub"と"Windows Boot Manager"を表示し、指定に応じてそれぞれのOSを起動することができます。
図2 ASUS B85M-EのUEFIメニュー画面
一方、同様の設定を作ってもVirtualBoxのUEFIにはブートローダを選ぶ機能はなく、BOOTX64.EFIしかブートローダと認識しませんでした。VirtualBoxのような仮想環境の場合、複数のブートローダを使い分ける必要はまず無いので、このあたりは割り切った実装になっているようです。
Linux用UEFIブートローダ
前節では説明の都合上grubx64.efiもまとめて紹介したものの、本節では改めてこのブートローダの出所について説明することにします。
前節で紹介したように、UEFIで起動するためには
マザーボードのファームウェアがUEFIに対応していること
が必要です。加えて、
HDDがGPT形式になっていること
HDD上にFAT32形式でフォーマットされたESPが存在し、
ESPの\EFI\BOOT\以下に.EFIという拡張子を持ったPE形式のブートローダがあること
が必要になります。
インストーラとしては、前者のハードウェア的な条件はユーザに用意してもらうことにして、それらの上で後者の環境を作る、ということになります。後者のうち、HDDのディスクラベルやESPを作る作業は既存のインストーラを改造すれば対応できそうなので、残る条件はLinux環境で使えるEFI用のPE形式のブートローダ 、ということになります。
ざっと調べたところ、Linuxの代表的なブートローダであるliloとgrubそれぞれにUEFI対応版が存在していることがわかりました。さて、どっちがいいかな…、としばし考えたものの、メンテナの名倉さんがしばらく前からUEFI対応のgrubをPlamo-testに上げてくれていることを思い出し、その作業を元にgrubのUEFI対応版 を作ってみることにしました。
ftp.gnu.org等で公開されているgrubの公式版は2012年の2.00で止まったままで、最新の開発版はgit経由で取り寄せることになっています。しかしながら、あまり新しい開発版を使うのもトラブルの元になりそうなので、Debian方面で公開されている2.02_28というバージョンを使うことにしました。
grubでUEFI対応版を作るためには--with-platform=efi というオプションを指定する必要があります。
$ ./configure --prefix=/usr --with-platform=efi
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking target system type... x86_64-unknown-linux-gnu
...
*******************************************************
GRUB2 will be compiled with following components:
Platform: x86_64-efi
With devmapper support: Yes
With memory debugging: No
...
このオプション指定でビルドして、試しにローカルにインストールしてみると、モジュール類のインストール先が/usr/lib/grub/x86_64-efi/に変わりました。
$ make ; make install DESTDIR=`pwd`/work
....
$ ls ./work/usr/lib/grub/x86_64-efi/
acpi.mod gcry_whirlpool.mod part_plan.mod
acpi.module* gcry_whirlpool.module* part_plan.module*
adler32.mod gdb_grub* part_sun.mod
...
--with-platform=efiオプションを付けない場合、grubのモジュールは/usr/lib/grub/i386-pc/にインストールされるので、これらのモジュールはUEFI用と考えてよさそうです。しかしながら、これらのモジュールを確認するとPE形式ではなくLinuxネイティブのELF形式です。
$ file ./work/usr/lib/grub/x86_64-efi/acpi.mod
work/usr/lib/grub/x86_64-efi/acpi.mod: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
あれれ、PE形式じゃないとUEFIは認識してくれないはずでは…、とgrubのドキュメントやソースコードをざっと眺めたところ、grub-install やgrub-mkimage など実際に動作するブートローダを用意する際に、これらモジュールのヘッダ部分等を切り貼りして、異なるバイナリ形式に変換する機能 が用意されているようです。
$ grub-mkimage --help
使い方: grub-mkimage [OPTION...] [OPTION]... [MODULES]
Make a bootable image of GRUB.
-c, --config=FILE embed FILE as an early config
-C, --compression=(xz|none|auto)
choose the compression to use for core image
...
-o, --output=FILE output a generated image to FILE [default=stdout]
-O, --format=FORMAT generate an image in FORMAT
available formats: i386-coreboot, i386-multiboot,
i386-pc, i386-pc-pxe, i386-pc-eltorito, i386-efi,
i386-ieee1275, i386-qemu, x86_64-efi, i386-xen,
x86_64-xen, mipsel-yeeloong-flash,
...
確かにgrubはさまざまなOSを起動するMultiboot specificationの考え方で開発され、Linuxのみならず、GNU HURDやBSD系UNIXも起動できるブートローダだから、さまざまなCPUやバイナリ形式に対応する必要があるものの、自前でバイナリ形式を変換する機能まで持っているのにはちょっと驚きました。
VirtualBox環境でのUEFIインストール例
UEFIに対応したgrubも用意できたので、Plamo-6.0ではUEFIインストールに仮対応 することにしました。「 仮」というのはESPを自動的に作成する処理を組み込めず、ESP回りの作業は手動で行う必要があるためです。
以下ではPlamo-6.0のDVDイメージを使って、VirtualBoxのUEFI環境にインストールする際、どのような作業が必要なのかを紹介してみます。
まずVirtualBoxでUEFI機能を使うには、該当する仮想マシンの「設定」 ->「システム」にある「拡張機能」の「EFIを有効化 」をチェックしておきます。
図3 「 EFIを有効化」オプション
次にPlamo-6.0のDVDイメージを「仮想光学ディスクファイル」としてCDドライブに指定して起動します。EFIを有効化して起動すればGNU GRUBのブートメニューが表示され、4種類の起動方法が選択できます。たいていの場合、"Plamo Linux install on VirtualBox"を選べば起動するものの、VirtualBoxのドライブ設定(IDEに接続するかSATAに接続するか、等)によって認識されるデバイスの順番が変るので、うまく起動しない場合は別の項目を試してください。
図4 UEFI DVDから起動したメニュー
インストールの流れは以前のバージョンと同じものの、HDDをフォーマットする際に「ラベル 」(パーティションテーブルの種類)としてGPT を指定し、ブートローダ用のESPを独立したパーティション として作成する必要があります。
図5 新規HDDのパーティションテーブルをGPT形式に指定
今回は8GBのHDDの先頭の128MBをESP用にすることにしました。ESPにするにはパーティションタイプを変更 する必要があるのを忘れないでください。
図6 cfdiskで必要なパーティションを作成
上述のように、ESPはFAT32形式でフォーマットされる必要があるものの、Plamo-6.0のインストーラにはESPを自動フォーマットする機能は入れていないので、ESPは手動でフォーマットする 必要があります。具体的には、パッケージのインストールを進めている途中にでも、ALT+F2でコンソールを切り替えてログインし、mkfs.vfatコマンドを実行します。オプションには-F32(FAT32の指定)と-s2(1クラスタあたり2セクタ)を指定すればいいでしょう。
図7 別コンソールからESPを手動でフォーマット
UEFIから起動するためのブートローダにはgrubを指定する必要があります。grubは前節で紹介したUEFI対応版にしているので、ESPが正しく設定されていれば自動的にUEFI用のgrubがインストールされます。
図8 UEFI対応版grubのインストール
インストール終了後、再起動するとESPにインストールされたgrub-2.02_28の起動メニューが出て、"Plamo GNU/Linux"を選べばUEFIモードでインストールしたPlamo Linuxが起動します。
図9 ESPにインストールしたgrubの起動メニュー
なお、これらの手順はインストールメディアの"README_GPT.pdf"という文書でも解説しているので、Plamo-6.0をUEFI環境にインストールされる方は、ぜひそちらにも目を通しておいてください。
時間的な制約もあり、Plamo-6.0でのUEFI対応は今回紹介したようにかなり荒削りで、インストール時に別途手作業が必要です。しかし、現在開発中のPlamo-6.1ではこのあたりを改善し、ESP作成もほぼ自動化したので、もっと簡単にUEFI環境にインストールできるようになりました。Plamo-6.1は近日公開の予定なのでご期待ください。