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 サーバを自由に選択できるようにしたいので,
以下のようにリンクを張りなおしておきます.
まずは vipw でパスワードを修正します.
さらに,/etc 以下のファイル(主に /etc/rc.conf など)を適切に修正します.
これが CDBSD 起動時のデフォルトの設定になります.ただし /etc/fstab は
後で修正するので,ここで CDBSD 用の修正をする必要はありません.
(/etc/fstab をへんに修正すると,イメージ用 FreeBSD が起動できなくなって
しまいますので...)
FreeBSD では vnconfig の機能を使用して,イメージファイルをマウントすることが
できます.(Linux の loopback filesystem に相当するものです)
さらに,イメージ用 FreeBSD のカーネルを boot.flp 上にコピーします.
FreeBSD では,ネットワークブートによるディスクレスマシンを作成する場合の
ために,/etc/rc.diskless1, /etc/rc.diskless2 というスクリプトがあります.
今回は CD-ROM からのブートですから /etc/rc.diskless1 は不要です.
/etc/rc.diskless2 の処理はそのまま流用できるので,/etc/rc.diskless2 を
利用して /var や /dev を作成することにします.
CDBSD のブート時には,以下の作業が必要になります.
実は リスト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 がフリーズした)
また,CDBSD の起動時の /var の作成は /cdbsd/etc/rc.diskless2 で行われるの
ですが,
標準では /var/log や /var/at が作成されません.そこで
/cdbsd/etc/rc.diskless2 の以下の行を修正し,/var/log と /var/at が
作成されるようにします.
ISO9660 ファイルシステムを作成したら,まずは ls -l cdbsd.img をして,
ファイルサイズが 333000 セクタ × 2048バイト = 681984000 バイト
(650MB のメディアの場合)を超えていないことを確認してください.
作成したイメージをマウントして,正しいイメージが作成しているかどうかを
確認します.ブート用の FD のイメージを作成したときと同様に,vnconfig を
利用します.
今回は ATAPI の CD-R/RW ドライブを使用しているので,焼き付けには
/usr/sbin/burncd を使用します.CD-RW の場合には,はじめに
/etc/rc.conf などを修正してブートしたいときには,Windows でフォーマットした
FD を用意して,FD 上に etc というディレクトリを作成し,そこに差し替えたい
rc.conf を置くようにします.CDBSD の起動時に FD を挿入しておけば,
FD 上の rc.conf を /etc に上書きコピーして起動します.
最後に,CDBSD を終了させたいときは,
md は FreeBSD-4.0 から追加されました.ソースコード自体は FreeBSD-4.3 まで
ほとんど変更されていません.仕組みは NetBSD の md ドライバとほとんど同じで,
md の定義を行うとカーネル内に
md の便利な点は,必要なファイルやディレクトリをあらかじめ書き込んでおく
ことができるということです.この点は,プロセスとして実装されている
MFS と大きく異なっています.(mount_mfs は newfs と同一の実体として
実装されている.詳しくは参考文献[4]参照)
通常のプログラミング方法からいえば,配列 mfs_root[] へのイメージの書き込みは
カーネルのコンパイル前に,
write_mfs_in_kernel のしくみは簡単です.カーネル内での配列 mfs_root[] の定義を
見ればわかりますが,配列 mfs_root[] の先頭は "MFS Filesystem goes here" という
文字列で初期化されています.write_mfs_in_kernel は kernel をファイルオープン
してこの文字列を検索し,見つかったらその部分を先頭として,以降の領域を
root.img で書き換えるだけです.
実際に md にファイルシステムを持つカーネルを作成する方法を説明しましょう.
まず,カーネルのコンフィグファイルに以下の行を追加して,カーネルを作成します.
/usr/src/release 以下には,インストーラなどを作成するためのファイルがあります
ので,CDBSD を作成する上で多いに参考になっています.
また,FreeBSD ハンドブックやFAQ日本語版なども非常に参考になっていますので,
併せて参照するとよいでしょう.
4.2 Xの設定
設定後に startx をして,ちゃんと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 にマウントして中身を見るときのために,
すべて相対リンクにします.
4.3 /etc の修正
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 コマンドで設定して
おいてください.
4.4 dot ファイルの作成
root# ln -s ../README /root/README
root# su guest
guest> cd /home/guest
guest> ln -s ../../README /home/guest/README
のようなリンクを張っておくといいでしょう.
/root と /home は CDBSD の起動時に MFS でマウントされるので,
あまり巨大なファイルを置いたり,たくさんのファイルを置いたりしないように
注意してください.
4.5 /usr/tmp の修正とリンクの張りかえ
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
のようにして,絶対リンクを相対リンクに張りかえておくといいでしょう.
4.6 マウントポイントの作成
root# mkdir /fd /mnt2 /mnt3 /mnt4 /work /work2
root# mkdir /windows95 /windowsnt
root# chmod 777 /windows95 /windowsnt
のようにして,マウントポイントを多めに作成しておきます.
/windows95, /windowsnt は HDD 上の Windows パーティションのマウント用の
ためのものなので,属性を書き込み可にしておきます.
4.7 カーネルの作成
device pcm0 at isa? irq 5 drq 1 flags 0x0
device pca0 at isa? port IO_TIMER1
を追加.
4.8 スペシャルファイルの作成
root# ./MAKEDEV snd0
root# ./MAKEDEV ad0s1 ad0s2 ad0s3 ad0s4 ad1s1 ad1s2 ad1s3 ad1s4
root# ./MAKEDEV ad0s1a ad0s2a ad0s3a ad0s4a ad1s1a ad1s2a ad1s3a ad1s4a
などをして,必要なデバイスを作成しておきます.
4.9 mkfsrw.sh の作成
リスト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)"
fi
mkrwfs.sh は,CDBSD の起動後に,
root# mkrwfs.sh /usr/local/etc
のようにして使用します.指定したディレクトリを MFS でマウントしなおし,
既存のファイルやディレクトリをコピーします.ディレクトリは絶対パスでも
相対パスでも指定できます.
4.10 パッケージのインストール
5 イメージの作成
root# mkdir /cdbsd
root# mount /dev/ad1s1a /cdbsd
root# mount /dev/ad1s1e /cdbsd/usr
のようにして,イメージ用 FreeBSD のパーティションを /cdbsd にマウント
してください.
5.1 ブート用のイメージの作成
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
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 以下にあります)を読んだりしていますので,
うまく実現する方法が見つかりましたら,また報告しようと思っています.
5.2 /etc/rc.cdrom の作成
これらの作業を /etc/rc.cdrom (リスト3) にまとめ,起動時に
自動で行われるようにします.
/etc/rc.cdrom では,FD のチェック時に,msdos ファイルシステム,ufs を順次
チェックしますので,FD はどちらのファイルシステムになっていても構いません.
リスト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"
5.3 /etc/rc の修正
リスト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
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.4 /etc/fstabの修正
リスト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 0
fstab.cdbsd では SWAP を無効にし,FD や Windows のマウント用のエントリを
追加しています.これらは noauto オプションをつけてあるので,CDBSD の
起動時に勝手にマウントされることはありません.
6 CD-R への焼き込み
6.1 ISO9660イメージの作成
リスト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/rc
mkisofs が /cdrom/etc/master.passwd などを参照する必要があるため,mkimg.sh は
root 権限で実行する必要があります.
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
6.2 イメージの焼き込み
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 を作成できません.
7 起動
root# umount -a
で /windows95 や /fd をアンマウントした後に,
root# shutdown -p now
もしくは
root# reboot
で,終了できます.Windows 領域を忘れずにアンマウントするようにしましょう.
8 おわりに
コラム - md の利用
今回のような書き込みのできないメディアからブートさせたい場合には,
記憶メディア上でなく,カーネルの内部にあらかじめ内容を持ったディレクトリを
保持させておくと便利なことがあります.そのような場合には,md (Memory Disk)
ドライバが利用できます.
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 のイメージをマウントして読み書き
できるようになります.
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 を参照してください.
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 vn0
write_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 に
現れます.
ファイルのダウンロード
mkrwfs.sh
ブート用FDの /etc/fstab の例
/etc/rc.cdrom
/etc/rc の修正(rc.patch)
fstab.cdbsd
CDBSDのイメージ作成用シェルスクリプト(mkimg.sh)
参考文献