Re: loader.efi of 13.1

From: Tomoaki AOKI <junchoon_at_dec.sakura.ne.jp>
Date: Sun, 11 Sep 2022 01:36:08 UTC
青木@名古屋です。
本文内に適宜コメント挿入します。

On Sun, 11 Sep 2022 07:51:07 +0900
masa@amogha.jp (丸山直昌) wrote:

> 丸山です。
> 
> 「大袈裟な実験」のまとめです。
> 
> UEFIマシンにおいて FreeBSD13.1 の loader.efi がシステムを起動するプロセ
> スを見ると
> 
> (A) loader.efi がデバイスから必要な情報を読み込んで「Welcome to FreeBSD」
>    画面を表示させる
> 
> (B) その後 カーネルをロードしてカーネルに制御を渡す
> 
> の2段階に分けて考えることができます。A段階で必要な情報を読み込むデバイス
> (以下「Aデバイス」と呼びます)とB段階でカーネル等を読み込むデバイス(以下
> 「Bデバイス」と呼びます)は、通常の運用では同じデバイスですが、私は意図的
> に異なるデバイスとなるようにしてみて、挙動を調べてみました。その方法は、
> 「Welcome to FreeBSD」画面でメニューエントリの3番を選んで OK プロンプト
> を表示させ、
> 
>   OK set currdev={Bデバイス}:
>   boot
> 
> とやる方法です。判ったことは
> 
> 1. ディスクからの起動で、ディスク内に freebsd-ufs あるいは freebsd-zfs
>    のパーティションが複数存在する場合にはパーティション番号が一番小さい
>    freebsd-ufs, freebsd-zfs が Aデバイスとして選択される

さらにいうと、ZFS・UFS両方存在する場合、デフォルトでは
ZFSが優先されます。


> 2. loader.efi はA段階においても、B段階においても、 ufs ファイルシステム、
>    zfs ファイルシステムのいずれも読むことができる。(インストールメディア
>    FreeBSD-13.1-RELEASE-amd64-dvd1.isoから起動した場合も考慮すると、 iso
>    ファイルシステムも読めることがわかる。)

loader.efi, boot1.efiとも、「ZFSのプールからloader関連設定・
カーネル・モジュールを読み込むために必要な最低限の機能」を
【デフォルトでは】持っています。

 ※【ビルド時の】オプションで無効化することもできた筈です。

但し、基本的に、loader.efiやboot1.efiに読み込ませるファイルは
ZFS内の「/」と同じデータセット(乃至、Boot Environment [BE])内に
ある必要があります(子のデータセットのマウントまではしません)。

 ※これが、portsやpkgでインストールするものは【デフォルトで】
  /usr/local以下にインストールされる中、*.koだけは例外的に
  /boot/modules以下にインストールされる理由の1つです。



> 3. Bデバイスがzfsの場合、B段階においてロードされたカーネルがBデバイスを
>    ルートシステムとしてマウントできるかどうかは、loader.efi がAデバイス
>    から読み込んだ /boot/loader.conf の中に zfs_load="YES" があるかどうか
>    に依存している。

そういう構造になっています。
デフォルトのGENERICカーネルにはZFSを読み書きする機能は
含まれていません。

 ※【ビルド時の】オプションで組み込むことはできた筈です。

従って、Root on ZFSの場合、カーネルは/etc/rc.*等の起動に
必要なファイル群どころかそれ以前に最初のプロセスとして
起動する/sbin/initすら見つけることができません。
従い、カーネルに制御が渡されるより【前に】zfs.koが組み込まれて
いる必要があるのです。(これをやるのが/boot/loader.confの
zfs_load="YES"です。

翻って、では何故/etc/rc.conf[.local]のzfs_enable="YES"の
設定が存在するかというと、/etc/rc.d/zfsの処理を走らせるか
どうかの設定だからです。 

このスクリプトでZFSのoptionでマウントポイントの指定されている
データセットのマウント等の処理を行うので、これが走ってくれないと、
例えば/usr/localを別データセットに分けていて、起動中にその下の
何かにアクセスする必要が生じた場合に詰みます。

また、シャットダウン時にはこのスクリプトがアンマウント処理を
行います。

また、スクリプト内の「# REQUIRE」で先に何が済んでいないと
いけないかを指定(この場合、zfsbe)されていて、「# BEFORE」で
何の前に処理が済んでいないといけないかが指定されていて、
これらは双方向にきちんと指定されていなくても大丈夫なので、
他に事前に必要になる/etc/rc.d/zpool等のスクリプトも芋蔓式に
処理されます。

 ※このへんをよきに計らうのが/sbin/rcorderです。

ところで、何故デフォルトではZFSが無効かというと、お気づきとは
思いますが、プールの大きさにもよりますが、凄まじくメモリを
喰うからです。 zfs.ko自体カーネルモジュールとしては巨大なので
ZFS不要でメモリ容量の少ない組込用途等では著しく邪魔ですし。


> 以上です。
> 
> --------
> 丸山 直昌 まるやま なおまさ
> メールアドレス: masa@amogha.jp
> 


-- 
青木 知明  [Tomoaki AOKI]    <junchoon@dec.sakura.ne.jp>