玩式草子─ソフトウェアとたわむれる日々

第78回Plamo LinuxのGPT/UEFI対応その2]

前回最近のマザーボードが採用している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
図1 GPT HDD上のESP

UEFIは接続されたHDD上にESPがあるかを調べ、ESPが見つかればそのパーティション上の\EFI\BOOT\ディレクトリ以下にあるブートローダを探します。UEFI用のブートローダは、.EFIという拡張子を持つ、PE形式のバイナリファイルです。

UEFIの仕様では、x86_64環境の場合は\EFI\BOOT\BOOTX64.EFI32ビットの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メニュー画面
図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-installgrub-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を有効化」オプション
図3 「EFIを有効化」オプション

次にPlamo-6.0のDVDイメージを「仮想光学ディスクファイル」としてCDドライブに指定して起動します。EFIを有効化して起動すればGNU GRUBのブートメニューが表示され、4種類の起動方法が選択できます。たいていの場合、"Plamo Linux install on VirtualBox"を選べば起動するものの、VirtualBoxのドライブ設定(IDEに接続するかSATAに接続するか、等)によって認識されるデバイスの順番が変るので、うまく起動しない場合は別の項目を試してください。

図4 UEFI DVDから起動したメニュー
図4 UEFI DVDから起動したメニュー

インストールの流れは以前のバージョンと同じものの、HDDをフォーマットする際にラベル(パーティションテーブルの種類)としてGPTを指定し、ブートローダ用のESPを独立したパーティションとして作成する必要があります。

図5 新規HDDのパーティションテーブルをGPT形式に指定
図5 新規HDDのパーティションテーブルをGPT形式に指定

今回は8GBのHDDの先頭の128MBをESP用にすることにしました。ESPにするにはパーティションタイプを変更する必要があるのを忘れないでください。

図6 cfdiskで必要なパーティションを作成
図6 cfdiskで必要なパーティションを作成

上述のように、ESPはFAT32形式でフォーマットされる必要があるものの、Plamo-6.0のインストーラにはESPを自動フォーマットする機能は入れていないので、ESPは手動でフォーマットする必要があります。具体的には、パッケージのインストールを進めている途中にでも、ALT+F2でコンソールを切り替えてログインし、mkfs.vfatコマンドを実行します。オプションには-F32(FAT32の指定)と-s2(1クラスタあたり2セクタ)を指定すればいいでしょう。

図7 別コンソールからESPを手動でフォーマット
図7 別コンソールからESPを手動でフォーマット

UEFIから起動するためのブートローダにはgrubを指定する必要があります。grubは前節で紹介したUEFI対応版にしているので、ESPが正しく設定されていれば自動的にUEFI用のgrubがインストールされます。

図8 UEFI対応版grubのインストール
図8 UEFI対応版grubのインストール

インストール終了後、再起動するとESPにインストールされたgrub-2.02_28の起動メニューが出て、"Plamo GNU/Linux"を選べばUEFIモードでインストールしたPlamo Linuxが起動します。

図9 ESPにインストールしたgrubの起動メニュー
図9 ESPにインストールしたgrubの起動メニュー

なお、これらの手順はインストールメディアの"README_GPT.pdf"という文書でも解説しているので、Plamo-6.0をUEFI環境にインストールされる方は、ぜひそちらにも目を通しておいてください。


時間的な制約もあり、Plamo-6.0でのUEFI対応は今回紹介したようにかなり荒削りで、インストール時に別途手作業が必要です。しかし、現在開発中のPlamo-6.1ではこのあたりを改善し、ESP作成もほぼ自動化したので、もっと簡単にUEFI環境にインストールできるようになりました。Plamo-6.1は近日公開の予定なのでご期待ください。

おすすめ記事

記事・ニュース一覧