Revision 1 as of 2007-02-15 12:39:09
|Deletions are marked like this.||Additions are marked like this.|
|Line 3:||Line 3:|
|All 2.6 Linux kernels contain a ["gzip"]ped ["cpio"] format archive, which is extracted into rootfs when the kernel boots up. The kernel then checks to see if rootfs now contains a file "init", and if so it executes it as PID 1.||All 2.6 Linux kernels contain a ["gzip"]ped ["cpio"] format archive, which is extracted into rootfs when the kernel boots up. The kernel then checks to see if ["rootfs"] now contains a file "init", and if so it executes it as PID 1.|
More information about ["initramfs"]:
All 2.6 Linux kernels contain a ["gzip"]ped ["cpio"] format archive, which is extracted into rootfs when the kernel boots up. The kernel then checks to see if ["rootfs"] now contains a file "init", and if so it executes it as PID 1.
At this point, this init process is responsible for bringing the system the rest of the way up, including locating and mounting the real root device (if any). If rootfs does not contain an init program after the embedded cpio archive is extracted into it, the kernel will fall through to the older code to locate and mount a root partition, then exec some variant of /sbin/init out of that.
All this differs from the old initrd in several ways:
- The old ["initrd"] was a separate file, while the initramfs archive is linked into the linux kernel image. (This archive is always linked into 2.6 kernels, but by default it's an empty archive.)
- The old initrd file was a gzipped filesystem image (in some file format, such as ["ext2"], that had to be built into the kernel), while the new initramfs archive is a gzipped cpio archive (like tar only simpler, see cpio(1) and Documentation/early-userspace/buffer-format.txt).
- The program run by the old initrd (which was called initrd, not init) did some setup and then returned to the kernel, while the init program from initramfs does not return to the kernel. (If it needs to hand off control it can overmount / with a new root device and exec another init program. See: switch_root, below.)
- - When switching another root device, initrd would pivot_root and then umount the ramdisk. But initramfs is rootfs: you shouldn't pivot_root ["rootfs"] and can't unmount it. Just delete everything out of it (except the new block device node, if any), overmount /, and exec the new init. (The klibc package contains a helper program in utils/run_init.c to do this for you, and other packages have adopted this as "switch_root".)
The 2.6 kernel build process always creates a gzipped cpio format initramfs archive and links it into the resulting kernel binary. By default, this archive is blank. The config option CONFIG_INITRAMFS_SOURCE (for some reason buried under devices->block devices in menuconfig) can be used to specify a source for the initramfs archive, which will automatically be incorporated into the resulting binary. This option can point to an existing gzipped cpio archive, a directory containing files to be archived, or a text file specification such as the following example:
- dir /dev 755 0 0 nod /dev/console 644 0 0 c 5 1 nod /dev/loop0 644 0 0 b 7 0 dir /bin 755 1000 1000 slink /bin/sh busybox 777 0 0 dir /proc 755 0 0 dir /sub 755 0 0 file /init initramfs/init.sh 755 0 0 file /bin/busybox initramfs/busybox 755 0 0
One advantage of the text file is that root access is not required to set permissions or create device nodes in a directory. (Note that those two example "file" entries expect to find files named "init.sh" and "busybox" in a directory called "initramfs", under the linux-2.6.* directory. See Documentation/early-userspace/README for more details.)
If you don't already understand what shared libraries, devices, and paths you need to get a minimal root filesystem up and running, here are some references:
The ["klibc"] package (http://www.kernel.org/pub/linux/libs/klibc) is designed to be a tiny C library to statically link early userspace code against, along with some related utilities. Some people use ["uClibc"] and ["busybox"]. (In theory you could use glibc, but that's not well suited for small embedded usage. Also note that glibc dlopens libnss to do name lookups, even when otherwise statically linked.)
diff -ru old/Documentation/initrd.txt new/Documentation/initrd.txt --- old/Documentation/initrd.txt 2005-09-09 21:42:58.000000000 -0500 +++ new/Documentation/initrd.txt 2005-10-17 22:38:41.447859392 -0500 @@ -1,3 +1,6 @@
NOTE: New systems should probably be using initramfs instead of initrd. See Documentation/filesystems/ramfs-rootfs-initramfs.txt for details