Linux Boot Sequence を読む ( 10 ) ~ 初期 RAM ディスク ~

February 19, 2018

初期 RAM ディスク

初期 RAM ディスクとはカーネルがメモリにロードされ実行が始まってから、ブート処理を完了させるためにアクセスが必要なドライバ等を提供する処理を行う。
ブートローダによりカーネルと初期 RAM ディスクがメモリ上にロードされ、カーネルは初期 RAM ディスクを / にマウントし、/init を実行する。
初期 RAM ディスクは以下の 2 通りが存在する。

  1. initrd: kernel 2.6 以前に使用されていたもので、ファイルシステムをイメージ化して圧縮したもの
  2. 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 スクリプトの概要を示す。

  1. ディレクトリのマウント
# 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  
  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 のスクリプトから取得される。

  1. udevd デーモンの起動
udevd --daemon --resolve-names=never  
udevadm trigger --action=add $udevtriggeropts  >/dev/null 2>&1  
  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  
  1. udevd デーモンの停止

udevadm control --stop-exec-queue   
  1. ルートファイルシステムの移行
exec switch_root "$NEWROOT" "$INIT" $initargs  

 © 2023, Dealing with Ambiguity