This document contains some basics about ramfs, rootfs, tmpfs and initramfs.
Backgrounds
-----------
ramfs is a very simple filesystem that exports Linux's disk caching mechanisms
(the page cache and dentry cache) as a dynamically resizable RAM-based
filesystem.
rootfs is special ramfs that the kernel uses at boot time. You can't umount
rootfs for approximately the same reason you can't kill the init process; rather
than having special code to check for and handle an empty list, it's smaller and
simpler for the kernel to just make sure certain lists can't become empty.
The older "ram disk" mechanism created a synthetic block device out of an area
of RAM and used it as backing store for a filesystem.
Disadvantages of ram disk mechanism
-- fixed size
-- unnecessary memory copying process from the fake block device to page cache
-- extra dependency on a filesystem driver to format and interpret its data
One downside of ramfs is you can keep writing data into it until you fill all
memory, and VM can't free it because VM thinks that files should get written
to backing store (rather than the swap space), but ramfs hasn't got any backing
store.
The initramfs is a gzipped cpio archive, which is extracted into rootfs when the
kernel boots up. After extracting, the kernel checks to see if rootfs contains a
file "init", and if so it executes it as PID 1. The init program is responsible
for bringing up the rest of the system, including locating and mounting the real
root device (if any). If the /init needs to hand off control it can overmount /
with a new root device and exec another init program.
Questions & Answers
-------------------
1. Default kernel config value for CONFIG_INITRAMFS_SOURCE is empty. Why?
Because we can use an external initramfs if the kernel has initrd support
enabled. Despite the name of "initrd", the cpio archive which is passed to the
kernel is actually initramfs. The kernel will extract the cpio archive before
trying to run /init. The files in the external cpio archive will overwrite
any confilicting files in the built-in initramfs archive. That's why it's OK
even when the value for CONFIG_INITRAMFS_SOURCE is empty. The empty initramfs
archive is always linked into the resulting kernel binary.
CONFIG_BLK_DEV_INITRD
initial RAM filesystem and RAM disk support (initramfs/initrd)
2. What shared libraries, devices and paths do we need to get a minimal root
filesystem up and running?
kernel
virtual filesystem (sys, proc, dev)
linker
c lib
basic functionality (busybox for example)
basic configuration files (/etc/passwd)
getty and login
3. The necessity of an early userspace
The move to early userspace is necessary because finding and mounting the real
root device is complex. Root partitions can span multiple devices (raid or
separate journal). They can be out on the network (requiring dhcp, setting a
specific MAC address, logging into a server, etc). They can live on removable
media, with dynamically allocated major/minor numbers and persistent naming
issues requiring a full udev implementation to sort out. They can be
compressed, encrypted, copy-on-write, loopback mounted, strangely partitioned,
and so on.
4. How to extract a cpio archive?
cpio -idv < archive
INITRAMFS in YOCTO
------------------
recipe: core-image-minimal-initramfs.bb
IMAGE_FSTYPE = "cpio.gz"
cd ${IMAGE_ROOTFS} && \
(find . | cpio -o -H newc >${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.cpio)
We use eglibc in initramfs images in Yocto instead of klibc or uClibc.
A dummy example of an initramfs
-------------------------------
cat > hello.c << EOF
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
printf("Hello world!\n");
sleep(999999999);
}
EOF
gcc -static hello.c -o init
echo init | cpio -o -H newc | gzip > test.cpio.gz
# Testing external initramfs using the initrd loading mechanism.
qemu -kernel /boot/vmlinuz -initrd test.cpio.gz /dev/zero
Terminology
-----------
ramfs
ram disk
tmpfs
a ramfs derivative which has the ability to limit size an to write data to
swap space
rootfs
in-RAM filesystem
backing store
usually the block device the filesystem is mounted on
dentry cache
greatly speeds up access to directories
initramfs
initrd
early userspace
References
----------
https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt
http://lxr.linux.no/#linux+v3.1/fs/namespace.c#L997
Linux Kernel Documentation: early-userspace/README