[FreeBSD-users-jp 95974] Re: UEFIモードでの起動パーティション切り替え
Naomichi Nonaka
nao @ enuenu.org
2016年 10月 7日 (金) 11:24:59 UTC
野中です。
私の書いた、boot1.efiにパーティション選択機能(下記A)を加える
パッチは放置されたままで何の動きもありません(^^;
gurb2を使う場合はboot1.efiをchainloadして起動する方が手軽に
できますよ。
野中
On 2016/10/07 19:48, 丸山直昌 wrote:
> 統計数理研究所の丸山です。
>
> UEFIブートのマシンの disk(当然 GPTスキーム)に複数のFreeBSDの版を入れて、
> 起動時に切り替えるにはどうしたら良いか。
>
> この問題は以前このMLで話題になったことがありますが、前よりも私の知識が増
> えたので、書いておこうと思います。まあ、ご存知の方も多いかも知れませんが。
>
> 私自身は、最近手持ちの Toshiba dynabookN51というマシンで PC-BSD10.3を
> UEFIブートする方法がわかったので、この問題について色々実験ができるように
> なったわけですが、この記事に書くことは dynabookN51という特定のハードウェ
> アや、PC-BSDに固有のことではなく、UEFIブートできるマシンでFreeBSD一般に
> 通用する内容であると考えています。
>
> まず GPTスキームでの起動時の切り替えに関して、 BIOSブートとUEFIブートで
> どのような違いがあるかを書いておきます。
>
> GPTスキームのBIOSブートの場合、起動パーティションの変更は、私が知る限り
>
> A. ブート時のキー入力による介入
> B. /boot.config による変更
> C. gpart の attribute 属性による変更
>
> の3通りがあります。Aは起動時のインタラクティブな変更で、B, C はディス
> クを少し書き換えておいてから reboot するという、非インタラクティブな変
> 更です。
>
> 以下少し具体的にこの3つを説明しますが、残念ながらFreeBSD10.2, 10.3,
> 11.0 ではこのいずれも UEFIブートでは対応する機能は現在サポートされてい
> ません。
>
> BIOSブートの場合、disk上には type freebsd-boot のパーティションが必要で、
> 仮にここではそのパーティションをada0p1としますと、
>
> gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 ada0
>
> あるいは
>
> gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0
>
> としておく必要があります。前者が UFS用、後者は zfs 用です。
>
> A. ブート時のキー入力による介入
>
> は、man gptbootや man gptzfsboot には書いてありませんが、起動の初期の
> 段階で何かRETURN以外のキーを押すと、UFSの場合は
>
> FreeBSD/x86 boot
> Default: 0:ad(0p3)/boot/loader
> boot:
>
> zfsの場合は
>
> FreeBSD/x86 boot
> Default: tank/ROOT/initial:/boot/zfsloader
> boot:
>
> のような表示が現れて一旦ブートプロセスは停止し、別のパーティション、あ
> るいは zfs pool上のloader を指定すると、そのパーティションから起動する
> ことができます。この「起動時のキー入力による変更」は、/boot/menu.rc に
> よるメニューが表示されてからでは間に合いません。
>
> 次に「B. /boot.config による変更」ですが、私は UFSの場合しか試していな
> いのですが、起動されるパーティションが ada0p3の場合であれば、このパー
> ティションのトップのディレクトリのboot.config というファイルに
>
> 0:ad(0p5)/boot/loader
>
> と書いておくと、ada0p5 にある /boot/loader が起動される、という仕組み
> です。この方法でも、Aの「ブート時のキー入力による介入」でも、書き方は
> "ada"ではなく、"ad" です。
>
> 最後の「C. gpart の attribute 属性による変更」は、
>
> gpart set -a bootme -i 5 ada0
>
> として、起動パーティションの「印」を GPTスキームのパーティション情報に
> 書き込んでおく方法です。これで ada0p5 から起動されます。これは man
> gpart に書いてあり、UFSでもzfsでも確かに働きます。
>
> 以上 A,B,C はBIOSブートの場合の話ででしたが、以下UEFIブートの場合を書
> きます。
>
> UEFIボートではディスク上に type efi のパーティションが必要で、それは
> MSDOSのFAT16にフォーマットされ、適切な BOOTX64.EFIというファイルと、起
> 動構成データが書かれている(Windowsであれば bcdeditコマンドで書き込む)
> 必要がありますが、その詳細は
>
> http://d.hatena.ne.jp/msll/20150527/1432708323
> http://qiita.com/takawata19/items/3d1fb96cfde4f1626e3c
> 及び、 dynabookN51に関しては、私が書いた
> [FreeBSD-users-jp 95970] Date: Tue, 20 Sep 2016 11:17:43 +0900
>
> に譲り、ここでは BOOTX64.EFI としては、 FreeBSDの場合には
> /boot/boot1.efiを使う必要がある、という事に留めておきます。
>
> さて BIOSブートの場合には
>
> A. ブート時のキー入力による介入
> B. /boot.config による変更
> C. gpart の attribute 属性による変更
>
> の3つの方法で起動パーティションを切り替えることができましたが、実験し
> たところ、UEFIブートではすべて駄目でした。BIOSブートの場合A, B, Cは
> type freebsd-boot のパーティションに書き込む /boot/gptboot あるいは
> /boot/gptzfsboot によって実現されていると思われますが、 UEFIブートの場
> 合には、type efi のパーティションの BOOTX64.EFI にコピーされる
> /boot/boot1.efi がそのような機能を実装していないということでしょう。こ
> れは 10.2, 10.3, 11.0 いずれの /boot/boot1.efi を使ってみても駄目でし
> た。(BとCは、それぞれman boot.config, man gpart に書いてあるのに、それ
> は反則だろう、と言いたくなりますが。)
>
> 残る手段(最後の手段)は gnu-grubです。正確には grub2 ですが、BIOSブート
> の場合には
>
> insmod ufs2
> insmod bsd
> set root=(hd0,5)
> kfreebsd /boot/loader
> set kFreeBSD.vfs.root.mountfrom=ufs:/dev/ada0p5
> set kFreeBSD.vfs.root.mountfrom.options=rw
>
> という簡単なメニューエントリでUFSのパーティションから起動できます(zfs
> は試していませんが、多分同じようにできると思います)。grub2のインストー
> ル、設定などはここでは解説しませんが、仕組みを簡単に説明しておくと、
> grub-install, grub-mkconfig を使って正しくインストール、設定が行われて
> いれば、電源投入後
>
> diskのsector0 にある stage0 boot loader
> -> type bios-boot のパーティションにある grub2
>
> という順で起動され、その後は grub2 の文法に従って起動が進みますが、上
> のようなメニューエントリが選ばれた場合には、
>
> -> /dev/ada0p5 の /boot/loader
> -> /boot/kernel/kernel
>
> という順でFreeBSDが起動されます。なおこの流れの中では A, B, Cの変更方
> 法は機能しません。なぜかと言うと、A, B, Cの変更方法は type
> freebsd-bootのパーティションにコピーされた /boot/gptboot や
> /boot/gptzfsbootの機能であって、/boot/loader に制御が移った時点では最
> 早手遅れだからです。
>
> 以上の話はUEFIブートの場合の grub2 ではどうなるかと言いますと、
>
> (UEFIファームウェアが) type efi のパーティションにある BOOTX64.EFIを起動
> -> type bios-boot のパーティションにコピーされた grub2が起動
>
> となって、以後は grub2の文法に従いますが、ここで上と全く同じメニューエ
> ントリを選択しても起動できません!
>
> これには当初私は途方に暮れました。理由がわかるのに少し時間がかかったの
> ですが、答えは
>
> https://www.gnu.org/software/grub/manual/grub.html#Supported-kernels
>
> にありました、これを見ると
>
> BIOS Coreboot
> BIOS chainloading yes no (1)
> NTLDR yes no (1)
> Plan9 yes no (1)
> Freedos yes no (1)
> FreeBSD bootloader yes crashes (1)
> 32-bit kFreeBSD yes crashes (2,6)
> 64-bit kFreeBSD yes crashes (2,6)
> (途中略)
> ia32 EFI amd64 EFI
> BIOS chainloading no (1) no (1)
> NTLDR no (1) no (1)
> Plan9 no (1) no (1)
> FreeDOS no (1) no (1)
> FreeBSD bootloader crashes (1) crashes (1)
> 32-bit kFreeBSD headless headless
> 64-bit kFreeBSD headless headless
>
> と言う部分があります。この "FreeBSD bootloader" というのは/boot/loader
> ですので、 BIOSブートでは"yes", つまりポートされていますが、 amd64 EFI
> ではcrashする、というわけです。
>
> ではこれで絶望かと言うと、そうではなく、最後の行の
>
> 64-bit kFreeBSD headless headless
>
> に救いがあります。ここで headless というのは
>
> "headless" means that the kernel works but lacks console drivers (you
> can still use serial or network console).
>
> だそうで、これを使うと
>
> insmod ufs2
> insmod bsd
> set root=(hd0,5)
> set kFreeBSD.vfs.root.mountfrom=ufs:/dev/ada0p5
> set kFreeBSD.vfs.root.mountfrom.options=rw
> kfreebsd /boot/kernel/kernel
>
> というメニューエントリで、 /boot/loader を経ずに直接
> /boot/kernel/kernelを起動することはできます。ですがこれだと通常
> /boot/loader がやってくれていた作業(/boot/loader.conf を読み込んで
> kernel module をload しておくとか、カーネル環境変数を設定しておく)が全
> 部飛ばされるので、実際にはOSは満足な動作をしません。その飛ばされる作業
> を grub2 自身にやらせるために少し長いメニューエントリを書く必要があり
> ます。例えば以下のようになります。
>
> insmod ufs2
> insmod bsd
> set root=(hd0,5)
> set kFreeBSD.vfs.root.mountfrom=ufs:/dev/ada0p5
> set kFreeBSD.vfs.root.mountfrom.options=rw
> kfreebsd /boot/kernel/kernel
> kfreebsd_loadenv /boot/device.hints
> kfreebsd_module_elf /boot/modules/nvidia.ko
> kfreebsd_module_elf /boot/kernel/drm.ko
> kfreebsd_module_elf /boot/kernel/drm2.ko
> kfreebsd_module_elf /boot/kernel/iicbus.ko
> kfreebsd_module_elf /boot/modules/vboxdrv.ko
> kfreebsd_module_elf /boot/kernel/crypto.ko
> kfreebsd_module_elf /boot/kernel/aesni.ko
> kfreebsd_module_elf /boot/kernel/geom_eli.ko
> kfreebsd_module_elf /boot/kernel/zfs.ko
> kfreebsd_module_elf /boot/kernel/opensolaris.ko
> kfreebsd_module_elf /boot/kernel/tmpfs.ko
> kfreebsd_module_elf /boot/kernel/linux.ko
> kfreebsd_module_elf /boot/kernel/linux_common.ko
> kfreebsd_module_elf /boot/kernel/geom_journal.ko
> kfreebsd_module_elf /boot/kernel/geom_mirror.ko
> kfreebsd_module_elf /boot/kernel/ums.ko
> set kFreeBSD.bootfile="kernel"
> set kFreeBSD.kernel="kernel"
> set kFreeBSD.kernel_options=""
> set kFreeBSD.kernelname="/boot/kernel/kernel"
> set kFreeBSD.module_path="/boot/kernel;/boot/modules"
> set kFreeBSD.kern.ipc.shmseg="1024"
> set kFreeBSD.kern.ipc.shmmni="1024"
> set kFreeBSD.kern.maxproc="10000"
> set kFreeBSD.legal.intel_ipw.license_ack="1"
> set kFreeBSD.legal.intel_iwi.license_ack="1"
> set kFreeBSD.legal.realtek.license_ack="1"
> set kFreeBSD.hint.acpi_throttle.0.disabled="1"
> set kFreeBSD.machdep.disable_mtrrs="1"
> set kFreeBSD.kern.geom.eli.visible_passphrase="2"
> set kFreeBSD.kern.cam.scsi_delay="500"
> set kFreeBSD.hw.memtest.tests="0"
> set kFreeBSD.kern.vty="vt"
> set kFreeBSD.kern.geom.label.gptid.enable="0"
> set kFreeBSD.kern.geom.label.disk_ident.enable="0"
> set kFreeBSD.kern.geom.label.ufsid.enable="0"
> set kFreeBSD.hw.pci.do_power_nodriver="3"
> set kFreeBSD.net.inet.ip.fw.default_to_accept="1"
> set kFreeBSD.net.inet.ip.fw.one_pass="0"
> set kFreeBSD.net.graph.maxdata="65536"
> set kFreeBSD.grub.platform="$grub_platform"
> set kFreeBSD.kern.geom.eli.passphrase="$pass"
>
> 以上はUFSの場合ですが、zfs なら
>
> insmod zfs
> search --no-floppy -s -l tank
> kfreebsd /ROOT/initial/@/boot/kernel/kernel
> kfreebsd_loadenv /ROOT/initial@/boot/device.hints
> kfreebsd_module /ROOT/initial/@/boot/zfs/zpool.cache type=/boot/zfs/zpool.cache
> set kFreeBSD.vfs.root.mountfrom=zfs:tank/ROOT/initial
> kfreebsd_module_elf /ROOT/initial/@/boot/modules/nvidia.ko
> kfreebsd_module_elf /ROOT/initial/@/boot/kernel/drm.ko
> kfreebsd_module_elf /ROOT/initial/@/boot/kernel/drm2.ko
> (以下略)
>
> という調子です。
>
> 以上で、私がこの記事で書きたかったことはほぼ終わりましたが、最後に少し
> grub2 のインストールに関係することを書いておきます。
>
> UEFI のマシンに元祖FreeBSD10.3をインストールすることは、私は経験がない
> のですが、どなたかの記事ではちゃんと起動できるようにインストールされる
> と書いてありました。起動した状態で、 grub2 を pkg add し、grub-install
> と grub-mkconfig をやればtype efiのパーティションにかかれた
> BOOTX64.EFI (このファイル名が case sensitive なのかどうか私は知りませ
> ん)が grub 用のものに書き換わり、grub のメニューが作成されて、rebootす
> れば、 grub 経由で 10.3が立ち上がるようになるのでしょう(実験してなく
> て申し訳ない、無保証です)。この時どのような初期メニューが作成されるの
> か私は知りませんが、ともかくメニューは /boot/grub/grub.cfg と
> /boot/grub/custom.cfgを見ればわかります。そして、/boot/grub/custom.cfg
> を手動で直すか、あるいは /usr/local/etc/grub.d の下にあるファイルを手
> 動で直してgrub-mkconfig をやり直せば、メニューを思い通りに作り直すこと
> は可能であるはずです(詳しくは grub2 の info に書いてあるのでしょう)。
> この時、上に書いた事を参考にしてください。
>
> PC-BSD10.3について書きますと、標準のインストールでは、grub2 が既定のブー
> トローダーとしてインストールされ、インストールしたzfs を起動するメニュー
> が初期状態として作られます。私は /boot/grub/custom.cfgや
> /usr/local/etc/grub.d の下のファイルをいじくって、複数のパーティション
> の切り替えを実現しています。
>
> 以前は「一個のディスクに複数の zfs(プール名は違える)を作り、ぞれぞれシ
> ステムをインストールをすると、grub のメニューが面倒」と思い込んでいた
> のですが、どうも grub-mkconfig はその点も「何とかしてくれる」らしいと
> 最近気が付きました。ただこれがgrub2 に元々備わった機能なのか、あるいは
> grub2 に加えて PC-BSD固有の設定が関係しているのか、調べきれていません。
>
> --------
> 丸山直昌@統計数理研究所
> _______________________________________________
> freebsd-users-jp @ freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-users-jp
> To unsubscribe, send any mail to "freebsd-users-jp-unsubscribe @ freebsd.org"
>
freebsd-users-jp メーリングリストの案内