前の記事では新たに初期RAMディスクを作成し、それを経由して新システムを起動することができました。
現状、新システムはハードディスクから起動しています。 ハードディスク上のブートローダが、同じくハードディスク上にあるカーネルと初期RAMディスクをロードすることで起動しています。
ここからは、いよいよ次の段階であるCDからの起動の作業に入ります。 新システム全体をCDに書き込み、さらに、ブートローダもCD上に配置します。
つまり、CD上のブートローダによって、同じくCD上のカーネルと初期RAMディスクが読み込まれ、カーネルがCDをルートファイルシステムとしてマウントすることで起動します。
初期RAMディスクを修正します。 ハードディスクではなく、CDをルートファイルシステムとしてマウントするように修正を加えます。
なお、引き続き、Fedora上でチェンジルートはせずに作業してください。
初期RAMディスクを展開します。 展開する初期RAMディスクのファイルパスは、$MYLINUX/boot/initrd.img-4.0.4 です。 つまり、前の記事で作成した初期RAMディスクを展開するということです。
rm -vfr $MYLINUX/tmp/initrd mkdir -vp $MYLINUX/tmp/initrd pushd $MYLINUX/tmp/initrd zcat $MYLINUX/boot/initrd.img-4.0.4 | cpio -i --make-directories popd
新たに必要になる実行ファイルをコピーします。
cp -va $MYLINUX/bin/sed $MYLINUX/tmp/initrd/bin/
上記のように、sedのみをコピーします。
初期RAMディスク用のinitを作り直します。
cat > $MYLINUX/tmp/initrd/init << "EOF" #!/bin/bash export PATH="/sbin:/bin" echo echo "My Linux initrd" echo mount -t proc proc /proc mount -t sysfs none /sys mount -t devtmpfs none /dev CDROM=`grep -i "drive name" /proc/sys/dev/cdrom/info | sed -e 's/drive name.*[ \t]//'` mount -o ro /dev/$CDROM /newroot umount /sys umount /proc exec /sbin/switch_root /newroot /sbin/init EOF chmod 0755 $MYLINUX/tmp/initrd/init
上記ファイルの変更点について詳しく見てみましょう。
まず、
mount -t proc proc /proc mount -t sysfs none /sys
の2行ですが、これは仮想ファイルシステムである procfs と sysfs をマウントしています。 procfs はカーネルやプロセスに関する情報を提供するための仮想ファイルシステムで、sysfs はカーネルが検出したデバイスに関する情報を提供するための仮想ファイルシステムです。
procfs は、光学ドライブのデバイスファイル名を取得するために使います。
続いての、
CDROM=`grep -i "drive name" /proc/sys/dev/cdrom/info | sed -e 's/drive name.*[ \t]//'`
の処理では、procfs 仮想ファイルシステムから光学ドライブのデバイスファイル名を取得しています。
次の、
mount -o ro /dev/$CDROM /newroot
は、光学ドライブのメディアを /newroot にマウントしています。
さらに、
umount /sys umount /proc
を実行していますが、これは単なる後始末です。
初期RAMディスク作成用のファイルツリーを、初期RAMディスクに戻します。
pushd $MYLINUX/tmp/initrd find . | cpio -R 0:0 -o -H newc | gzip > $MYLINUX/boot/initrd.img-4.0.4 popd
新システムをCDに書き込みます。 書き込む対象は、ルートファイルシステム、カーネル、初期RAMディスク、CD起動用ブートローダです。
CDへの書き込み作業を行うためのディレクトリを作成します。 全ての作業はこのディレクトリ以下で行います。
rm -vfr $MYLINUX/isolinux mkdir -vp $MYLINUX/isolinux mkdir -vp $MYLINUX/isolinux/working mkdir -vp $MYLINUX/isolinux/rootforcdrommount
マウント方式向けの配布用ファイルツリー、つまり、CDに収めるファイル群を準備します。 1CD Linux用のパーティションから、不要なものを除外して複製します。
rsync -av --delete \ --exclude='isolinux/' \ --exclude='lost+found/' \ --exclude='sources/' \ --exclude='backups/' \ --exclude='logs/' \ --exclude='tools/' \ --exclude='lib/cpp' \ --exclude='usr/bin/c++' \ --exclude='usr/bin/cc' \ --exclude='usr/bin/cpp' \ --exclude='usr/bin/g++' \ --exclude='usr/bin/gcc' \ --exclude='usr/bin/gcc-ar' \ --exclude='usr/bin/gcc-nm' \ --exclude='usr/bin/gcc-ranlib' \ --exclude='usr/bin/gcov' \ --exclude='usr/bin/i686-pc-linux-gnu-c++' \ --exclude='usr/bin/i686-pc-linux-gnu-g++' \ --exclude='usr/bin/i686-pc-linux-gnu-gcc' \ --exclude='usr/bin/i686-pc-linux-gnu-gcc-4.9.2' \ --exclude='usr/bin/i686-pc-linux-gnu-gcc-ar' \ --exclude='usr/bin/i686-pc-linux-gnu-gcc-nm' \ --exclude='usr/bin/i686-pc-linux-gnu-gcc-ranlib' \ --exclude='usr/lib/bfd-plugins' \ --exclude='usr/lib/gcc' \ --exclude='usr/lib/*.a' \ --exclude='usr/libexec/gcc' \ --exclude='usr/share/man/' \ --exclude='usr/share/doc/' \ --exclude='usr/share/info/' \ --exclude='usr/include/' \ --exclude='run/*' \ --exclude='root/.bash_history' \ $MYLINUX/ $MYLINUX/isolinux/rootforcdrommount
rsyncで同期することで複製しています。
続いては、SYSLINUXの入手と展開を行います。 なお、SYSLINUXは、Linux向けのブートローダです。
ただし、SYSLINUXは、GRUBのようなハードディスクからの起動用ではありません。 フロッピーディスクやUSBフラッシュメモリ、CD-ROM、ネットワーク等からブートするためのブートローダです。
なお、CDから起動するためのブートローダは、SYSLINUX内のコンポーネントの1つである ISOLINUX です。
ではSYSLINUXの入手と展開を行います。
cd $MYLINUX/isolinux/working wget 'https://www.kernel.org/pub/linux/utils/boot/syslinux/syslinux-6.03.tar.xz' tar xvf syslinux-6.03.tar.xz cp -va syslinux-6.03/bios/core/isolinux.bin $MYLINUX/isolinux/rootforcdrommount/ cp -va syslinux-6.03/bios/com32/elflink/ldlinux/ldlinux.c32 $MYLINUX/isolinux/rootforcdrommount/
SYSLINUXをダウンロードおよび展開し、ISOLINUXおよび依存ファイルのみをマウント方式向けの配布用ファイルツリーに複製しています。
続いて、ブート設定ファイルを作成します。 ブートローダが利用するファイルで、カーネルおよび初期RAMディスクのパスを記述します。
cat > $MYLINUX/isolinux/rootforcdrommount/isolinux.cfg << "EOF" default linux label linux kernel /boot/vmlinuz-4.0.4 append initrd=/boot/initrd.img-4.0.4 EOF
指定するパスはCDに書き込まれた状態での絶対パスです。 ハードディスク上のパスではありませんので、注意してください。
では、ISOイメージを作成します。
mkisofs \ -o $MYLINUX/isolinux/mylinux.iso \ -b isolinux.bin \ -c boot.cat \ -L \ -J \ -R \ -no-emul-boot \ -boot-load-size 4 \ -boot-info-table \ $MYLINUX/isolinux/rootforcdrommount
mkisofs コマンドに渡している各オプションについて以下で説明します。
まず、
-o $MYLINUX/isolinux/mylinux.iso
ですが、これは出力するISOイメージファイルのパスを指定しています。
次の、
-b isolinux.bin
は、ブートローダを指定しています。 この指定により、先頭セクタ ( マスターブートレコード や ブートセクタとも呼ばれる ) に isolinux.bin が書き込まれます。
続いての、
-c boot.cat
は、ブートカタログを boot.cat というファイル名で生成させることを指示しています。 なお、ブートカタログは、mkisofs コマンドによって生成されるものであり、利用者が用意するものではありません。
なお、このオプションは重要であり、この指定がなくては起動可能なCDは作成されません。
最後の、
$MYLINUX/isolinux/rootforcdrommount
は、CDに書き込むトップディレクトリを指定します。 先ほど準備したマウント方式向けの配布用ファイルツリーのトップディレクトリを指定します。
mkisofs コマンドによって作成された $MYLINUX/isolinux/mylinux.iso を、CD-Rに書き込みます。
開発機を実機として用意した場合は、Fedora上のBraseroを使うのがいいと思います。 ISOイメージファイルを右クリックし "Braseroディスク作成ツールで開く" を実行することでCDを作成することができます。
開発機を仮想マシンとして用意した場合は、他のマシンへ転送してからCD-Rに書き込みましょう。 開発機にはSSHでログインできますので、WinSCP等を利用して転送してください。
転送先がWindowsであれば、無償のライティングソフトであるImgBurnを導入するのがよいでしょう。 転送先がLinux系OSならBraseroを使いましょう。
では、起動テストを行います。 作成した起動用CDを光学ドライブにセットし、電源を投入してください。
ただし、今の段階ではシステムは正常には起動できません。 システムの起動が途中で一時的に停止するはずです。
なぜなら、起動用CDがリードオンリーであるため、書き込みができないからです。
上図のようにファイルシステムに書き込みができないことが原因でいくつかのエラーが発生します。 また、起動処理が一時的に停止しています。 なお、しばらく放置していればログイン画面が表示されますので、そのまま数分待ってください。
Linux系OSでは、システムが稼働しているだけで /var /tmp /lib /etc などのディレクトリへの書き込みが発生します。 それらへ書き込めなければ、システムは正常に動作することができません。