18c2ecf20Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci===========================
48c2ecf20Sopenharmony_ciRamfs, rootfs and initramfs
58c2ecf20Sopenharmony_ci===========================
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ciOctober 17, 2005
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ciRob Landley <rob@landley.net>
108c2ecf20Sopenharmony_ci=============================
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ciWhat is ramfs?
138c2ecf20Sopenharmony_ci--------------
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ciRamfs is a very simple filesystem that exports Linux's disk caching
168c2ecf20Sopenharmony_cimechanisms (the page cache and dentry cache) as a dynamically resizable
178c2ecf20Sopenharmony_ciRAM-based filesystem.
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ciNormally all files are cached in memory by Linux.  Pages of data read from
208c2ecf20Sopenharmony_cibacking store (usually the block device the filesystem is mounted on) are kept
218c2ecf20Sopenharmony_ciaround in case it's needed again, but marked as clean (freeable) in case the
228c2ecf20Sopenharmony_ciVirtual Memory system needs the memory for something else.  Similarly, data
238c2ecf20Sopenharmony_ciwritten to files is marked clean as soon as it has been written to backing
248c2ecf20Sopenharmony_cistore, but kept around for caching purposes until the VM reallocates the
258c2ecf20Sopenharmony_cimemory.  A similar mechanism (the dentry cache) greatly speeds up access to
268c2ecf20Sopenharmony_cidirectories.
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ciWith ramfs, there is no backing store.  Files written into ramfs allocate
298c2ecf20Sopenharmony_cidentries and page cache as usual, but there's nowhere to write them to.
308c2ecf20Sopenharmony_ciThis means the pages are never marked clean, so they can't be freed by the
318c2ecf20Sopenharmony_ciVM when it's looking to recycle memory.
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ciThe amount of code required to implement ramfs is tiny, because all the
348c2ecf20Sopenharmony_ciwork is done by the existing Linux caching infrastructure.  Basically,
358c2ecf20Sopenharmony_ciyou're mounting the disk cache as a filesystem.  Because of this, ramfs is not
368c2ecf20Sopenharmony_cian optional component removable via menuconfig, since there would be negligible
378c2ecf20Sopenharmony_cispace savings.
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ciramfs and ramdisk:
408c2ecf20Sopenharmony_ci------------------
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ciThe older "ram disk" mechanism created a synthetic block device out of
438c2ecf20Sopenharmony_cian area of RAM and used it as backing store for a filesystem.  This block
448c2ecf20Sopenharmony_cidevice was of fixed size, so the filesystem mounted on it was of fixed
458c2ecf20Sopenharmony_cisize.  Using a ram disk also required unnecessarily copying memory from the
468c2ecf20Sopenharmony_cifake block device into the page cache (and copying changes back out), as well
478c2ecf20Sopenharmony_cias creating and destroying dentries.  Plus it needed a filesystem driver
488c2ecf20Sopenharmony_ci(such as ext2) to format and interpret this data.
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ciCompared to ramfs, this wastes memory (and memory bus bandwidth), creates
518c2ecf20Sopenharmony_ciunnecessary work for the CPU, and pollutes the CPU caches.  (There are tricks
528c2ecf20Sopenharmony_cito avoid this copying by playing with the page tables, but they're unpleasantly
538c2ecf20Sopenharmony_cicomplicated and turn out to be about as expensive as the copying anyway.)
548c2ecf20Sopenharmony_ciMore to the point, all the work ramfs is doing has to happen _anyway_,
558c2ecf20Sopenharmony_cisince all file access goes through the page and dentry caches.  The RAM
568c2ecf20Sopenharmony_cidisk is simply unnecessary; ramfs is internally much simpler.
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ciAnother reason ramdisks are semi-obsolete is that the introduction of
598c2ecf20Sopenharmony_ciloopback devices offered a more flexible and convenient way to create
608c2ecf20Sopenharmony_cisynthetic block devices, now from files instead of from chunks of memory.
618c2ecf20Sopenharmony_ciSee losetup (8) for details.
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ciramfs and tmpfs:
648c2ecf20Sopenharmony_ci----------------
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ciOne downside of ramfs is you can keep writing data into it until you fill
678c2ecf20Sopenharmony_ciup all memory, and the VM can't free it because the VM thinks that files
688c2ecf20Sopenharmony_cishould get written to backing store (rather than swap space), but ramfs hasn't
698c2ecf20Sopenharmony_cigot any backing store.  Because of this, only root (or a trusted user) should
708c2ecf20Sopenharmony_cibe allowed write access to a ramfs mount.
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ciA ramfs derivative called tmpfs was created to add size limits, and the ability
738c2ecf20Sopenharmony_cito write the data to swap space.  Normal users can be allowed write access to
748c2ecf20Sopenharmony_citmpfs mounts.  See Documentation/filesystems/tmpfs.rst for more information.
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ciWhat is rootfs?
778c2ecf20Sopenharmony_ci---------------
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ciRootfs is a special instance of ramfs (or tmpfs, if that's enabled), which is
808c2ecf20Sopenharmony_cialways present in 2.6 systems.  You can't unmount rootfs for approximately the
818c2ecf20Sopenharmony_cisame reason you can't kill the init process; rather than having special code
828c2ecf20Sopenharmony_cito check for and handle an empty list, it's smaller and simpler for the kernel
838c2ecf20Sopenharmony_cito just make sure certain lists can't become empty.
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ciMost systems just mount another filesystem over rootfs and ignore it.  The
868c2ecf20Sopenharmony_ciamount of space an empty instance of ramfs takes up is tiny.
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ciIf CONFIG_TMPFS is enabled, rootfs will use tmpfs instead of ramfs by
898c2ecf20Sopenharmony_cidefault.  To force ramfs, add "rootfstype=ramfs" to the kernel command
908c2ecf20Sopenharmony_ciline.
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ciWhat is initramfs?
938c2ecf20Sopenharmony_ci------------------
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ciAll 2.6 Linux kernels contain a gzipped "cpio" format archive, which is
968c2ecf20Sopenharmony_ciextracted into rootfs when the kernel boots up.  After extracting, the kernel
978c2ecf20Sopenharmony_cichecks to see if rootfs contains a file "init", and if so it executes it as PID
988c2ecf20Sopenharmony_ci1.  If found, this init process is responsible for bringing the system the
998c2ecf20Sopenharmony_cirest of the way up, including locating and mounting the real root device (if
1008c2ecf20Sopenharmony_ciany).  If rootfs does not contain an init program after the embedded cpio
1018c2ecf20Sopenharmony_ciarchive is extracted into it, the kernel will fall through to the older code
1028c2ecf20Sopenharmony_cito locate and mount a root partition, then exec some variant of /sbin/init
1038c2ecf20Sopenharmony_ciout of that.
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ciAll this differs from the old initrd in several ways:
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci  - The old initrd was always a separate file, while the initramfs archive is
1088c2ecf20Sopenharmony_ci    linked into the linux kernel image.  (The directory ``linux-*/usr`` is
1098c2ecf20Sopenharmony_ci    devoted to generating this archive during the build.)
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci  - The old initrd file was a gzipped filesystem image (in some file format,
1128c2ecf20Sopenharmony_ci    such as ext2, that needed a driver built into the kernel), while the new
1138c2ecf20Sopenharmony_ci    initramfs archive is a gzipped cpio archive (like tar only simpler,
1148c2ecf20Sopenharmony_ci    see cpio(1) and Documentation/driver-api/early-userspace/buffer-format.rst).
1158c2ecf20Sopenharmony_ci    The kernel's cpio extraction code is not only extremely small, it's also
1168c2ecf20Sopenharmony_ci    __init text and data that can be discarded during the boot process.
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci  - The program run by the old initrd (which was called /initrd, not /init) did
1198c2ecf20Sopenharmony_ci    some setup and then returned to the kernel, while the init program from
1208c2ecf20Sopenharmony_ci    initramfs is not expected to return to the kernel.  (If /init needs to hand
1218c2ecf20Sopenharmony_ci    off control it can overmount / with a new root device and exec another init
1228c2ecf20Sopenharmony_ci    program.  See the switch_root utility, below.)
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci  - When switching another root device, initrd would pivot_root and then
1258c2ecf20Sopenharmony_ci    umount the ramdisk.  But initramfs is rootfs: you can neither pivot_root
1268c2ecf20Sopenharmony_ci    rootfs, nor unmount it.  Instead delete everything out of rootfs to
1278c2ecf20Sopenharmony_ci    free up the space (find -xdev / -exec rm '{}' ';'), overmount rootfs
1288c2ecf20Sopenharmony_ci    with the new root (cd /newmount; mount --move . /; chroot .), attach
1298c2ecf20Sopenharmony_ci    stdin/stdout/stderr to the new /dev/console, and exec the new init.
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci    Since this is a remarkably persnickety process (and involves deleting
1328c2ecf20Sopenharmony_ci    commands before you can run them), the klibc package introduced a helper
1338c2ecf20Sopenharmony_ci    program (utils/run_init.c) to do all this for you.  Most other packages
1348c2ecf20Sopenharmony_ci    (such as busybox) have named this command "switch_root".
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ciPopulating initramfs:
1378c2ecf20Sopenharmony_ci---------------------
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ciThe 2.6 kernel build process always creates a gzipped cpio format initramfs
1408c2ecf20Sopenharmony_ciarchive and links it into the resulting kernel binary.  By default, this
1418c2ecf20Sopenharmony_ciarchive is empty (consuming 134 bytes on x86).
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ciThe config option CONFIG_INITRAMFS_SOURCE (in General Setup in menuconfig,
1448c2ecf20Sopenharmony_ciand living in usr/Kconfig) can be used to specify a source for the
1458c2ecf20Sopenharmony_ciinitramfs archive, which will automatically be incorporated into the
1468c2ecf20Sopenharmony_ciresulting binary.  This option can point to an existing gzipped cpio
1478c2ecf20Sopenharmony_ciarchive, a directory containing files to be archived, or a text file
1488c2ecf20Sopenharmony_cispecification such as the following example::
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci  dir /dev 755 0 0
1518c2ecf20Sopenharmony_ci  nod /dev/console 644 0 0 c 5 1
1528c2ecf20Sopenharmony_ci  nod /dev/loop0 644 0 0 b 7 0
1538c2ecf20Sopenharmony_ci  dir /bin 755 1000 1000
1548c2ecf20Sopenharmony_ci  slink /bin/sh busybox 777 0 0
1558c2ecf20Sopenharmony_ci  file /bin/busybox initramfs/busybox 755 0 0
1568c2ecf20Sopenharmony_ci  dir /proc 755 0 0
1578c2ecf20Sopenharmony_ci  dir /sys 755 0 0
1588c2ecf20Sopenharmony_ci  dir /mnt 755 0 0
1598c2ecf20Sopenharmony_ci  file /init initramfs/init.sh 755 0 0
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ciRun "usr/gen_init_cpio" (after the kernel build) to get a usage message
1628c2ecf20Sopenharmony_cidocumenting the above file format.
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ciOne advantage of the configuration file is that root access is not required to
1658c2ecf20Sopenharmony_ciset permissions or create device nodes in the new archive.  (Note that those
1668c2ecf20Sopenharmony_citwo example "file" entries expect to find files named "init.sh" and "busybox" in
1678c2ecf20Sopenharmony_cia directory called "initramfs", under the linux-2.6.* directory.  See
1688c2ecf20Sopenharmony_ciDocumentation/driver-api/early-userspace/early_userspace_support.rst for more details.)
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ciThe kernel does not depend on external cpio tools.  If you specify a
1718c2ecf20Sopenharmony_cidirectory instead of a configuration file, the kernel's build infrastructure
1728c2ecf20Sopenharmony_cicreates a configuration file from that directory (usr/Makefile calls
1738c2ecf20Sopenharmony_ciusr/gen_initramfs.sh), and proceeds to package up that directory
1748c2ecf20Sopenharmony_ciusing the config file (by feeding it to usr/gen_init_cpio, which is created
1758c2ecf20Sopenharmony_cifrom usr/gen_init_cpio.c).  The kernel's build-time cpio creation code is
1768c2ecf20Sopenharmony_cientirely self-contained, and the kernel's boot-time extractor is also
1778c2ecf20Sopenharmony_ci(obviously) self-contained.
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ciThe one thing you might need external cpio utilities installed for is creating
1808c2ecf20Sopenharmony_cior extracting your own preprepared cpio files to feed to the kernel build
1818c2ecf20Sopenharmony_ci(instead of a config file or directory).
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_ciThe following command line can extract a cpio image (either by the above script
1848c2ecf20Sopenharmony_cior by the kernel build) back into its component files::
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci  cpio -i -d -H newc -F initramfs_data.cpio --no-absolute-filenames
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ciThe following shell script can create a prebuilt cpio archive you can
1898c2ecf20Sopenharmony_ciuse in place of the above config file::
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci  #!/bin/sh
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci  # Copyright 2006 Rob Landley <rob@landley.net> and TimeSys Corporation.
1948c2ecf20Sopenharmony_ci  # Licensed under GPL version 2
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci  if [ $# -ne 2 ]
1978c2ecf20Sopenharmony_ci  then
1988c2ecf20Sopenharmony_ci    echo "usage: mkinitramfs directory imagename.cpio.gz"
1998c2ecf20Sopenharmony_ci    exit 1
2008c2ecf20Sopenharmony_ci  fi
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci  if [ -d "$1" ]
2038c2ecf20Sopenharmony_ci  then
2048c2ecf20Sopenharmony_ci    echo "creating $2 from $1"
2058c2ecf20Sopenharmony_ci    (cd "$1"; find . | cpio -o -H newc | gzip) > "$2"
2068c2ecf20Sopenharmony_ci  else
2078c2ecf20Sopenharmony_ci    echo "First argument must be a directory"
2088c2ecf20Sopenharmony_ci    exit 1
2098c2ecf20Sopenharmony_ci  fi
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci.. Note::
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci   The cpio man page contains some bad advice that will break your initramfs
2148c2ecf20Sopenharmony_ci   archive if you follow it.  It says "A typical way to generate the list
2158c2ecf20Sopenharmony_ci   of filenames is with the find command; you should give find the -depth
2168c2ecf20Sopenharmony_ci   option to minimize problems with permissions on directories that are
2178c2ecf20Sopenharmony_ci   unwritable or not searchable."  Don't do this when creating
2188c2ecf20Sopenharmony_ci   initramfs.cpio.gz images, it won't work.  The Linux kernel cpio extractor
2198c2ecf20Sopenharmony_ci   won't create files in a directory that doesn't exist, so the directory
2208c2ecf20Sopenharmony_ci   entries must go before the files that go in those directories.
2218c2ecf20Sopenharmony_ci   The above script gets them in the right order.
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_ciExternal initramfs images:
2248c2ecf20Sopenharmony_ci--------------------------
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_ciIf the kernel has initrd support enabled, an external cpio.gz archive can also
2278c2ecf20Sopenharmony_cibe passed into a 2.6 kernel in place of an initrd.  In this case, the kernel
2288c2ecf20Sopenharmony_ciwill autodetect the type (initramfs, not initrd) and extract the external cpio
2298c2ecf20Sopenharmony_ciarchive into rootfs before trying to run /init.
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ciThis has the memory efficiency advantages of initramfs (no ramdisk block
2328c2ecf20Sopenharmony_cidevice) but the separate packaging of initrd (which is nice if you have
2338c2ecf20Sopenharmony_cinon-GPL code you'd like to run from initramfs, without conflating it with
2348c2ecf20Sopenharmony_cithe GPL licensed Linux kernel binary).
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_ciIt can also be used to supplement the kernel's built-in initramfs image.  The
2378c2ecf20Sopenharmony_cifiles in the external archive will overwrite any conflicting files in
2388c2ecf20Sopenharmony_cithe built-in initramfs archive.  Some distributors also prefer to customize
2398c2ecf20Sopenharmony_cia single kernel image with task-specific initramfs images, without recompiling.
2408c2ecf20Sopenharmony_ci
2418c2ecf20Sopenharmony_ciContents of initramfs:
2428c2ecf20Sopenharmony_ci----------------------
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ciAn initramfs archive is a complete self-contained root filesystem for Linux.
2458c2ecf20Sopenharmony_ciIf you don't already understand what shared libraries, devices, and paths
2468c2ecf20Sopenharmony_ciyou need to get a minimal root filesystem up and running, here are some
2478c2ecf20Sopenharmony_cireferences:
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ci- https://www.tldp.org/HOWTO/Bootdisk-HOWTO/
2508c2ecf20Sopenharmony_ci- https://www.tldp.org/HOWTO/From-PowerUp-To-Bash-Prompt-HOWTO.html
2518c2ecf20Sopenharmony_ci- http://www.linuxfromscratch.org/lfs/view/stable/
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ciThe "klibc" package (https://www.kernel.org/pub/linux/libs/klibc) is
2548c2ecf20Sopenharmony_cidesigned to be a tiny C library to statically link early userspace
2558c2ecf20Sopenharmony_cicode against, along with some related utilities.  It is BSD licensed.
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_ciI use uClibc (https://www.uclibc.org) and busybox (https://www.busybox.net)
2588c2ecf20Sopenharmony_cimyself.  These are LGPL and GPL, respectively.  (A self-contained initramfs
2598c2ecf20Sopenharmony_cipackage is planned for the busybox 1.3 release.)
2608c2ecf20Sopenharmony_ci
2618c2ecf20Sopenharmony_ciIn theory you could use glibc, but that's not well suited for small embedded
2628c2ecf20Sopenharmony_ciuses like this.  (A "hello world" program statically linked against glibc is
2638c2ecf20Sopenharmony_ciover 400k.  With uClibc it's 7k.  Also note that glibc dlopens libnss to do
2648c2ecf20Sopenharmony_ciname lookups, even when otherwise statically linked.)
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_ciA good first step is to get initramfs to run a statically linked "hello world"
2678c2ecf20Sopenharmony_ciprogram as init, and test it under an emulator like qemu (www.qemu.org) or
2688c2ecf20Sopenharmony_ciUser Mode Linux, like so::
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_ci  cat > hello.c << EOF
2718c2ecf20Sopenharmony_ci  #include <stdio.h>
2728c2ecf20Sopenharmony_ci  #include <unistd.h>
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_ci  int main(int argc, char *argv[])
2758c2ecf20Sopenharmony_ci  {
2768c2ecf20Sopenharmony_ci    printf("Hello world!\n");
2778c2ecf20Sopenharmony_ci    sleep(999999999);
2788c2ecf20Sopenharmony_ci  }
2798c2ecf20Sopenharmony_ci  EOF
2808c2ecf20Sopenharmony_ci  gcc -static hello.c -o init
2818c2ecf20Sopenharmony_ci  echo init | cpio -o -H newc | gzip > test.cpio.gz
2828c2ecf20Sopenharmony_ci  # Testing external initramfs using the initrd loading mechanism.
2838c2ecf20Sopenharmony_ci  qemu -kernel /boot/vmlinuz -initrd test.cpio.gz /dev/zero
2848c2ecf20Sopenharmony_ci
2858c2ecf20Sopenharmony_ciWhen debugging a normal root filesystem, it's nice to be able to boot with
2868c2ecf20Sopenharmony_ci"init=/bin/sh".  The initramfs equivalent is "rdinit=/bin/sh", and it's
2878c2ecf20Sopenharmony_cijust as useful.
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_ciWhy cpio rather than tar?
2908c2ecf20Sopenharmony_ci-------------------------
2918c2ecf20Sopenharmony_ci
2928c2ecf20Sopenharmony_ciThis decision was made back in December, 2001.  The discussion started here:
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_ci  http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1538.html
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_ciAnd spawned a second thread (specifically on tar vs cpio), starting here:
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci  http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1587.html
2998c2ecf20Sopenharmony_ci
3008c2ecf20Sopenharmony_ciThe quick and dirty summary version (which is no substitute for reading
3018c2ecf20Sopenharmony_cithe above threads) is:
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci1) cpio is a standard.  It's decades old (from the AT&T days), and already
3048c2ecf20Sopenharmony_ci   widely used on Linux (inside RPM, Red Hat's device driver disks).  Here's
3058c2ecf20Sopenharmony_ci   a Linux Journal article about it from 1996:
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_ci      http://www.linuxjournal.com/article/1213
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_ci   It's not as popular as tar because the traditional cpio command line tools
3108c2ecf20Sopenharmony_ci   require _truly_hideous_ command line arguments.  But that says nothing
3118c2ecf20Sopenharmony_ci   either way about the archive format, and there are alternative tools,
3128c2ecf20Sopenharmony_ci   such as:
3138c2ecf20Sopenharmony_ci
3148c2ecf20Sopenharmony_ci     http://freecode.com/projects/afio
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_ci2) The cpio archive format chosen by the kernel is simpler and cleaner (and
3178c2ecf20Sopenharmony_ci   thus easier to create and parse) than any of the (literally dozens of)
3188c2ecf20Sopenharmony_ci   various tar archive formats.  The complete initramfs archive format is
3198c2ecf20Sopenharmony_ci   explained in buffer-format.txt, created in usr/gen_init_cpio.c, and
3208c2ecf20Sopenharmony_ci   extracted in init/initramfs.c.  All three together come to less than 26k
3218c2ecf20Sopenharmony_ci   total of human-readable text.
3228c2ecf20Sopenharmony_ci
3238c2ecf20Sopenharmony_ci3) The GNU project standardizing on tar is approximately as relevant as
3248c2ecf20Sopenharmony_ci   Windows standardizing on zip.  Linux is not part of either, and is free
3258c2ecf20Sopenharmony_ci   to make its own technical decisions.
3268c2ecf20Sopenharmony_ci
3278c2ecf20Sopenharmony_ci4) Since this is a kernel internal format, it could easily have been
3288c2ecf20Sopenharmony_ci   something brand new.  The kernel provides its own tools to create and
3298c2ecf20Sopenharmony_ci   extract this format anyway.  Using an existing standard was preferable,
3308c2ecf20Sopenharmony_ci   but not essential.
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_ci5) Al Viro made the decision (quote: "tar is ugly as hell and not going to be
3338c2ecf20Sopenharmony_ci   supported on the kernel side"):
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_ci      http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1540.html
3368c2ecf20Sopenharmony_ci
3378c2ecf20Sopenharmony_ci   explained his reasoning:
3388c2ecf20Sopenharmony_ci
3398c2ecf20Sopenharmony_ci     - http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1550.html
3408c2ecf20Sopenharmony_ci     - http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1638.html
3418c2ecf20Sopenharmony_ci
3428c2ecf20Sopenharmony_ci   and, most importantly, designed and implemented the initramfs code.
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_ciFuture directions:
3458c2ecf20Sopenharmony_ci------------------
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ciToday (2.6.16), initramfs is always compiled in, but not always used.  The
3488c2ecf20Sopenharmony_cikernel falls back to legacy boot code that is reached only if initramfs does
3498c2ecf20Sopenharmony_cinot contain an /init program.  The fallback is legacy code, there to ensure a
3508c2ecf20Sopenharmony_cismooth transition and allowing early boot functionality to gradually move to
3518c2ecf20Sopenharmony_ci"early userspace" (I.E. initramfs).
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_ciThe move to early userspace is necessary because finding and mounting the real
3548c2ecf20Sopenharmony_ciroot device is complex.  Root partitions can span multiple devices (raid or
3558c2ecf20Sopenharmony_ciseparate journal).  They can be out on the network (requiring dhcp, setting a
3568c2ecf20Sopenharmony_cispecific MAC address, logging into a server, etc).  They can live on removable
3578c2ecf20Sopenharmony_cimedia, with dynamically allocated major/minor numbers and persistent naming
3588c2ecf20Sopenharmony_ciissues requiring a full udev implementation to sort out.  They can be
3598c2ecf20Sopenharmony_cicompressed, encrypted, copy-on-write, loopback mounted, strangely partitioned,
3608c2ecf20Sopenharmony_ciand so on.
3618c2ecf20Sopenharmony_ci
3628c2ecf20Sopenharmony_ciThis kind of complexity (which inevitably includes policy) is rightly handled
3638c2ecf20Sopenharmony_ciin userspace.  Both klibc and busybox/uClibc are working on simple initramfs
3648c2ecf20Sopenharmony_cipackages to drop into a kernel build.
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_ciThe klibc package has now been accepted into Andrew Morton's 2.6.17-mm tree.
3678c2ecf20Sopenharmony_ciThe kernel's current early boot code (partition detection, etc) will probably
3688c2ecf20Sopenharmony_cibe migrated into a default initramfs, automatically created and used by the
3698c2ecf20Sopenharmony_cikernel build.
370