UEFI環境下でのgrubでLinuxとWindows 10をデュアルブートする
Windowsでのブートの制約
Dual boot with Windows - ArchWiki
上記より、Windows 10ではUEFI-GPTあるいはBIOS-MBRの組合せでしかブート出来ません。ところで旧来のBIOSブートに比べてUEFIブートは高速であることが知られています。またMBRに比べてGPTでは基本パーティション数の制限が緩和されているというように、UEFI-GPTブートがモダンなブート環境であることは間違いないでしょう。特にWindows 10をクリーンインストールするとき、デフォルトでパーティションを切ろうとするとEFI System Partition (ESP) を作る挙動がみられるように、UEFI-GPTでのブートを推奨しているようです。
ここでは、もともとLinuxを起動する際に用いていた従来のBIOS-MBR型で定義されていたgrubのブートをUEFIブートにリフトし、Windows 10とのデュアルブート環境を構築することを目論みます。grubは2.02 rc2
を用いました。
予めWindows 10の高速スタートアップ機能は無効にしておきましょう。
grub2の仕様
デュアルブート対象のLinux上で作業します。まずは既存のgrubから、UEFIのWindowsをチェインして呼び出すことを考えます。そのためにはUEFIのWindowsを認識させなければなりません。しかしos-prober
を行っても、Windows Boot Managerを発見できません。そこでwikiを参照して/etc/grub.d/40_custom
に書き込んで、grub-mkconfig
しました。
# grub-mkconfig -o /boot/grub/grub.cfg
こうしてgrubのエントリを追加すればもうWindows 10を起動できるようになったのかというとそうではなく、grubのメニューから追加したエントリを選択するとInvalid signature
と言って怒られます。これはBIOS型のgrubからUEFIのブートローダーをチェインして起動することが出来ないためであると考えられます。
後で試してわかるのですが、LinuxをBIOSブートで起動している場合はUEFIブートのOSを検出してくれませんが、UEFIブートで起動した場合はos-prober
でWindows Boot Managerを検出でき、systemd-bootやrEFIndと同様にgrub-mkconfig
で自動でUEFIのWindowsを探してくれます。そこで上記の手順を省略し、下記の方法でUEFIブートによって起動してからgrub-mkconfig
を行えば、手動でWindowsのエントリを追加する必要はないと考えられます。
そこで次に、UEFIモードでgrubをインストールすることを考えます。UEFIの大きな特徴として、一つのESP内に複数のブートローダーを共存させることができます。
ここでは既存のMBRブートのパーティションを残し、Windows 10インストール時に生成したESPにWindows Boot Managerと共存させる形でgrubをインストールすることにしました。/dev/sda1
がESPであったとします。
# mount /dev/sda1 /mnt # grub-install --target=x86_64-efi --efi-directory=/mnt --bootloader-id=grub
としたいのですが、このコマンドを実行するとUEFI経由で起動しろと怒られます。
efibootmgr: EFI variables are not supported on this system.
この状況でUEFIブートを行ったとしても、このgrubは起動できません。ブートエントリにgrubが追記されていないためです。しかしUEFIのブートエントリに追加しようにも、内部的にはefibootmgr
を用いているようですが、従来のBIOSブートで起動したlinux側からはそれを編集することができません。UEFIシェル上でbcfg
コマンドでブートローダーを追記してもよいのですが、失敗するのが怖いのでgrub
の機能を用いて自動でやってもらいたいと思います。そのためにはUEFI経由で起動する必要があります。
UEFIシェルを触る
先述の理由からUEFI経由で起動したいのですが、BIOSからUEFIの設定を変えてgrubから起動しようとしても、今grub-installしたブートローダーはエントリには表示されないので、UEFIシェルを叩いて直接起動するしかありません。BIOSのブートオプションでUEFI shellを選択します。このシェル画面で先ほどgrub-install
したefiファイルを実行します。
> fs1: > cd EFI > cd grub > grubx64.efi
こうしてから起動すると、grubのブート画面が立ち上がります。この画面でLinuxを選択するとEFI経由で起動したことになるので、再びgrub-install
することでファームウェアのブートエントリにgrubを追記することができます。こうすると、再起動した時にUEFI経由でgrubの画面が表示され、Windows 10を選択するとgrub経由で起動できるようになります。
以上のようにして、grubによるWindows 10とLinuxのマルチブートを行いました。ただしこの場合、BIOSブートでインストールされたWindows 7などを今までのgrub経由でブートしていた場合は、UEFI経由のgrubからでは起動できなくなります。