Sometimes it is needed to start an initramfs, perform some actions (system update for example) and then mount your target rootfs. The util-linux package provides special utility switch_root, that simplifies the root changing process. There are at least two flavors of switch_root: one from the util-linux package and a busybox variant. I’ll show the difference later.
The most important part in this case is, that switch_root must be executed with PID 1, hence it must be run within /init script.
Create an initramfs image in Buildroot. Your default output/target/init will look like this:
#!/bin/sh # devtmpfs does not get automounted for initramfs /bin/mount -t devtmpfs devtmpfs /dev exec 0</dev/console exec 1>/dev/console exec 2>/dev/console exec /sbin/init $*
In our use case we will mount a rootfs stored in NAND in a UBIFS partition. So our script for busybox switch_root will look like this:
#!/bin/sh # devtmpfs does not get automounted for initramfs export PATH=/bin:/sbin:/usr/bin:/usr/sbin /bin/mount -t devtmpfs devtmpfs /dev mount -t proc none /proc mount -t sysfs none /sys exec 0</dev/console exec 1>/dev/console exec 2>/dev/console ubiattach -p /dev/mtd5 mount -t ubifs ubi0:rootfs /mnt cd /mnt mount --move /sys /mnt/sys mount --move /proc /mnt/proc mount --move /dev /mnt/dev exec switch_root -c /dev/console /mnt sbin/init
If you prefer to use util-linux switch_root, your script will be simpler because this switch_root flavor will take care of /dev, /proc and /sys itself:
#!/bin/sh # devtmpfs does not get automounted for initramfs export PATH=/bin:/sbin:/usr/bin:/usr/sbin /bin/mount -t devtmpfs devtmpfs /dev mount -t proc none /proc mount -t sysfs none /sys exec 0</dev/console exec 1>/dev/console exec 2>/dev/console ubiattach -p /dev/mtd5 mount -t ubifs ubi0:rootfs /mnt cd /mnt exec switch_root /mnt sbin/init