[klibc] initramfs howto

Daniel Thaler daniel at dthaler.de
Tue Aug 9 11:56:07 PDT 2005


Here's a try at writing an initramfs HOWTO.
This is basically a write-up of a number of interesting emails I collected 
over time.

It could probably use an editor, more fact-checking and a bunch of other 
good things, but it should be better than nothing ;-)

-------------- next part --------------

0) What are klibc and initramfs?

Initramfs is a ramfs into which an initramfs archive (a gzipped cpio archive)
is unpacked before the kernel performs the late-startup tasks like mounting
the root filesystem. Initramfs will allow such tasks to be performed in
userpace in the future. Initramfs archives can be attached to the kernel image,
so from a user's point of view things can continue to "just work"

Klibc is a means to this end: Userspace programs need a C library, but glibc is
_way_ too big. Klibc is a minimal C library, which contains the bare essentials
needed for the programs that will perform the userspace set-up in future.
The klibc distribution also contains a number of utilities that are useful in
an initramfs.

For more info read <http://lwn.net/Articles/14776/> (Initramfs arrives)

1) Creating an Initramfs

1.1) During the kernel build via kbuild
The easiest way to create an initramfs archive is to set INITRAMFS_SOURCE
in your kernel config. 
INITRAMFS_SOURCE should point to either
    - a directory containing the files to be included in the archive
      There is a slight problem with this, as you will need device files
      which you can only create as root.
    - a file which should contain entries according to the format described by
      the "usr/gen_init_cpio" program in the kernel tree.
      This solves the above problem, as creating device nodes only involves
      adding a line to a text file.
    - a cpio archive with a .cpio suffix
The archive created by setting INITRAMFS_SOURCE is saved as
usr/initramfs_data.cpio.gz and built into the kernel.

1.2) Calling "usr/gen_init_cpio" manually
You could also call "usr/gen_init_cpio" manually. This is the program used by
kbuild, so it takes the same list.

1.3) Using cpio
Running "find | cpio --format=newc -o | gzip > archive.cpio.gz" will create a
cpio archive of that directory's contents that can be used as an initramfs.

See also: Documentation/early-userspace/README

2) Contents of the initramfs

When an intramfs archive is found during boot, the kernel will try to start
/init. This is the only file the initramfs actually _needs_. Everything else
is optional, depending on what you want the initramfs to do.

Typically you would want /init to be a shellscript which mounts the root and
other filesystems, loads modules and then starts the regular init via run_init;
all of which can be done with programs included in the klibc package.

However it is also possible to run an installation program or a firewall from
an initramfs and never mount any disk filesystems.

If you want more functionality in your initramfs than the utilities that come
with klibc provide, you should try compiling that app with klcc. klcc is a perl
wrapper around gcc which will cause the program to be linked with klibc rather
than glibc.

If you can't get your source to compile against klibc you could try uClibc
which is also fairly small or link statically against glibc.

The only size constraint is that the initramfs archive must be less than half
the size of the machine's RAM, since the archive will be deleted _after_ it is

3) Booting

An Initramfs archive can either be built into the kernel, passed by the
bootloader or both; however the kernel must have CONFIG_BLK_DEV_INITRD if you
want to pass an initramfs archive via the bootloader.

During boot the kernel unpacks the built in archive first, then the one passed
by the bootloader (if either of them exist of course). Initramfs archives are
unpacked directly into the rootfs, a ramfs which is usually immediately
overmounted by the user-visible root.

If an initramfs is found the kernel does not mount a root filesystem and starts
/init in the initramfs.
/init is responsible for mounting the root and exec'ing the normal init.
Once /init has performed all necessary set-up tasks and initramfs is no longer
needed, the proper way to clean up is to use run_init (or do what it does
manually). Run_init deletes all the files on the initramfs to free up the space
and chroots into the "real" root.

DO NOT use pivot_root and try to unmount the initramfs; since initramfs is
rootfs you're pulling the rug out from under the kernel by doing so and bad
things _will_ happen as a result.

4) Testing

There is no need to reboot repeatedly to test your initramfs; you can test by
building the initramfs into a UML kernel. There is no need to rebuild any
programs (or klibc) to do so.

VMWare or bochs should work too.

More information about the klibc mailing list