From owner-freebsd-users-jp@freebsd.org Fri Oct 7 10:53:16 2016 Return-Path: Delivered-To: freebsd-users-jp@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E1CDEC026EE for ; Fri, 7 Oct 2016 10:53:16 +0000 (UTC) (envelope-from maruyama@ism.ac.jp) Received: from amogha.ism.ac.jp (amogha.ism.ac.jp [133.58.120.10]) by mx1.freebsd.org (Postfix) with ESMTP id 596D2201 for ; Fri, 7 Oct 2016 10:53:16 +0000 (UTC) (envelope-from maruyama@ism.ac.jp) Received: from samanta.ism.ac.jp (amogha.ism.ac.jp [133.58.120.10]) by amogha.ism.ac.jp (8.14.5/8.14.5) with ESMTP id u97Ap1bt096450; Fri, 7 Oct 2016 19:51:01 +0900 (JST) (envelope-from maruyama@ism.ac.jp) Received: (from maruyama@localhost) by samanta.ism.ac.jp (8.15.2/8.15.2/Submit) id u97AmSoG009260; Fri, 7 Oct 2016 19:48:28 +0900 (JST) (envelope-from maruyama@ism.ac.jp) X-Authentication-Warning: samanta.ism.ac.jp: maruyama set sender to maruyama@ism.ac.jp using -f From: maruyama@ism.ac.jp (=?iso-2022-jp?B?GyRCNF07M0Q+PjsbKEI=?=) To: freebsd-users-jp@freebsd.org Organization: =?iso-2022-jp?B?GyRCRX03Vz90TX04JjVmPWobKEI=?= Reply-To: maruyama@ism.ac.jp Date: Fri, 07 Oct 2016 19:48:28 +0900 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=iso-2022-jp Subject: [FreeBSD-users-jp 95973] =?iso-2022-jp?b?VUVGSRskQiViITwlSSRHJE41L0YwJVEhPCVGJSMlNyVnGyhC?= =?iso-2022-jp?b?GyRCJXNAWiRqQlgkKBsoQg==?= X-BeenThere: freebsd-users-jp@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Discussion relevant to FreeBSD communities in Japan List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 07 Oct 2016 10:53:17 -0000 統計数理研究所の丸山です。 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固有の設定が関係しているのか、調べきれていません。 -------- 丸山直昌@統計数理研究所