PICOBSD(8)

名称
picobsd - フロッピディスクベースの FreeBSD システム

書式
picobsd [options] [floppy-type [site-name]]

解説
picobsd ユーティリティは、最小実装の FreeBSD (歴史的に PicoBSD と呼ばれます) の生成に使用可能なスクリプトです。 生成物は、典型的には 1 枚のフロッピディスクに収まるか、 CDROM やフラッシュメモリといったメディア、あるいは etherboot 経由から単一のイメージファイルとしてダウンロード可能な ものとなります。

picobsd ユーティリティは、もともとファイアウォールやブリッジのような単純な スタンドアロンシステムを構築するために作られたものですが、 サーバに存在するものとは違うソースツリーを使用してイメージを クロスビルドできるため、開発者にとってはシステムを 再インストールせずに自分の書いたコードをテストできるので 大変便利でしょう。

ブートメディア (典型的にはフロッピディスク) は、 ブートローダと、メモリファイルシステムを含む圧縮カーネルを含みます。 メディアに依存しますが、追加ファイルをいくつか含むかもしれません。 これらは、実行時に更新可能であり、 メモリファイルシステム中のファイルの書き換え/更新に使用されます。

システムは、カーネルを通常の方法でロードし、 メモリファイルシステムを伸長し、これをルートとしてマウントします。 その後、メモリファイルシステムを、ブートメディアからのファイルで更新し (存在する場合のみ)、特別なバージョンの /etc/rc を実行します。 ブートメディア (フロッピ等) は、ロードのためだけに必要であり、 一般には読み取り専用で使用されます。 ブートフェーズ後は、システムは完全に RAM で実行されます。

次のオプションが使用可能です (詳細は picobsd も参照してください):

--src SRC_PATH
    /usr/src にあるものではなく SRC_PATH にあるソースツリーを使用します。 このオプションは、フロッピイメージをクロスビルドする際に 便利でしょう。 このオプションを使用する際には、 <SRC_PATH>/../usr にサブツリーを作成し、クロスビルドに必要な 正しいヘッダファイルやライブラリ、そしてツール ( config(8) のような) を置いてツリーを初期化しておく必要があります (後述の --init オプションを参照してください)。 ソースファイルは picobsd スクリプトによっては変更されません。しかし、 ソースツリーは完全に読み込み専用であるというわけではありません。 なぜなら、 config(8) はカーネル設定ファイルがソースツリーのサブディレクトリにある ものとしていますし、また usr サブツリーを初期化する過程でソースツリーのいくつかの部分に 触れてしまうからです (この動作はリリースビルド用スクリプトの バグであり、時間がたてばこのバグは取り払われるでしょう)。

--init
    --src オプションと一緒に使用した場合、後で picobsd イメージを構築するのに必要となる <SRC_PATH>/../usr サブツリーを初期化します。

--modules
    カーネルモジュールも構築します。 カーネルモジュールはフロッピイメージには入りませんが、 構築用ディレクトリには利用可能なまま残っています。

-n  スクリプトを、非対話的にします。 最初のメニューを表示せず、ユーザの入力を要せずに構築処理に進みます。

-v  スクリプトを冗長表示にし、実行するコマンドを表示し、 それらの実行前にユーザの入力を待ちます。 デバッグ時に有用です。

--all_in_mfs
    カーネル内に含まれているメモリファイルシステムイメージにある ファイルシステムの内容をすべて置きます。 これはデフォルトの動作であり、 etherboot もしくは pxeboot(8) を使用して、完全に機能するシステムとしてカーネルそのものを ロードできるため大変便利です。

--no_all_in_mfs
    floppy.tree に含まれているファイルをフロッピイメージに残します。これにより、 ファイルをカーネルとは別にロードすることができます (そして、個別にファイルを更新してフロッピイメージを カスタマイズできます)。

--floppy_size size
    フロッピイメージのサイズを設定します。 CDROM に焼くイメージ用に、1440 以外の値を使用可能です。

-c, -clean
    前回の構築時にできた生成物を消します。

環境
サイズ制限が極めて厳しいため、 picobsd の環境は通常の FreeBSD といくつかの点で異なっています:

•   ダイナミックライブラリは存在せず、 /usr/lib ディレクトリもありません。 そのため、スタティックリンクした実行体のみ実行可能です。

•   実行体のサイズを減らすため、特定のフロッピ内のすべての実行体は、 crunchgen(1) を利用して単一の実行体にまとめられています。

•   プログラムによっては最小限のバージョンが提供されています。 ns は netstat(1) の機能限定版であり、 vm は vmstat(8) の機能限定版です。

PicoBSD の構築
picobsd のソースはディレクトリ /usr/src/release/picobsd の下の階層にあります。 以下では、相対パス名はすべてこのディレクトリからの相対位置です。 picobsd の構築過程は、時とともに少し変化しました。 コード量がやむなく増加していることに対応するため、 なるべく多くのものをフロッピに詰め込むための からくりがだんだんと多く必要となったからです。 FreeBSD 4.3 以降では、サポートされている構築スクリプトは /usr/src/release/picobsd/build/picobsd であり、どこからでも実行可能です。 対話的モードで実行した場合 ( --n オプションをつけなければこれがデフォルトです)、 スクリプトによってフロッピイメージを構築するのに使用される さまざまなパラメータを設定可能です。 認識するフロッピイメージは次の種類があります。私達は、このイメージを 機能するものに維持し、カーネルおよびアプリケーションのサイズが やむを得ず大きくなっていますがそれでも 1.44MB フロッピに収まる ように努めています。

bridge
    ブリッジ、ルータおよびファイアウォールに適した設定です。

次の設定も存在はしますが、参照するにとどめてください。 これらの設定の多くはもう直せないほど古いものになっていますし、 体裁を整える努力はなんら払われていません。

dial
    ダイヤルアウト (ppp(8)) ネットワークに適した設定です。

isp ダイヤルイン (ppp(8)) ネットワークに適した設定です。

net 一般的なネットワークに適した設定です。

router
    ルータとして使用する場合に適した設定です。 この特別な設定は、最低限のハードウェアで動作することを 目標としています。

これらの設定は、 あなたが独自の変更を行うときに参考にするためだけにあります。 すべてがテストされたわけではありませんし、 動かすため、もしくはコード量増加時に空きディスク空間に納めるために、 設定ファイルにちょっとした修正が必要となるかもしれません。

あなた独自のフロッピタイプを定義可能です。それには、 何か好きな名前 (例えば FOO) を選んでディレクトリを作成し、その中に次のファイル およびディレクトリのいくつかを含めれば良いのです。 これらのファイルを作成するための詳細情報については、 標準の picobsd の設定のどれか 1 つを参考資料として見てください。

PICOBSD
    カーネル設定ファイル (必須)。 これは、大抵の場合標準のカーネル設定ファイルですが、 場合によってはカーネルサイズを小さくするために 必要のないドライバやオプションを削っているためファイルが小さく なっていることがあります。

    picobsd カーネル設定ファイルとして認識されるためには、 次に示すように “#PicoBSD” で始まる行も含め、対応する MD_ROOT_SIZE オプションも含める必要があります:

        #marker    def_sz  init   MFS_inodes    floppy_inodes
        #PicoBSD   4200    init   8192          32768
        options MD_ROOT_SIZE=4200      # def_sz と同じ

    この設定でメモリファイルシステムのサイズをスクリプトに教え、 イメージを構築する方法に関する他の詳細をいくつか与えます。

crunch.conf
    crunchgen(1) 設定ファイル (必須)。 この設定にはプログラムソースを含んだ ディレクトリのリスト、構築されるバイナリのリスト、および これらのバイナリプログラムが使用するライブラリのリストが 含まれています。 このファイルの文法に関する正確な詳細は crunchgen(1) マニュアルページを参照してください。

    picobsd の設定を扱う際には次の点がとりわけ重要です:

    •   makefile のオプションに、makefile が理解できる構築用オプションを 渡すことができます。プログラムのサイズを減らすためです。 次の形式の行を用いて実現されます。

            buildopts -DNOPAM -DRELEASE_CRUNCH ...

    •   ソースファイルのあるディレクトリのリストを与えるときは、 次のエントリを最初にリストしておくと便利です:

            srcdirs /usr/src/release/picobsd/tinyware

        こうすると、 picobsd 特有のバージョンのプログラムがこのディレクトリで見つけられる ようになります。

    •   文字列 “@__CWD__@” は、 picobsd 設定ファイルが入っているディレクトリ (すなわち、 PICOBSD, crunch.conf などが見つかるディレクトリ) のフルパス名に置き換わります。 設定ファイルのあるディレクトリの中に 存在するソースコードを参照するのに便利でしょう。例えば、次の ようにです。

            srcdirs @__CWD__@/src

config
    picobsd スクリプトが読み取るシェル変数 (省略可能)。 ここで最も重要な変数は次のものです:

    MY_DEVS
        FreeBSD (5.0 では devfs(5) がありますので使用されていません) イメージの /dev ディレクトリに作成されるべきデバイスのリストを設定すべきです (これは、 MAKEDEV(8) に渡される引数そのものですから、デバイスの名称については MAKEDEV(8) のマニュアルページを参照してください)。

    fd_size
        picobsd イメージのサイズ (キロバイト単位) です。 デフォルトでは fd_size は 1440 に設定されます。この値では、標準のフロッピディスクに 適したイメージを生成します。

        CDROM にイメージを保存するつもりなら (例えば、 “El Torito” フロッピエミュレーションを用いて)、 fd_size を 2880 に設定できます。 ハードディスク (パーティション内もしくはディスク全体) に イメージをダンプするつもりなら、標準のフロッピサイズに 制限されることはありません。 それ自体がサイズの大きなイメージを使用しても実行時に RAM が 浪費されることはありません。なぜなら、実際にイメージから ロードされるファイルしかメモリ使用量には関わってこないからです。

    import_files
        フロッピツリー内に取り込まれるファイルのリストを含みます。 絶対パス名の場合標準ファイルシステムを、相対パス名の場合 使用しているソースツリー (すなわち SRC_PATH/..) SRC_PATH/.. のルートディレクトリを表します。 通常、共有ライブラリやデータベースなどのファイルを 取り込みたい場合に、 floppy.tree/ ディレクトリ配下の設定内でそれらのファイルの 複製を最初に作らなくても良いように、このオプションを使用できます。

floppy.tree.exclude
    標準フロッピツリーから得る、コピーしたくないファイルのリスト (省略可能)。

floppy.tree/
    標準フロッピツリーへの、ローカルな追加 (省略可能)。 このサブツリーの内容はフロッピイメージにそのままコピーされます。

floppy.tree.<site-name>
    上と同じですが、サイト固有です (省略可能)。

構築過程に関する更なる情報は、 picobsd スクリプトのコメントに記述されています。 サンプルの設定ファイルは /usr/src/release/picobsd/<floppy-type>/ にあります。

別のソースツリーの使用
構築スクリプトは、別のソースツリーを使用するよう、 --src SRC_PATH オプションで指示可能です。 指定するツリーは、カーネルおよびイメージに含める全プログラムの ソースすべてを含む必要があります。 例として、RELENG_4 ソースツリーを使って bridge フロッピをクロスビルドするには、次のようにしてできます:

    cd <some_empty_directory>
    mkdir FOO
    (cd FOO; cvs -d<my_repository> co -rRELENG_4 src)
    picobsd --src FOO/src --init   # これは 1 回だけ必要です
    picobsd --src FOO/src -n -v bridge

構築に成功すると、ディレクトリ build_dir-bridge/ には etherboot でダウンロード可能な kernel 、 picobsd.bin という名前のフロッピイメージ、さらに 他のディレクトリでコンパイルされた生成物が入ります。 FOO/src 内のソースツリーを変更したい場合は、 新しいイメージは単に

    picobsd --src FOO/src -n -v bridge
を実行すれば得られます。

これに対し、変更によって、インクルードファイルや ライブラリに影響がでる場合は、最初にそれらを更新する 必要があります。例えば、まず最初に

    picobsd --src FOO/src --init   # これは 1 回だけ必要です

を実行するのです。 このような変更があれば通常はいつでも実行するでしょう。

PicoBSD のインストール

  フロッピへのインストール
歴史的には、 picobsd はフロッピディスクから起動されます。この場合、単に

    dd if=picobsd.bin of=/dev/rfd0

を実行してインストールできます。そうすれば、フロッピで ブートできます。

  ハードディスクへのインストール
イメージをハードディスク (ボリューム全体もしくはスライスの 1 つ) に置くのにも同じプロセスが使用できます。

    dd if=picobsd.bin of=/dev/ad2
    dd if=picobsd.bin of=/dev/ad2s3
    dd if=picobsd.bin of=/dev/ad2 oseek=NN

1 番目の形式では、イメージをディスク全体にインストールします。 このときには、イメージはフロッピに対するときと同じ方法で動作します。

2 番目の形式では、イメージをスライス番号 3 にインストールします (このスライスがイメージの内容を保存するのに充分な大きさを 持っている必要があります)。 しかし、このやり方は、指定したパーティションに正しいディスク ラベルが入っていない場合にしか成功せず、正しいディスクラベルを 持っている場合には、カーネルはラベルを上書きされないようにする でしょう。 この場合、3 番目の形式を使うことができます。 NN のところは実際のパーティションの開始位置で置き換えてください (開始位置は fdisk(8) を使用すると決定できます)。 スライスにイメージを保存した後でも、まだ認識はされないという ことに注意してください。 ラベルを正しく初期化するには disklabel(8) コマンドを使用しなくてはなりません (どうしてかは聞かないでください！)。 初期化を行う 1 つの方法としては、

    disklabel -w ad0s2 auto
    disklabel -e ad0s2

とし、エディタから実際のパーティションに対応する行を入力します。 例えば、イメージが 2.88MB (5760 セクタ) である場合、パーティションに 対して次の行を入力する必要があります:

    a:5760   0    4.2BSD   512   4096

この時点で、このパーティションはブート可能になります。 イメージサイズはスライスサイズ (パーティション “c:” として示されます) よりも小さい可能性があることに注意してください。

  CDROM へのインストール
もう 1 つのオプションに、イメージを CDROM に置くというものが あります。 ディスクタイプ foo に対するイメージがディレクトリ build_dir-foo にあると仮定します。そうすると、次のコマンドでブート可能な (El Torito) イメージを生成する (さらに、焼く) ことができます:

    mkisofs -b picobsd.bin -c boot.catalog -d -N -D -R -T \
        -o cd.img build_dir-foo
    burncd -f /dev/acd0c -s 4 data cd.img fixate

イメージサイズは 1.44MB もしくは 2.88MB に制限される ことに注意してください。その他のサイズではまず動作しない でしょう。

  ネットワークからのブート
picobsd を用いたさらにもう 1 つの方法は、ネットワークから イメージをブートすることです。 これを実現するためには、コンパイルによる副産物として 入手できる非圧縮カーネルを使用する必要があります。 さらなる詳細については、ネットワークブートに関する ドキュメントを参照してください。 picobsd カーネルは、標準 FreeBSD kernel としてブート可能です。

PicoBSD のブート
picobsd をブートするには、フロッピを挿入してマシンをリセットします。 ブート手順は標準の FreeBSD ブートと似ています。 フロッピからのブートは普通は非常にゆっくりと進みます (1 〜 2 分というオーダです)。イメージをハードディスクや コンパクトフラッシュ、あるいは CDROM に保存している場合、 事はずっと速く進みます。

etherboot を使用して、ロード済みで非圧縮のカーネルイメージを ロードすることもできます。 このイメージは、 picobsd 構築過程で生成される副産物です。 この場合、10Mbit/s イーサネットでさえ、ロード時間は数秒になります、

ブート後は、 picobsd は、メモリファイルシステムからルートファイルシステムをロードし、 /sbin/init を起動します。そして制御を 1 番目のスタートアップスクリプト /etc/rc に渡します。後者は /etc および /root ディレクトリにデフォルトファイル群と一緒に入っています。 そして、ブートデバイスを同定し (フロッピやハードディスクの パーティション)、そして場合によってはルートファイルシステムの 内容をブートデバイスから読み込んだファイルで上書きします。 これによって、同一メディアにローカルの設定を 保存することが可能です。 このフェーズの後では、ユーザが明確に使用しようとしない限り ブートデバイスはもう使用されません。

この後、制御は 2 番目のスクリプト /etc/rc1 に渡ります (このスクリプトはブートデバイスから上書き可能です)。 このスクリプトは、 1 番最初にくるイーサネットインタフェースの MAC アドレスをキーに、そして /etc/hosts ファイルをルックアップテーブルに 使用してホスト名とシステムとを関連づけようとします。 そして、制御はメインのユーザ設定スクリプト /etc/rc.conf に渡されます。このファイルは、 /etc/rc.conf.defaults で事前に設定されたいくつかの設定用変数の値を 上書きするためにあります。 hostname 変数を用いて、同一ファイルから違った設定を 作成することができます。 制御が戻ってきたら、 /etc/rc1 は初期化を完了し、このスクリプトの一部として ネットワークインタフェースを設定し、オプションで ファイアウォール設定スクリプト /etc/rc.firewall を呼び出します。 このスクリプトには、独自のファイアウォール設定を保存できます。

デフォルトでは、 picobsd は、すべてメインメモリから実行し、明示的に要求しなければ スワップ領域は持たないのだということに注意してください。 /etc/rc1 が制御を受け取った後では、ブートデバイスももう使用されません。 何度も言いますが、明示的に要求しなければです。

PicoBSD システムの設定
picobsd システムの運用については、ブート時に読み込まれるいくつかの ファイルを通して設定可能であり、標準の FreeBSD システムと大変良く似ています。しかしながら、保存しておくべき ファイルおよび / もしくはカスタマイズすべきファイル数を 減らし、それによってスペースを節約するために 多少小さな違いがあります。 設定ファイルの中では、違いがあるものには次のものがあります:

/etc/hosts
    伝統的に、このファイルには IP とホスト名とのマッピングが 入っています。 このマッピングに加えて、 picobsd バージョンのものにはイーサネット (MAC) アドレスとホスト名との マッピングも次のように含まれています:

        #ethertable     start of the ethernet->hostname mapping
        #mac_address            hostname
        # 00:12:34:56:78:9a     pinco
        # 12:34:56:*            pallino
        # *                     this-matches-all

    ここで、 “#ethertable” を含んだ行はテーブルの始まりを表しています。

    MAC アドレスが見つからなかった場合、このスクリプトは システム用のホスト名と IP アドレスを入力するよう促します。 そしてこの情報を (メモリ上の) /etc/hosts ファイルに保存し、後で簡単にディスク上に保存できるように します。

    アドレス部にはワイルドカードを使用できますので、例の 最後の行のようにすると任意の MAC アドレスにマッチし、 システムに入力要求をさせないようにできるということに 注意してください。

/etc/rc.conf
    このファイルにはシステムの運用状況を制御する変数が いくつか含まれています。例えば、インタフェース設定、 ルータ設定、ネットワークサービスの起動などです。 これらの変数の正確なリストおよびその意味については、 /etc/rc.conf.defaults を参照してください。

    これらの変数の中には、 /etc 中のファイルの内容をいくつか上書きできるようにするものが あるということに触れておく価値はあります。 このオプションは、さしあたり /etc/host.conf および /etc/resolv.conf 用に利用可能です。これらのファイルの内容は一般的にとても 小さく、この種の更新を行うには向いています。 これらの変数を使用する場合、改行を適切に使うことを忘れないで ください。例えば、次のようにです。

        host_conf="# この行は /etc/host.conf に入ります
        hosts
        bind"

    必須というわけではありませんが、このファイル中では、 /etc/rc.conf.defaults で示される変数しか設定してはいけません。そして、 ネットワークが起動しているかどうかに依ってしまうサービスは 起動させずにおくべきです。 ネットワークの起動は後からでも行えます。 firewall_enable="YES" に設定した場合、 /etc/rc.firewall スクリプトがネットワークインタフェースの設定後に起動されますので、 ファイアウォールを設定し、安全にネットワークサービスを起動したり、 ルーティングやブリッジなどを有効にしたりできます。

/etc/rc.firewall
    このスクリプトは ipfw(4) ファイアウォールを設定するために使用することができます。 エントリ時に、 fwcmd 変数はファイアウォール用コマンドのパス名に設定されます。 firewall_type には /etc/rc.conf ファイル中で設定された値が入っており、 hostname にはホストに割り当てられた名前が入っています。

update という名前の小さなスクリプトがあり、これを用いてブート後に変更した ファイルを編集したり、ディスクに保存したりできます。 このスクリプトは 1 つまたはそれより多い絶対パス名を取り、 引数として渡されたファイルに対してエディタを実行し、そして ファイルを圧縮したコピーをディスクに保存します (この操作の前後でディスクをマウント / アンマウントします)。

引数無しでこのスクリプトを起動した場合、 update は rc.conf, rc.firewall および master.passwd ファイルを編集し、保存します。

引数の 1 つが /etc (ディレクトリ名だけ) である場合、このコマンドは、/etc ディレクトリにあり、 (例えば、前回の updateの結果) すでにコピーがディスク上にあるファイルを みなディスクに (編集せずに) 保存します。

関連項目
crunchgen(1), mdconfig(8), swapon(8), vnconfig(8)

作者
-nosplit Andrzej Bialecki <abial@FreeBSD.org> です。 スクリプト関連の仕事を Luigi Rizzo <luigi@iet.unipi.it> 等が引き継ぎました。 マニュアルページと Makefile の作成は Greg Lehey <grog@lemis.com> が行いました。

バグ
picobsd を構築する際、 構築作業を行うシステムのカーネルには vn(4) ドライバがインストールされていなければなりません。

構築の過程は “root” で実行しなければなりません。 mdconfig(8)/vnconfig(8) と mount(8) を実行する必要があるためです。

picobsd の構築には、依然、中身の見えにくいところがあります。 最大の問題は、 どういうふうにすればフロッピにぴったり詰め込むことができるかを 判断することです。 現実的な方法は試行錯誤しかありません。