initramfs切入真实linux文件系统主要用到switch_root命令。
通常initramfs都是为安装最终的根文件系统做准备工作,它的最后一步需要安装最终的根文件系统,然后切换到新根文件系统上去。
以往 的基于ramdisk 的initrd 使用pivot_root命令切换到新的根文件系统,然后卸载ramdisk。但是initramfs是rootfs,而rootfs既不能 pivot_root,也不能umount。
busybox的解决方案是,提供了switch_root命令,完成全部的处理过程,使用起来非常方便。
switch_root命令的格式是:
switch_root [-c /dev/console] NEW_ROOT NEW_INIT [ARGUMENTS_TO_INIT]
switch_root命令必须由PID=1的进程调用,也就是必须由initramfs的init程序直接调用,不能由init派生的其他进程调用,否则会出错,提示: switch_root: not rootfs
也是同样的原因,init脚本调用switch_root命令必须用exec命令调用,否则也会出错,提示: switch_root: not rootfs
下面是个人写的一个init文件,把分区写到命令里了,你可以从“/proc/cmdline”中读取内核参数来找到要切换的分区。
#!/bin/sh #[ expression ] expression为真返回true,否则返回false。-d file FILE exists and is a directory # ||或运算,前面为假运行后面。 #下面一段的意思,没有对应目录创建。 [ -d /dev ] || mkdir -m 0755 /dev [ -d /root ] || mkdir -m 0700 /root [ -d /sys ] || mkdir /sys [ -d /proc ] || mkdir /proc [ -d /tmp ] || mkdir /tmp #----------------------------------- mkdir -p /var/lock echo "mount -t sysfs -o nodev,noexec,nosuid none /sys" mount -t sysfs -o nodev,noexec,nosuid none /sys echo "mount -t proc -o nodev,noexec,nosuid none /proc " mount -t proc -o nodev,noexec,nosuid none /proc # Note that this only becomes /dev on the real filesystem if udev's scripts # are used; which they will be, but it's worth pointing out if ! mount -t devtmpfs -o mode=0755 none /dev; then mount -t tmpfs -o mode=0755 none /dev #echo "mknod -m 0600 /dev/console c 5 1" #mknod -m 0600 /dev/console c 5 1 #mknod /dev/null c 1 3 # Make some basic devices first, let udev handle the rest mknod /dev/null c 1 3 mknod /dev/ptmx c 5 2 mknod /dev/console c 5 1 mknod /dev/kmsg c 1 11 fi mkdir /dev/pts mount -t devpts -o noexec,nosuid,gid=5,mode=0620 none /dev/pts || true mdev -s echo "mount /dev/sda3 /root" mount /dev/sda3 /root echo "switch_root /root /sbin/init " exec switch_root /root /sbin/init