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

第79回 Plamo LinuxのGPT/UEFI対応[その3]

この記事を読むのに必要な時間:およそ 5.5 分

前回はUEFIがGPT形式のHDDからOSを起動する仕組みを解説し,Plamo Linux 6.0をGPT形式のHDDにインストールする手順を紹介しました。前回は省略したものの,UEFI環境にインストールするにはもう一つ越えなければならない壁があります。それはUEFIにインストールするにはUEFIから起動しなければいけないという条件です。

従来のSystem BIOSではHDDの起動順序等の設定はBIOSのメニュー画面からしか操作できなかったのに対し,UEFIではさまざまな設定をOSから操作する機能が提供され,起動順序等をより柔軟に設定できるようになりました。

一方,この機能を使うにはOSがUEFIモードで起動している必要があります。たとえばLinuxの場合,UEFIの設定はefivarfsという専用のファイルシステム経由で利用するようになっており,このファイルシステムはカーネルがUEFIモードで起動しないと有効になりません。

すなわち,GPT/UEFI環境にインストールするにはインストーラをGPT/UEFI対応にするだけではなく,インストーラ自身をUEFIから起動する必要があるわけで,そのための方法をあれこれ調べることになりました。

USBメモリからUEFI起動

前回紹介したように,UEFIはHDDからOSを起動する場合,専用のパーティションIDを持ったFAT32形式のEFIシステムパーティション(ESP)にあるブートローダを調べます。一方,USBメモリのように通常は一つのパーティションしか持たないリムーバブルメディアから起動する場合,ESPとは関係なくメディアのルートディレクトリにある\EFI\BOOT\ディレクトリを探します。このディレクトリに置くブートローダは,x86_64アーキテクチャの場合BOOTX64.EFI32ビットのx86アーキテクチャの場合はBOOTIA32.EFIという名前にすることになっています。

前回紹介したように,--with-platform=efiオプションを指定してビルドすればUEFI用のgrubはビルドできるものの,この状態のgrubは機能が細かく分割されたモジュール群でしかありません。

$ ls -l /usr/lib64/grub/x86_64-efi/
合計 20,307,968
-rw-r--r-- 1 root root    16,432 10月 30日  17:11 acpi.mod
-rwxr-xr-x 1 root root   102,088 10月 30日  17:11 acpi.module*
-rw-r--r-- 1 root root     1,928 10月 30日  17:11 adler32.mod
-rwxr-xr-x 1 root root    13,328 10月 30日  17:11 adler32.module*
-rw-r--r-- 1 root root     8,272 10月 30日  17:11 affs.mod
-rwxr-xr-x 1 root root    48,344 10月 30日  17:11 affs.module*
-rw-r--r-- 1 root root     9,016 10月 30日  17:11 afs.mod
-rwxr-xr-x 1 root root    57,488 10月 30日  17:11 afs.module*
...

grubがブートローダとして機能するためには,これらモジュールのうち必要なものをgrubコアに組み込む必要があります。grub-installコマンドを使ってインストールする場合,grub-mkconfigコマンドが自動的に起動され,インストールする環境に応じたモジュールを組み込むための設定ファイルgrub.cfgを生成してくれます。

骨組みだけしかないgrubコアにgrub.cfgで必要なモジュールを組み込むという仕組みは,さまざまな環境に柔軟かつ効率的に対応できる利点はあるものの,どのような環境で使われるかが事前には分からないインストーラでは使えません。

そのような場合のために用意されているのがgrub-mkimageコマンドです。このコマンドは,指定したモジュールをgrubコアに組み込んで,モジュールを追加ロードしなくても動作するバイナリファイルを生成します。

$ 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
  -d, --directory=DIR        use images and modules under DIR
                             [default=/usr/lib64/grub/<platform>]
  -k, --pubkey=FILE          embed FILE as public key for signature checking
  -m,                              --memdisk=FILE         embed FILE as a memdisk image
Implies `-p (memdisk)/boot/grub' and overrides
                             any prefix supplied previously, but the prefix
                             itself can be overridden by later options
  -n, --note                 add NOTE segment for CHRP IEEE1275
  -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,
  ...

grubには250近いモジュールが用意されており,どのモジュールを組み込むかを考えるのも一苦労なものの,今回はUSBメモリと後述するDVDからの起動に限定して以下のようなモジュールを組み込むことにしました。

$ grub-mkimage -v -p '' -o bootx64.efi -O x86_64-efi fat part_msdos iso9660 gzio \
      all_video gfxterm font terminal normal linux echo test search configfile cpuid minicmd
grub-mkimage: 情報: the total module size is 0x6ffb8.
grub-mkimage: 情報: reading /usr/lib64/grub/x86_64-efi/kernel.img.
grub-mkimage: 情報: locating the section .text at 0x0.
grub-mkimage: 情報: locating the section .rodata at 0x9600.
grub-mkimage: 情報: locating the section .rodata.str1.1 at 0x9798.
...
grub-mkimage: 情報: kernel_img=0x7fcad3119010, kernel_size=0x18200.
grub-mkimage: 情報: the core size is 0x881b8.
grub-mkimage: 情報: writing 0x89400 bytes.

今回組み込んだモジュールは,FATファイルシステム用のfatDOSパーティション用のpart_msdosCD/DVD用のiso9660圧縮ファイル用のgzio各種ビデオカードに対応するためのall_videoグラフィカルターミナル用のgfxtermフォント回りを扱うfontターミナル表示用のterminal通常モード用のnormalカーネルをロードするためのlinuxスクリプト中で各機能を有効にするechotest指定されたファイルシステムを探すsearch設定ファイルを操作するconfigfileCPUの種類を調べるcpuid最低限のコマンドを実装するminicmdということになります。

-p ''は起動時に必要なファイルを探すディレクトリを変更するための指定で,EFI版のgrubでは -p '' と指定すると/EFI/BOOT/以下にある設定ファイルを読みこむことになります。この指定をしないとデフォルトである/boot/grub/以下を探します。

grub-mkimageはgrubコアにこれらのモジュールを組み込み,バイナリ形式もPE32+に変更してEFIアプリケーションを生成します。

$ ls -lh bootx64.efi 
-rw-r--r-- 1 kojima users 549K  2月 23日  23:12 bootx64.efi
$ file bootx64.efi 
bootx64.efi: PE32+ executable (EFI application) x86-64 (stripped to external PDB), for MS Windows

次に,grub.cfgでこのgrubから読み込むカーネルとinitrd.gzを指定します。initrd.gzにはインストーラを動かすための小規模なLinux環境が入っています。Plamo Linuxのインストールメディアではカーネルとinitrd.gzはisolinuxディレクトリに置いているので,USBメモリから起動するための最小限の設定はこうなりました。

1:  menuentry "UEFI Plamo Linux install from USB memory" {
2:    linux (hd0)/isolinux/vmlinuz root=/dev/ram0 rw nomodeset vga16 unicon=eucjp vt.default_utf8=0 kbd=usbkbd
3:    initrd (hd0)/isolinux/initrd.gz
4:  }

2行目が読み込むカーネルと起動時のオプションの指定,3行目がinitrd.gzの指定です。なお,この設定はパーテイションを切らずにフォーマットしたUSBメモリの例で,パーティションを切ってフォーマットしたUSBメモリでは(hd0)の部分が(hd0,msdos1)のようになります。

こうして作成したbootx64.efiとgrub.cfgをUSBメモリの\EFI\BOOTディレクトリに,カーネルとinitrd.gzを\isolinuxディレクトリに置けば,UEFIはUSBメモリをUEFI対応メディアとして認識し,そこから起動できるようになりました。

図1 UEFIが起動メディアとして認識したUSBメモリ

図1 UEFIが起動メディアとして認識したUSBメモリ

著者プロフィール

こじまみつひろ

Plamo Linuxとりまとめ役。もともとは人類学的にハッカー文化を研究しようとしていたものの,いつの間にかミイラ取りがミイラになってOSSの世界にどっぷりと漬かってしまいました。最近は田舎に隠棲して半農半自営な生活をしながらソフトウェアと戯れています。

URLhttp://www.linet.gr.jp/~kojima/Plamo/index.html

コメント

コメントの記入