HDD | パーティション | デバイス名 | 内容 |
1台目 | 1番目 | /dev/ad0s1 | Windows |
1台目 | 2番目 | /dev/ad0s2a | 作業用 FreeBSD の / |
1台目 | 2番目 | /dev/ad0s2e | 作業用 FreeBSD の /var |
1台目 | 2番目 | /dev/ad0s2f | 作業用 FreeBSD の /usr |
1台目 | 3番目 | /dev/ad0s3e | 作業用 FreeBSD の /home |
2台目 | 1番目 | /dev/ad1s1a | イメージ用 FreeBSD の / |
2台目 | 1番目 | /dev/ad1s1e | イメージ用 FreeBSD の /usr |
インストールが済んだら,イメージ用 FreeBSD を起動してください.
以降ではイメージ用 FreeBSD 側での設定を行います.
今回はなるべく多くのPC上で動作させたいので,SVGA用のXサーバを利用することに より,機種依存性を極力少なくしています.
XF86Setup を起動して,以下の設定を行います.
ここで,CDBSD の起動後に,X サーバを自由に選択できるようにしたいので, 以下のようにリンクを張りなおしておきます.
root# rm /usr/X11R6/bin/X root# ln -s ../../../etc/X /usr/X11R6/bin/X root# ln -s ../usr/X11R6/bin/XF86_SVGA /etc/Xリンクは,CDBSD の CD-ROM を /cdrom にマウントして中身を見るときのために, すべて相対リンクにします.
まずは vipw でパスワードを修正します.
root# vipwで vipw を起動し,root の行を,
root::0:0::0:0:Charlie &:/root:/bin/cshのように,2カラム目を空欄に修正することにより,パスワード無しに設定します. guestの行も同様にパスワード無しに修正します.
guest::1001:1001::0:0:Guest User:/home/guest:/bin/tcsh繰り返しますが,セキュリティには各自で十分に注意してください.CDBSD は HDD 上の Windows のパーティションをマウントして操作することができるため,root の パスワードが無い場合には,誰でも Windows 領域にアクセスできることになって しまいます.もしもパスワードを設定したいならば,passwd コマンドで設定して おいてください.
さらに,/etc 以下のファイル(主に /etc/rc.conf など)を適切に修正します.
これが CDBSD 起動時のデフォルトの設定になります.ただし /etc/fstab は
後で修正するので,ここで CDBSD 用の修正をする必要はありません.
(/etc/fstab をへんに修正すると,イメージ用 FreeBSD が起動できなくなって
しまいますので...)
root# ln -s ../README /root/README root# su guest guest> cd /home/guest guest> ln -s ../../README /home/guest/READMEのようなリンクを張っておくといいでしょう. /root と /home は CDBSD の起動時に MFS でマウントされるので, あまり巨大なファイルを置いたり,たくさんのファイルを置いたりしないように 注意してください.
root# rmdir /usr/tmp root# ln -s ../tmp /usr/tmpのようにして,/tmp へのリンクにしておきます./var/tmp は rc.diskless2 に よって MFS 上に作成されるので,リンクにする必要はありません.また,CDBSD の CD-ROM を /cdrom などにマウントして中身を見るときのために,
root# cd / root# rm /compat root# ln -s usr/compat /compatのようにして,絶対リンクを相対リンクに張りかえておくといいでしょう.
root# mkdir /fd /mnt2 /mnt3 /mnt4 /work /work2 root# mkdir /windows95 /windowsnt root# chmod 777 /windows95 /windowsntのようにして,マウントポイントを多めに作成しておきます. /windows95, /windowsnt は HDD 上の Windows パーティションのマウント用の ためのものなので,属性を書き込み可にしておきます.
device pcm0 at isa? irq 5 drq 1 flags 0x0 device pca0 at isa? port IO_TIMER1を追加.
root# ./MAKEDEV snd0 root# ./MAKEDEV ad0s1 ad0s2 ad0s3 ad0s4 ad1s1 ad1s2 ad1s3 ad1s4 root# ./MAKEDEV ad0s1a ad0s2a ad0s3a ad0s4a ad1s1a ad1s2a ad1s3a ad1s4aなどをして,必要なデバイスを作成しておきます.
リスト1 mkrwfs.sh #!/bin/sh # mkrwfs.sh is a script to change read-only file system directory to # writable directory by MFS (Memory File System). Files and directories # in the old directory are saved. # # usage: # mkrwfs.sh [directory] # # You can specify the directory absolutely or relatively. dir=$1 case $dir in /*) # dir is absolute directory. absodir=$dir ;; *) # dir is relative directory. absodir=`/bin/pwd`/$dir ;; esac if [ -d $dir ]; then # Backup files and directories in old directory. /usr/bin/tar czPf /tmp/mkrwfs.tmp.tgz $dir /sbin/mount_mfs -s 4096 -T qp120at dummy $absodir /bin/chmod 755 $dir # Restore the files and directories. /usr/bin/tar xzPf /tmp/mkrwfs.tmp.tgz rm -f /tmp/mkrwfs.tmp.tgz else echo "$absodir: cannot mount to MFS. (not found)" fimkrwfs.sh は,CDBSD の起動後に,
root# mkrwfs.sh /usr/local/etcのようにして使用します.指定したディレクトリを MFS でマウントしなおし, 既存のファイルやディレクトリをコピーします.ディレクトリは絶対パスでも 相対パスでも指定できます.
root# mkdir /cdbsd root# mount /dev/ad1s1a /cdbsd root# mount /dev/ad1s1e /cdbsd/usrのようにして,イメージ用 FreeBSD のパーティションを /cdbsd にマウント してください.
FreeBSD では vnconfig の機能を使用して,イメージファイルをマウントすることが できます.(Linux の loopback filesystem に相当するものです)
root# mkdir /fd root# vnconfig -c vn0 boot.flp root# mount /dev/vn0c /fdこれで,boot.flp を /fd にマウントし,読み書きできるようになります.
root# cd /fd root# ls boot kernel.gz root#まず,ブート時に CD-ROM がマウントされるよう,
root# mkdir /fd/etc root# cd /fd/etc root# vi fstabのようにして,/fd/etc/fstab をリスト2のように作成します. 起動時には,ブートしたディスクの /etc/fstab が読まれる (参考文献[3]p.29参照)ので,boot.flp 中に /etc/fstab を 作成して,/dev/acd0c を / にマウントするようにします.
リスト2 ブート用FDの /etc/fstab の例 /dev/acd0c / cd9660 ro 0 0
さらに,イメージ用 FreeBSD のカーネルを boot.flp 上にコピーします.
root# cp /cdbsd/kernel /tmp root# cd /tmp root# gzip -9 kernel root# mv kernel.gz /fd作業が終了したら,アンマウントします.
root# cd / root# umount /fd root# vnconfig -u vn0これで CD-ROM からブートするための 2.88MB の FD イメージを作成することが できました.ところで実は,ここで行っているのは,CD-ROM 上に置く FD の ブートイメージを修正して,FD 上の fstab を参照して CD-ROM をマウントし, FD 上のカーネルで起動するようにしているだけです.したがって,CD-ROM 上の カーネルを読み込んでブートするわけではないため,本当の意味での CD-ROM ブートと は言えないかもしれません. 本当は CD-ROM 上の /kernel を読み込んでブートするようにしたいと思い, boot.flp 上の /boot.config, /boot/loader.rc, /boot/loader.conf などを いろいろ編集したり,/boot/loader のかわりに /boot/cdboot を利用したり などして指向錯誤したのですが,うまくいきませんでした.現在,これを実現する 方法を見つけようと思い,boot2 や loader などのソース (/usr/src/sys/boot/i386 以下にあります)を読んだりしていますので, うまく実現する方法が見つかりましたら,また報告しようと思っています.
FreeBSD では,ネットワークブートによるディスクレスマシンを作成する場合の ために,/etc/rc.diskless1, /etc/rc.diskless2 というスクリプトがあります. 今回は CD-ROM からのブートですから /etc/rc.diskless1 は不要です. /etc/rc.diskless2 の処理はそのまま流用できるので,/etc/rc.diskless2 を 利用して /var や /dev を作成することにします.
CDBSD のブート時には,以下の作業が必要になります.
リスト3 /etc/rc.cdrom # chkerr: # # Routine to check for error # # checks error code and drops into shell on failure. # if shell exits, terminates script as well as /etc/rc. # chkerr() { case $1 in 0) ;; *) echo "$2 failed: dropping into /bin/sh" /bin/sh # RESUME ;; esac } # Create an MFS /tmp to temporarily hold files from /etc until we # can bootstrap /etc as an MFS. /sbin/mount_mfs -s 4096 -T qp120at dummy /tmp chkerr $? "MFS mount on /tmp" /bin/cp -Rp /etc /tmp chkerr $? "cp /etc to /tmp/etc MFS" /sbin/mount_mfs -s 4096 -T qp120at dummy /etc chkerr $? "MFS mount on /etc" /bin/chmod 755 /etc /bin/cp -Rp /tmp/etc / chkerr $? "cp /tmp/etc to /etc MFS" rm -rf /tmp/etc # Create an MFS /root if [ -d /root ]; then /bin/cp -Rp /root /tmp chkerr $? "cp /root to /tmp/root MFS" /sbin/mount_mfs -s 4096 -T qp120at dummy /root chkerr $? "MFS mount on /root" /bin/chmod 755 /root /bin/cp -Rp /tmp/root / chkerr $? "cp /tmp/root to /root MFS" rm -rf /tmp/root fi # Create an MFS /home if [ -d /home ]; then /bin/cp -Rp /home /tmp chkerr $? "cp /home to /tmp/home MFS" /sbin/mount_mfs -s 4096 -T qp120at dummy /home chkerr $? "MFS mount on /home" /bin/chmod 755 /home /bin/cp -Rp /tmp/home / chkerr $? "cp /tmp/home to /home MFS" rm -rf /tmp/home fi #/sbin/umount /tmp # check FD inserted dd if=/dev/fd0a of=/dev/null count=1 > /dev/null 2>&1 case $? in 0) echo "FD inserted. Now trying to mount FD." if /sbin/mount -t msdos /dev/fd0a /mnt > /dev/null 2>&1 ; then echo "FD mounted as msdosfs" if [ -d /mnt/etc ] ; then echo "Found /etc on FD. Now copying FD to /etc" /bin/cp -Rp /mnt/etc / chkerr $? "cp /etc on FD to /etc MFS" else echo "Not found /etc on FD" fi /sbin/umount /mnt chkerr $? "Unmounted FD" elif /sbin/mount -t ufs /dev/fd0a /mnt > /dev/null 2>&1 ; then echo "FD mounted as ufs" if [ -d /mnt/etc ] ; then echo "Found /etc on FD. Now copying FD to /etc" /bin/cp -Rp /mnt/etc / chkerr $? "cp /etc on FD to /etc MFS" else echo "Not found /etc on FD" fi /sbin/umount /mnt chkerr $? "Unmounted FD" elif /usr/bin/gzip -cd /dev/fd0a > /tmp/fd_etc.tar 2> /dev/null ; then if /usr/bin/tar xf /tmp/fd_etc.tar -C /etc > /dev/null 2>&1 ; then echo "/etc extracted from FD as tar+gzip archive" else echo "FD not tar+gzip format" fi rm -f /tmp/fd_etc.tar elif /usr/bin/tar xf /dev/fd0a -C /etc > /dev/null 2>&1 ; then echo "/etc extracted from FD as tar archive" else echo "Unknown format FD" fi ;; *) echo "No FD inserted" ;; esac # /var, /dev mount by MFS. diskless_mount="/etc/rc.diskless2"
実は リスト3 には,tar と tar+gzip によるアーカイブも 展開できるような処理が入っているのですが,あまりうまく動作しませんでした. 興味のあるかたは試してみてください.
なお,
ぼく
ははじめのうち,FD を union file system で / にマウントするとか,
FDを union file system で /fd あたりにマウントし,/etc -> /fd/etc
のようなリンクを張るなど考えましたが,どちらもうまく起動できませんでした
(/etc をリンクにすることはできなかった).
また,MFS は /md にマウントして,/tmp は /tmp -> /md/tmp のようなリンクにして,
ホームディレクトリとかは /md/home に置くようにしたかったが,これも
うまく起動できませんでした.
(/tmp をリンクにしたら,ifconfig 実行時に OS がフリーズした)
リスト4 /etc/rc の修正(rc.patch) --- rc~ Wed May 30 06:10:20 2001 +++ rc Wed May 30 06:10:24 2001 @@ -52,6 +52,12 @@ PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin export HOME PATH +# for CD-ROM boot. +# +if [ -r /etc/rc.cdrom ]; then + . /etc/rc.cdrom +fi + # BOOTP diskless boot. We have to run the rc file early in order to # retarget various config files. # See /usr/share/examples/diskless/clone_root for details on howオリジナルの /etc/rc はイメージ用 FreeBSD の起動に必要なので,消さないように してください.(後述の /etc/fstab も同様)
root# cd /cdbsd/etc root# mv rc rc.org root# cp rc.org rc root# patch < rc.patch root# mv rc.org rc.orig root# mv rc rc.cdbsd
また,CDBSD の起動時の /var の作成は /cdbsd/etc/rc.diskless2 で行われるの ですが, 標準では /var/log や /var/at が作成されません.そこで /cdbsd/etc/rc.diskless2 の以下の行を修正し,/var/log と /var/at が 作成されるようにします.
var_dirs="run dev db msgs tmp spool spool/mqueue spool/lpd spool/output \ spool/output/lpd" を, var_dirs="run dev db msgs tmp log at at/jobs at/spool spool spool/mqueue spool/lpd spool/output \ spool/output/lpd" に修正.(var_dirs に log, at, at/jobs, at/spool を追加)
リスト5 fstab.cdbsd # Device Mountpoint FStype Options Dump Pass# #/dev/ad1s1b none swap sw 0 0 #/dev/ad1s1a / ufs rw 1 1 #/dev/ad1s1e /usr ufs rw 2 2 #/dev/ad0s2a /fbsd4 ufs rw 0 0 #/dev/ad0s2e /fbsd4/var ufs rw 0 0 #/dev/ad0s2f /fbsd4/usr ufs rw 0 0 #/dev/ad0s3e /fbsd4/home ufs rw 0 0 #/dev/acd0c /cdrom cd9660 ro,noauto 0 0 /dev/acd0c / cd9660 ro 0 0 /dev/fd0a /fd msdos rw,noauto 0 0 /dev/ad0s1 /windows95 msdos rw,noauto 0 0 /dev/ad0s1 /windowsnt ntfs rw,noauto 0 0 proc /proc procfs rw 0 0fstab.cdbsd では SWAP を無効にし,FD や Windows のマウント用のエントリを 追加しています.これらは noauto オプションをつけてあるので,CDBSD の 起動時に勝手にマウントされることはありません.
リスト6 CDBSDのイメージ作成用シェルスクリプト(mkimg.sh) #!/bin/sh cp /cdbsd/etc/fstab.cdbsd /cdbsd/etc/fstab cp /cdbsd/etc/rc.cdbsd /cdbsd/etc/rc rm -fR /cdbsd/tmp/.[A-z]* /cdbsd/tmp/* rm -fR /cdbsd/var/tmp/.[A-z]* /cdbsd/var/tmp/* rm -fR /cdbsd/usr/tmp/.[A-z]* /cdbsd/usr/tmp/* echo -n "" > /cdbsd/root/.history echo -n "" > /cdbsd/usr/home/guest/.history mkisofs -A "CDBSD" -R -J -b boot.flp -c boot.catalog -o /usr/tmp/cdbsd.img /cdbsd cp /cdbsd/etc/fstab.orig /cdbsd/etc/fstab cp /cdbsd/etc/rc.orig /cdbsd/etc/rcmkisofs が /cdrom/etc/master.passwd などを参照する必要があるため,mkimg.sh は root 権限で実行する必要があります.
ISO9660 ファイルシステムを作成したら,まずは ls -l cdbsd.img をして, ファイルサイズが 333000 セクタ × 2048バイト = 681984000 バイト (650MB のメディアの場合)を超えていないことを確認してください.
作成したイメージをマウントして,正しいイメージが作成しているかどうかを 確認します.ブート用の FD のイメージを作成したときと同様に,vnconfig を 利用します.
root# vnconfig -c vn0 /usr/tmp/cdbsd.img root# mount_cd9660 /dev/vn0c /cdrom root# ls /cdrom確認できたら,アンマウントします.
root# cd / root# umount /cdrom root# vnconfig -u vn0
今回は ATAPI の CD-R/RW ドライブを使用しているので,焼き付けには /usr/sbin/burncd を使用します.CD-RW の場合には,はじめに
root# burncd blankで,メディアをクリアします.ドライブを指定したい場合には,-f オプションを 使用します.
root# burncd -f /dev/acd0c blankでは,いよいよ CDBSD のイメージを焼き込みます.
root# burncd -s 4 data /usr/tmp/cdbsd.img fixate-s オプションで焼き込みの速度を指定できるので,ドライブとメディアにあった 適切な速度を指定してください.また,最後の fixate は必ずつけてください. これがないと正常な CD-ROM を作成できません.
/etc/rc.conf などを修正してブートしたいときには,Windows でフォーマットした FD を用意して,FD 上に etc というディレクトリを作成し,そこに差し替えたい rc.conf を置くようにします.CDBSD の起動時に FD を挿入しておけば, FD 上の rc.conf を /etc に上書きコピーして起動します.
最後に,CDBSD を終了させたいときは,
root# umount -aで /windows95 や /fd をアンマウントした後に,
root# shutdown -p now もしくは root# rebootで,終了できます.Windows 領域を忘れずにアンマウントするようにしましょう.
md は FreeBSD-4.0 から追加されました.ソースコード自体は FreeBSD-4.3 まで ほとんど変更されていません.仕組みは NetBSD の md ドライバとほとんど同じで, md の定義を行うとカーネル内に
static u_char mfs_root[MD_ROOT_SIZE*1024] = "MFS Filesystem goes here";のようにして,静的な配列として記憶領域が確保されます (/usr/src/sys/dev/md/md.c 参照). カーネルの作成時に,必要なディレクトリやファイルを ufs のイメージにして, あらかじめ配列 mfs_root[] に格納しておくことにより,カーネルの起動直後に
# mount /dev/md0c /mntのようにして,配列 mfs_root[] 上の ufs のイメージをマウントして読み書き できるようになります.
md の便利な点は,必要なファイルやディレクトリをあらかじめ書き込んでおく ことができるということです.この点は,プロセスとして実装されている MFS と大きく異なっています.(mount_mfs は newfs と同一の実体として 実装されている.詳しくは参考文献[4]参照)
通常のプログラミング方法からいえば,配列 mfs_root[] へのイメージの書き込みは カーネルのコンパイル前に,
static u_char mfs_root[MD_ROOT_SIZE*1024] = { 0x00, 0x01, 0x02, 0x03, ... };のようにして行うべきでしょうが,FreeBSD では write_mfs_in_kernel (/usr/src/release/write_mfs_in_kernel.c) というプログラムを使用することにより,コンパイル後のカーネルに対して イメージを書き込むことができます. 実際に使用するときには,ufs のイメージ root.img を作成して,
> write_mfs_in_kernel kernel root.imgのようにします.write_mfs_in_kernel の詳しい使いかたに関しては, /usr/src/release/Makefile を参照してください.
write_mfs_in_kernel のしくみは簡単です.カーネル内での配列 mfs_root[] の定義を 見ればわかりますが,配列 mfs_root[] の先頭は "MFS Filesystem goes here" という 文字列で初期化されています.write_mfs_in_kernel は kernel をファイルオープン してこの文字列を検索し,見つかったらその部分を先頭として,以降の領域を root.img で書き換えるだけです.
実際に md にファイルシステムを持つカーネルを作成する方法を説明しましょう. まず,カーネルのコンフィグファイルに以下の行を追加して,カーネルを作成します.
pseudo-device md # Memory "disks" options MD_ROOT_SIZE=1440 # MFS size (kB). See sys/dev/md/md.cさらに,以下のようにして ufs のファイルイメージを作成します. root.img のサイズが MD_ROOT_SIZE と一致するように注意してください.
root# cd /usr/tmp root# dd of=root.img if=/dev/zero count=1440 bs=1k root# awk 'BEGIN {printf "%c%c", 85, 170}' | dd of=root.img obs=1 seek=510 conv=notrunc root# vnconfig -s labels -c vn0 root.img root# dd if=/boot/boot1 of=root.img conv=notrunc root# disklabel -rw vn0 auto root# newfs vn0c root# mount /dev/vn0c /mnt root# cp -R /usr/tmp/sample /mnt root# umount /mnt root# vnconfig -u vn0write_mfs_in_kernel を使用して,カーネルに root.img を書き込みます.
root# cd /usr/src/sys/compile/CDBSD root# cp /usr/src/release/write_mfs_in_kernel.c . root# gcc write_mfs_in_kernel.c -o write_mfs_in_kernel root# ./write_mfs_in_kernel kernel /usr/tmp/root.imgこれで,このカーネルを make install し,起動後に,
root# cd /dev root# ./MAKEDEV md0 root# mount /dev/md0c /mntのようにすることにより,カーネルに書き込んだディレクトリ構成が,/mnt に 現れます.
/usr/src/release 以下には,インストーラなどを作成するためのファイルがあります ので,CDBSD を作成する上で多いに参考になっています. また,FreeBSD ハンドブックやFAQ日本語版なども非常に参考になっていますので, 併せて参照するとよいでしょう.