前の記事では、初期RAMディスクについて説明しました。 ここからは、実際に初期RAMディスクを作成する作業に入ります。
ただし、最終的な初期RAMディスクはまだ作成しません。 ここでは、今までと同じくハードディスクから起動するための初期RAMディスクを作成します。
ここからの作業は、Fedoraを起動して実施してください。 また、チェンジルートはせずにFedora上で作業してください。
初期RAMディスク作成用のファイルツリーを作成します。 初期RAMディスクのファイルツリーは、$MYLINUX/tmp/initrd 以下に作成します。
rm -vfr $MYLINUX/tmp/initrd mkdir -vp $MYLINUX/tmp/initrd mkdir -vp $MYLINUX/tmp/initrd/sbin mkdir -vp $MYLINUX/tmp/initrd/bin mkdir -vp $MYLINUX/tmp/initrd/lib mkdir -vp $MYLINUX/tmp/initrd/sys mkdir -vp $MYLINUX/tmp/initrd/dev mkdir -vp $MYLINUX/tmp/initrd/proc mkdir -vp $MYLINUX/tmp/initrd/newroot
すでに説明したように、初期RAMディスクは、小さなLinuxシステムです。 その『小さなLinuxシステム』を構成する、必要最低限のディレクトリを準備しています。
次に、実行ファイルをコピーします。 これらは、初期RAMディスク内で実行する様々な処理に必要となるコマンドです。
cp -va $MYLINUX/sbin/switch_root $MYLINUX/tmp/initrd/sbin/ cp -va $MYLINUX/sbin/sysctl $MYLINUX/tmp/initrd/sbin/ cp -va $MYLINUX/bin/bash $MYLINUX/tmp/initrd/bin/ cp -va $MYLINUX/bin/cat $MYLINUX/tmp/initrd/bin/ cp -va $MYLINUX/bin/dmesg $MYLINUX/tmp/initrd/bin/ cp -va $MYLINUX/bin/echo $MYLINUX/tmp/initrd/bin/ cp -va $MYLINUX/bin/grep $MYLINUX/tmp/initrd/bin/ cp -va $MYLINUX/bin/ls $MYLINUX/tmp/initrd/bin/ cp -va $MYLINUX/bin/mount $MYLINUX/tmp/initrd/bin/ cp -va $MYLINUX/bin/ps $MYLINUX/tmp/initrd/bin/ cp -va $MYLINUX/bin/umount $MYLINUX/tmp/initrd/bin/
上記のコマンドは、全てが必要というわけではありません。 エラー発生時にのみ必要となるコマンドも含まれています。
初期RAMディスク内の初期処理でエラーが発生すると、ログインプロンプトの表示まで進まずに、エラーの発生箇所で停止します。 その場合には、エラーの原因を調査する必要がありますが、上記コマンドにはそのためのコマンドも含んでいます。
さらに、共有ライブラリをコピーします。 これらは、実行ファイルから必要とされている共有ライブラリ群です。
cp -va $MYLINUX/lib/ld-linux.so.2 $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/libacl.so.1 $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/libattr.so.1 $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/libblkid.so.1 $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/libc.so.6 $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/libcap.so.2 $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/libdl.so.2 $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/libhistory.so.6 $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/libmount.so.1 $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/libreadline.so.6 $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/libuuid.so.1 $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/usr/lib/libprocps.so.4 $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/ld-2.21.so $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/libacl.so.1.1.0 $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/libattr.so.1.1.0 $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/libblkid.so.1.1.0 $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/libc-2.21.so $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/libcap.so.2.24 $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/libdl-2.21.so $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/libhistory.so.6.3 $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/libmount.so.1.1.0 $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/libreadline.so.6.3 $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/lib/libuuid.so.1.3.0 $MYLINUX/tmp/initrd/lib cp -va $MYLINUX/usr/lib/libprocps.so.4.0.0 $MYLINUX/tmp/initrd/lib
なお、実行ファイルが必要としている共有ライブラリは、ldd コマンドで調べることができます。 以下は実行例です。
[root@localhost ~]# ldd $MYLINUX/bin/bash linux-gate.so.1 (0xb77bd000) libreadline.so.6 => /lib/libreadline.so.6 (0xb7764000) libhistory.so.6 => /lib/libhistory.so.6 (0xb775a000) libdl.so.2 => /lib/libdl.so.2 (0xb7755000) libc.so.6 => /lib/libc.so.6 (0xb7588000) libtinfo.so.5 => /lib/libtinfo.so.5 (0xb7564000) /lib/ld-linux.so.2 (0xb77be000) [root@localhost ~]#
デバイスファイルを作成します。 最低限必要となる /dev/console および /dev/null を作成します。
mknod -m 0600 $MYLINUX/tmp/initrd/dev/console c 5 1 mknod -m 0666 $MYLINUX/tmp/initrd/dev/null c 1 3
初期RAMディスク用のinitを作成します。 このファイルはカーネルによって呼び出されるもので、初期処理を行うために使用します。
cat > $MYLINUX/tmp/initrd/init << "EOF" #!/bin/bash export PATH="/sbin:/bin" echo echo "My Linux initrd" echo mount -t devtmpfs none /dev mount -o ro /dev/<@デバイス名@> /newroot exec /sbin/switch_root /newroot /sbin/init EOF chmod 0755 $MYLINUX/tmp/initrd/init
上記ファイルの処理内容について詳しく見てみましょう。
まず、
export PATH="/sbin:/bin"
については、説明するまでもなく実行ファイルを検索するパスを通すための処理です。
続いての、
echo echo "My Linux initrd" echo
の3行については、"My Linux initrd"というメッセージを表示しているだけです。 おそらくこのメッセージは、/initスクリプトがエラーで停止した場合にしか見えないでしょう。
続いて実行している、
mount -t devtmpfs none /dev
の処理では、/dev に仮想ファイルシステム devtmpfs をマウントしています。 devtmpfs は procfs や sysfs と同じく仮想ファイルシステムであり、カーネルによって検出されたデバイスに対応するデバイスファイルが作成されます。
つまり、/dev 以下には、カーネルによって検出されたデバイスのデバイスファイルが自動的に作成されるようになります。
次の、
mount -o ro /dev/<@デバイス名@> /newroot
の処理では、1CD Linux用のパーティションを /newroot にマウントしています。 なお、デバイスファイルである /dev/<@デバイス名@> が存在するのは、devtmpfs のおかげです。
最後の、
exec /sbin/switch_root /newroot /sbin/init
は、スイッチルートの処理です。 スイッチルートは、ルートファイルシステムを切り替えるためのコマンドです。
この処理により /newroot が新たなルートファイルシステムとなり、さらに /sbin/init が呼ばれます。
初期RAMディスク作成用のファイルツリーを、初期RAMディスクにアーカイブします。 つまり、1つのファイルにまとめます。
pushd $MYLINUX/tmp/initrd find . | cpio -R 0:0 -o -H newc | gzip > $MYLINUX/boot/initrd.img-4.0.4 popd
以下のように書き込まれたブロック数が表示されます。
[root@localhost ~]# pushd $MYLINUX/tmp/initrd /mylinux/tmp/initrd ~ [root@localhost initrd]# find . | cpio -R 0:0 -o -H newc | gzip > $MYLINUX/boot/initrd.img-4.0.4 9888 blocks [root@localhost initrd]# popd ~ [root@localhost ~]#
開発機のブートローダが、作成した新システムの起動時に初期RAMディスクをロードするようにします。
grub2-mkconfig -o /boot/grub2/grub.cfg
以下のように "unknown Linux distribution" が認識されることを確認します。
Found linux image: /boot/vmlinuz-4.2.3-300.fc23.i686 Found initrd image: /boot/initramfs-4.2.3-300.fc23.i686.img Found linux image: /boot/vmlinuz-0-rescue-e0c29f9903d9415db6032f825c9fe336 Found initrd image: /boot/initramfs-0-rescue-e0c29f9903d9415db6032f825c9fe336.img Found unknown Linux distribution on /dev/sda3
さらに、生成されたGRUBの設定ファイル ( /boot/grub2/grub.cfg ) の中身も確認してみましょう。
...(省略)... ### BEGIN /etc/grub.d/30_os-prober ### menuentry 'unknown Linux distribution (on /dev/sda3)' --class gnu-linux --class gnu --class os $menuentry_id_option 'osprober-gnulinux-simple-5067082b-153 insmod part_msdos insmod ext2 set root='hd0,msdos3' if [ x$feature_platform_search_hint = xy ]; then search --no-floppy --fs-uuid --set=root --hint-ieee1275='ieee1275//disk@0,msdos3' --hint-bios=hd0,msdos3 --hint-efi=hd0,msdos3 --hint-baremetal= else search --no-floppy --fs-uuid --set=root 5067082b-153a-407c-b806-eda263a7e1bd fi linux /boot/vmlinuz-4.0.4 root=/dev/sda3 initrd /boot/initrd.img-4.0.4 } ...(省略)...
上記のように "initrd /boot/initrd.img-4.0.4" という行が含まれることを確認します。
では、起動テストを行います。 新システムを起動してrootでログインし、最小システムの構築 > 新システムの起動と動作テスト - 新システムの動作テスト -と同じ手順でテストを実施してください。