初期 RAM ディスク
初期 RAM ディスクとはカーネルがメモリにロードされ実行が始まってから、ブート処理を完了させるためにアクセスが必要なドライバ等を提供する処理を行う。
ブートローダによりカーネルと初期 RAM ディスクがメモリ上にロードされ、カーネルは初期 RAM ディスクを / にマウントし、/init を実行する。
初期 RAM ディスクは以下の 2 通りが存在する。
- initrd: kernel 2.6 以前に使用されていたもので、ファイルシステムをイメージ化して圧縮したもの
- initramfs: kernel 2.6 以降で使用されているもので、ファイル群を cpio 形式でアーカイブしたもの
今回は initramfs に絞って話を進める。
実際に、以下のコマンドによりinitramfs を展開でき、init スクリプトの内容を確認することが可能となる。
$ mkdir /tmp/initramfs
$ sudo cp /boot/initramfs-4.9.38-16.33.amzn1.x86_64.img /tmp/initramfs
$ cd /tmp/initramfs
$ file initramfs-4.9.38-16.33.amzn1.x86_64.img
$ zcat initramfs-4.9.38-16.33.amzn1.x86_64.img | cpio -id
$ ls
bin cmdline dev emergency etc init initqueue initqueue-finished initqueue-settled initqueue-timeout lib lib64 mount netroot pre-mount pre-pivot pre-trigger pre-udev proc sbin sys sysroot tmp usr var
上記の “init” が実行されるスクリプトである。
以下、init スクリプトの概要を示す。
- ディレクトリのマウント
# mount some important things
mount -t proc proc /proc >/dev/null 2>&1
mount -t sysfs sysfs /sys >/dev/null 2>&1
if [ ! -c /dev/ptmx ]; then
# try to mount devtmpfs
if ! mount -t devtmpfs -omode=0755 devtmpfs /dev >/dev/null 2>&1; then
# if it failed fall back to normal tmpfs
mount -t tmpfs -omode=0755 tmpfs /dev >/dev/null 2>&1
# Make some basic devices first, let udev handle the rest
mknod -m 0666 /dev/null c 1 3
mknod -m 0666 /dev/ptmx c 5 2
mknod -m 0600 /dev/console c 5 1
mknod -m 0660 /dev/kmsg c 1 11
fi
fi
...
mount -t devpts -o gid=5,mode=620 devpts /dev/pts >/dev/null 2>&1
mount -t tmpfs tmpfs /dev/shm >/dev/null 2>&1
- コマンドラインオプション root と rootflags、rootfstype の読み込み
{
echo "root='$root'"
echo "rflags='$rflags'"
echo "fstype='$fstype'"
echo "netroot='$netroot'"
echo "NEWROOT='$NEWROOT'"
} > /tmp/root.info
$root などの変数は、codline/*.sh のスクリプトから取得される。
- udevd デーモンの起動
udevd --daemon --resolve-names=never
udevadm trigger --action=add $udevtriggeropts >/dev/null 2>&1
- ルートファイルシステムのマウント
for f in /mount/*.sh; do
[ -f "$f" ] && . "$f"
[ -d "$NEWROOT/proc" ] && break;
done
/mount/*.sh で実際にマウントされる。
/mount/99mount-root.sh
if [ -n "$root" -a -z "${root%%block:*}" ]; then
mount -t ${fstype:-auto} -o "$rflags" "${root#block:}" "$NEWROOT" \
&& ROOTFS_MOUNTED=yes
- udevd デーモンの停止
udevadm control --stop-exec-queue
- ルートファイルシステムの移行
exec switch_root "$NEWROOT" "$INIT" $initargs