LOADER(8)

名称
loader - カーネルブートストラップの最終段階

解説
loader と呼ばれるプログラムは、 FreeBSD のカーネルブートストラップにおける、最終段です。 IA32 (i386) アーキテクチャでは、これは BTX クライアントです。 libstand(3) に静的にリンクされ、通常はディレクトリ /boot に置かれます。

また、作業自動化、事前設定、回復処理の補助に使用可能な、 スクリプト言語を提供します。 このスクリプト言語はおおまかに 2 つの主たる部分に分類されます。 小さな方は、通常のユーザが直接使用するようデザインされたコマンドの集合で、 歴史的な事情により「組み込みコマンド」と呼ばれます。 これらのコマンドを提供した背景には、 主としてユーザの使い勝手を改善する目的があります。 大きな部品は ANS Forth 互換の Forth インタプリタであり、 John Sadler の ficl をベースにしています。

初期化において、 loader はコンソールを検出して console 変数を設定します。 直前のブートステージにシリアルコンソールを使用した場合には、 この変数をシリアルコンソール (“comconsole”) に設定します。 その後、デバイスをプローブし、 currdev と loaddev を設定し、 LINES を 24 に設定します。 次に FICL が初期化され、組み込み語が語彙に追加され、存在する場合には /boot/boot.4th が処理されます。 このファイルが読み込まれるまで、ディスクの交換はできません。 loader が FICL とともに使用する内部インタプリタは interpret に設定されます。これは FICL のデフォルトです。 この後、使用可能な場合 /boot/loader.rc が処理され、そうでない場合には歴史的な理由で /boot/boot.conf が読み込まれます。 これらのファイルは include コマンドを介して処理されます。 このコマンドは、 処理前にファイル内容すべてをメモリに読み込みますので、 ディスク交換が可能となります。

この時点で、 autoboot が試されていない場合でかつ autoboot_delay が “NO” (大文字小文字は区別しません) に設定されていない場合、 autoboot が試されます。 システムがこの時点まで到達した場合、 prompt が設定され、 loader は対話モードになります。

組み込みコマンド
loader の組み込みコマンドは、パラメータをコマンドラインから受け取ります。 現在、スクリプトからの呼び出し方法は、文字列上で evaluate を使用することだけです。 エラー状態が発生すると、 ANS Forth 例外操作語でインタセプト可能な例外が生成されます。 インタセプトされない場合、エラーメッセージが表示され、 インタプリタの状態がリセットされます。 これにより、スタックが空になりインタプリタのモードが元に戻ります。

使用可能な組み込みコマンドは次の通りです:

acpi_load
    ACPI モジュールの自動ロードを無効にするには、これをアンセットします。 device.hints(5) の hint.acpi.0.disabled も参照してください。
autoboot [seconds]
    ユーザが割り込まない場合には、 指定した秒数の後にシステムのブートストラップへ進みます。 キーが押されて割り込まれるまで、 カウントダウンプロンプトを表示し、 ユーザに対してシステムがブートするところであることを警告します。 必要であれば、最初にカーネルがロードされます。 デフォルトは 10 秒です。

bcachestat
    ディスクキャッシュの使用状況を表示します。 デバッグのためだけにあります。

boot
boot kernelname [...]
boot -flag ...
    システムのブートストラップへすぐに進み、 必要であればカーネルをロードします。 すべてのフラグまたは引数はカーネルに渡されますが、 カーネル名が指定された場合、これらはカーネル名の後にある必要があります。

    警告: この組み込みコマンドの動作は、 loader.4th(8) がロードされると、変ります

echo
    [-n] [<message>] 画面にテキストを表示します。 -n を指定しない場合、改行が表示されます。

heap
    メモリ使用状況が表示されます。デバッグ目的のためだけにあります。

help [topic [subtopic]]
    ヘルプメッセージを /boot/loader.help から読み込んで表示します。 特殊トピック index は、使用可能なトピックを表示します。

include file [file ...]
    スクリプトファイルを処理します。 各ファイルは、順番がまわって来たところで完全にメモリに読み込まれ、 各行がコマンドラインインタプリタに渡されます。 インタプリタがエラーを返すと、 他のファイルは読み込まずに include コマンドは即時に異常終了し、 自身にエラーを返します ( エラー 参照)。

load
    [-t type] file ... カーネル、カーネルローダブルモジュール (kld)、内容を問わず type とタグ付けされているファイルのいずれかをロードします。 カーネルとモジュールは、a.out または FLF のどちらの形式であってもかまいません。 ロードされるファイルの後で渡される引数は、 そのファイルに対する引数として渡されます。 現在のところ、これはカーネルに対しては動作しないことに注意してください。

ls  [-l] [path] ディレクトリ path 、または path を指定しなかった場合にはルートディレクトリのファイル一覧を表示します。 -l を指定すると、ファイルの大きさも表示します。

lsdev [-v]
    モジュールのロード元となりうるデバイスをすべて表示します。 -v を指定すると、更なる詳細を表示します。

lsmod [-v]
    ロード済のモジュールを表示します。 -v を指定すると、更なる詳細を表示します。

more file [file ...]
    LINES 行を表示するごとに停止しながら、指定したファイルを表示します。

pnpscan [-v]
    プラグアンドプレイデバイスをスキャンします。 現在のところ動作しません。

read
    [-t seconds] [-p prompt] [variable] 入力行を端末から読み込み、 variable が指定された場合にはこれに読み込み結果を格納します。 タイムアウトは -t で指定可能ですが、これは最初に押されるキーにより打ち消されます。 プロンプトもまた -p フラグにより表示可能です。

reboot
    即時にシステムをリブートします。

set variable
set variable=value
    ローダの環境変数を設定します。

show [variable]
    指定した変数の値を表示します。 variable を指定しないと、すべての変数とその値を表示します。

unload
    全モジュールをメモリから取り除きます。

unset variable
    variable を環境から取り除きます。

?   “help index” と同じです。

  組み込みの環境変数
loader は実際のところ、異なった 2 種類の ‘環境’ 変数を持ちます。 それは、ANS Forth の 環境問い合わせ と、別の空間であり組み込みコマンドが使用する環境変数です。 後者は Forth の語としては直接使用できません。 この節で説明するのは、後者です。

環境変数の設定および設定解除は、 set と unset の組み込みコマンドを介して行います。これらの値は、 show 組み込みコマンドを使用して対話的に検査できます。 これらの値は、 組み込みパーザ で説明する方法でもまたアクセス可能です。

この環境変数は、システムブート後にシェルに継承されないことに注意してください。

数個の変数が loader により自動的に設定されます。 他の変数は、 loader またはブート時のカーネル動作に影響し得ます。 これらのうち値を要求するものがある一方、 設定されるだけで動作を定義するものもあります。 双方の組み込み変数が下記に説明されています。

autoboot_delay
    autoboot がブート前に待つ秒数です。この変数が定義されていない場合、 autoboot はデフォルトの 10 秒になります。

    “NO” に設定すると、 /boot/loader.rc の処理の後に autoboot を自動的には試みなくなります。 しかし、明示的に autoboot を指定すると、デフォルトの 10 秒の遅延の後に通常通り処理されます。

boot_askname
    カーネルブート時にルートデバイス名をユーザに尋ねるように、 カーネルに指示します。

boot_ddb
    ブート時に初期化に進むのではなく DDB デバッガを開始するように、 カーネルに指示します。

boot_gdb
    gdb リモートモードを、カーネルデバッガのデフォルトとして選択します。

boot_single
    カーネルがマルチユーザスタートアップを開始することを防ぎ、 カーネルがデバイスプローブを完了したときにはシングルユーザモードになります。

boot_userconfig
    カーネルブート時に カーネルの対話的なデバイス設定プログラムを実行するよう要求します。

boot_verbose
    この変数を設定すると、 ブートフェーズ中に追加のデバッグ情報をカーネルが表示します。

bootfile
    セミコロンで区切った検索パスのリストであり、 ここからブート可能なカーネルを探します。 デフォルトは ““kernel;kernel.old”” です。

console
    現在のコンソールを定義します。

currdev
    デフォルトデバイスを選択します。デバイスの文法は奇妙なものです。

init_path
    カーネルが初期プロセスとして実行しようとすべきバイナリのリストを指定します。 最初にマッチしたバイナリが使用されます。 デフォルトリストは “/sbin/init:/sbin/oinit:/sbin/init.bak:/stand/sysinstall” です。

interpret
    Forth の現在の状態がインタプリタの場合、 “ok” という値を持ちます。

LINES
    画面上の行数を定義します。ページャが使用します。

module_path
    モジュールを検索するディレクトリのリストを設定します。 モジュール名は、load コマンドまたは依存関係により暗黙的に指定されます。 この変数のデフォルト値は “/boot/kernel;/boot/modules” です。

num_ide_disks
    IDE ディスクの数を設定します。 これは、ブート時にルートディスクを見つけることに関する問題への対処です。 root_disk_unit により価値が低下しています。

prompt
    loader のプロンプトの値です。 デフォルトは “${currdev}>” です。

root_disk_unit
    ルートディスクのディスクユニット番号を検出するコードが混乱する場合、 この変数を設定することでユニット番号を強制可能です。 混乱するのは、例えば SCSI と IDE のディスクを両方持つ場合や、 IDE ディスクの並びに隙間がある場合 (プライマリスレーブが無い場合など) です。

rootdev
    デフォルトでは、カーネルブート時にルートファイルシステムの設定には currdev が使用されます。 これは rootdev を明示的に設定することによりオーバライド可能です。

dumpdev
    パニック時にカーネルがクラッシュダンプを保存可能なデバイスの名前です。 これは、自動的に kern.dumpdev sysctl(3) MIB 変数を設定します。

他の変数を使用することにより、 カーネルの調整可能なパラメータをオーバライド可能です。 次の調整可能な変数が使用可能です:

hw.physmem
    システムが使用する物理メモリ量を制限します。 デフォルトでは大きさはバイトで指定しますが、 k, K, m, M, g, G のサフィックスを使用し、 それぞれキロバイト、メガバイト、ギガバイトで指定可能です。 無効なサフィックスを使用すると、カーネルはこの変数を無視してしまいます。

hw.pci.enable_io_modes
    BIOS がオフのままとしたり、デバイスドライバが正しく有効化しなかった PCI 資源を、有効化します。 このチューナブルのデフォルト値は ON (1) ですが、 ペリフェラルによっては問題となることがあります。

hw.pci.allow_unsupported_io_range
    BIOS に割り当てられた未サポートのメモリレンジを、 PCI ブリッジが通過させることを許します。 このチューナブルのデフォルト値は OFF (0) です。

kern.maxusers
    多くの静的に割り当てられるシステムテーブルの大きさを設定します。 このチューナブルに対して適切な値をどのように選択するかについては、 tuning(7) を参照してください。 このチューナブルが設定されている場合、 カーネルがコンパイルされたときの設定ファイルで宣言された値は、 置き換えられます。

kern.ipc.nmbclusters
    割り当てられる mbuf クラスタ数を設定します。 カーネルコンパイル時に決定されたデフォルト値より小さくは、設定できません。 NMBCLUSTERS を変更します。

kern.ipc.nsfbufs
    割り当てるべき sendfile(2) バッファ数を設定します。 NSFBUFS に優先します。

kern.vm.kmem.size
    カーネルメモリの大きさ (バイト) を設定します。 カーネルコンパイル時に決定された値に、優先します。 VM_KMEM_SIZE を変更します。

kern.maxswzone
    スワップメタ情報を保持するための KVM 量を制限します。 これは、システムがサポート可能なスワップ量に直接影響を与えます。 この値は、KVA 空間のバイト数で指定され、デフォルトは約 70MB です。 この値を減らし過ぎて、 実際に構成されるスワップが カーネルがサポートするスワップの 1/2 を越えてしまわぬよう、 注意してください。 デフォルトの 70MB は、 カーネルが最大 (約) 14 GB のスワップを構成可能とします。 バッファキャッシュや NMBCLUSTERS といった 他の資源用の KVM 予約を大幅に増やす場合のみ、 本パラメータを調整してみてください。 VM_SWZONE_SIZE_MAX を変更します。

kern.maxbcache
    バッファキャッシュ用に予約される KVM の量を制限します。 バイト数で指定します。 デフォルトの最大値は 200 MB です。 このパラメータは、大規模構成において、 バッファキャッシュが多くの KVM を消費してしまうことを避けるために使用します。 スワップゾーンや NMBCLUSTERS といった 他の資源用の KVM 予約を大幅に増やす場合のみ、 本パラメータを調整してみてください。 NBUF パラメータがこの制限に優先することに注意してください。 VM_BCACHE_SIZE_MAX を変更します。

machdep.disable_mtrrs
    i686 MTRR を無効化します (x86 のみ)。

net.inet.tcp.tcbhashsize
    TCBHASHSIZE のコンパイル時の設定値をオーバライドするか、 デフォルトの 512 にプリセットします。 2 のべき乗である必要があります。

  組み込みパーザ
組み込みコマンドが実行されるとき、 行の残りはコマンドが引数として受け取り、 通常の Forth コマンドには使用されない特別なパーザがコマンドを処理します。

この特別なパーザは、解析したテキストに対して次のルールを適用します:

1.  すべてのバックスラッシュ文字は前処理されます。

    •   \b , \f , \r , \n, \t は C で扱われるように処理されます。

    •   \s は空白文字に変換されます。

    •   \v は ASCII の 11 に変換されます。

    •   \z は単にスキップされます。 “\0xf\z\0xf” のように使用すると便利です。

    •   \0xN と \0xNN は 16 進数の N と NN に変換されます。

    •   \NNN は 8 進数 NNN の ASCII 文字に変換されます。

    •   \" , \' , \$ は、これらの文字をエスケープし、 後述するステップ 2 における特殊な扱いをされないようにします。

    •   \\ は単一の \ に変換されます。

    •   他の場合、バックスラッシュは単に取り除かれます。

2.  エスケープされていないクォートまたはダブルクォートの間のすべての文字列は、 後続するステップにおいて単一の語として扱われます。

3.  $VARIABLE または ${VARIABLE} は、環境変数 VARIABLE の値に変換されます。

4.  空白で区切られた複数の引数を、呼び出した組み込みコマンドへ渡します。 空白は \\ を使用することによりエスケープ可能です。

解析ルールには例外があり、これは 組み込み語と FORTH で説明します。

  組み込み語と FORTH
すべての組み込み語は、状態を意識する即時実行語です。 インタプリトされると、これらは前述の通りに振舞います。 一方コンパイルされると、 引数をコマンドラインからではなくスタックから取り出します。

コンパイルされると、 実行時に組み込み語は、スタック上で次のパラメータを見付けられると期待します:
    addrN lenN ... addr2 len2 addr1 len1 N
ここで addrX lenX は文字列であり、組み込み語の引数として解釈されるコマンドラインを構成します。 内部的には、おのおのの間に空白を狭んで、 これらの文字列は 1 から N まで結合されます。

引数が渡されない場合、組み込み語が引数を受け付けない場合であっても、 単一の 0 を渡す 必要 があります。

この動作には利点がありますが、それ自身にはトレードオフがあります。 組み込み語の実行トークンが ( ' または ['] を通して) 得られて、 catch または execute に渡された場合、組み込み語の動作は catch または execute が実行されるときの システムの状態に依存します ! これは、 例外を扱いたいまたは扱う必要があるプログラムにとっては、特に悩ましいものです。 この場合、代理 (proxy) を使用することをお勧めします。 例えば次のようにします:
    : (boot) boot;

FICL
FICL は C で記述された Forth インタプリタであり、 C の関数などとして呼び出し可能な forth 仮想マシンライブラリの形式です。

loader では、対話的に読み込まれた各行は FICL に与えられます。 FICL は、組み込み語を実行するために loader を呼び戻します。 組み込みの include もまた、1 度に 1 行ずつを FICL へ与えます。

FICL へ使用可能な語は 4 グループへ分類可能です。それは、 ANS Forth 標準語、追加の FICL 語、追加の FreeBSD 語、そして組み込みコマンドです。 最後のものは既に説明しました。 ANS Forth 標準語は、 規格 の節に列挙しています。 別の 2 グループの語については、以降の小節において説明します。

  FICL 追加語

.env

.ver

-roll

2constant

>name

body>

compare
    This is the STRING word set's compare.

compile-only

endif

forget-wid

parse-word

sliteral
    This is the STRING word set's sliteral.

wid-set-super

w@

w!

x.

empty

cell-

-rot

  FREEBSD 追加語

$ (--)
    最初に入力バッファを表示した後、入力バッファの残りを評価します。

% (--)
    catch 例外ガード下の、入力バッファの残りを評価します。

.#  . と同様に動作しますが、後続の空白を表示しません。

fopen (addr len mode -- fd)
    ファイルをオープンします。ファイル記述子を返します。 失敗時には -1 を返します。 mode パラメータは、ファイルオープンの目的が読み込み用、書き込み用、 両用のいずれであるかを選択します。 定数 O_RDONLY, O_WRONLY, O_RDWR が /boot/support.4th で定義され、それぞれ読み込み専用、書き込み専用、読み書きを示します。

fclose (fd --)
    ファイルをクローズします。

fkey (fd -- char)
    ファイルから 1 文字読み込みます。

fload (fd --)
    ファイル fd を処理します。

fopen (addr len -- fd)
    ファイルをオープンします。 ファイル記述子を返すか、失敗時には -1 を返します。

    fread (fd addr len -- len') ファイル fd から len バイトを、バッファ addr へ読み込もうとします。 実際に読み込んだバイト数を返します。 エラー時またはファイルの終了の場合には -1 を返します。

heap
    ディレクトリヒープ中に残された空間を、セル数の単位で返します。 これは、動的なメモリ割り当ての意味で使われるヒープとは無関係です。

inb (port -- char)
    ポートからバイトを読み込みます。

key (-- char)
    コンソールから 1 文字読み込みます。

key? (-- flag)
    コンソールから読み込み可能な文字がある場合、 真 を返します。

ms (u --)
    u マイクロ秒待ちます。

outb (port char --)
    ポートへバイトを書き込みます。

seconds (-- u)
    深夜 0 時からの秒数を返します。

tib> (-- addr len)
    入力バッファの残りを、スタック上の文字列として返します。

trace! (flag --)
    トレースを有効または無効にします。 catch とともには動作しません。

  FREEBSD で定義される環境問い合わせ

arch-i386
    アーキテクチャが IA32 の場合 真 です。

arch-alpha
    アーキテクチャが AXP の場合 真 です。

FreeBSD_version
    コンパイル時の FreeBSD バージョンです。

loader_version
    loader のバージョンです。

  システム文書

関連ファイル
/boot/loader
    loader 自身。
/boot/boot.4th
    追加の FICL の初期化。
/boot/boot.conf
    loader のブートストラップスクリプト。価値が低下しています。
/boot/defaults/loader.conf
/boot/loader.conf
/boot/loader.conf.local
    loader 設定ファイル。 loader.conf(5) で解説されています。
/boot/loader.rc
    loader のブートストラップスクリプト。
/boot/loader.help
    help がロードします。 ヘルプメッセージを含みます。

使用例
シングルユーザモードでブートします:

    boot -s

カーネルのユーザ設定ファイルをロードします。 他の load コマンドを試みる前にカーネルをロードする必要があることに注意してください。

    load kernel
    load -t userconfig_script /boot/kernel.conf

カーネルと起動画面をロードし、5 秒以内に自動ブートします。

    load kernel
    load splash_bmp
    load -t splash_image_data /boot/chuckrulez.bmp
    autoboot 5

ルートデバイスのディスクユニットを 2 に設定し、ブートします。 IDE ディスクが 2 台のシステムで、 2 台目の IDE が wd1 ではなく wd2 に固定されているシステムにおいて、 必要となるでしょう。

    set root_disk_unit=2
    boot /kernel

次を参照してください:

/boot/loader.4th
    追加の組み込み的な語について。

/boot/support.4th
    loader.conf が処理する語について。

/usr/share/examples/bootforth/
    分類された使用例。

エラー
次の値を loader は返します:

100 組み込みコマンド処理において任意のタイプのエラーが発生しました。

-1  Abort が実行されました。

-2  Abort" が実行されました。

-56 Quit が実行されました。

-256
    インタプリトするテキストがありません。

-257
    成功するためには更なるテキストが必要です -- 次の実行で終了します。

-258
    Bye が実行されました。

-259
    未定義エラー。

関連項目
libstand(3), loader.conf(5), tuning(7), boot(8), btxld(8)

規格
ANS Forth 互換性の観点では、loader は 環境に制限がある ANS Forth System です。 Core Extensions 語集合からは、 .(, :noname, ?do, parse, pick, roll, refill, to, value, \, false, true, <>, 0<>, compile, , erase, nip, tuck, maker を提供しています。 Exception Extensions 語集合を提供しています。 Locals Extensions 語集合を提供しています。 Memory-Allocation Extensions 語集合を提供しています。 Programming-Tools 拡張語集合からは .s, bye, forget, see, words, [if], [else], [then] を提供しています。 Search-Order 拡張語集合を提供しています。

歴史
loader が最初に登場したのは FreeBSD 3.1 です。

作者
-nosplit loader は Michael Smith <msmith@FreeBSD.org> が記述しました。

FICL は John Sadler <john_sadler@alum.mit.edu> が記述しました。

バグ
expect と accept の語は、コンソールからではなく入力バッファから読み込みます。 後者については修正されますが、前者は修正されません。