Hi, 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 ;-) Daniel -------------- next part -------------- INITRAMFS HOWTO 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 unpacked. 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.
please kill the part about glibc being to big and replace it with some moderate sentence like "most people prefer a small initramfs and thus want a libc optimized for size like klibc which is considereably smaller than glibc". I have 160MB+ (compressed) initramfs with absolutely no problems, containing everything I could possibly ever need, and that is very, very, very nice to have. porting several hundred applications to klibc would not make the end result significantly smaller and only waste a lot of time. "but glibc is _way_ too big" is simply wrong, there is no _technical_ reason why it is too big. please present the benefits and tradeoffs with pure technical arguments (size versus the need to port and recompile every app), and people can make a decission on their own. Thanks, Andreas -- ------------------------ [ SECURITY NOTICE ] ------------------------ To: klibc@zytor.com, daniel@dthaler.de. For your security, aj@ciphirelabs.com digitally signed this message on 10 August 2005 at 08:52:58 UTC. Verify this digital signature at http://www.ciphire.com/verify. ------------------- [ CIPHIRE DIGITAL SIGNATURE ] ------------------- Q2lwaGlyZSBTaWcuAVdrbGliY0B6eXRvci5jb20sIGRhbmllbEBkdGhhbGVyLmRlAGFqQ GNpcGhpcmVsYWJzLmNvbQBlbWFpbCBib2R5AJkCAAB8AHwAAAABAAAAasD5QpkCAAB9Aw ACAAIAAgAghZSFWfYeisbzljA2qz+9FGrRjKrLtBrgUie1aQqxAIcBAFxY4npAnfA18dO ZSdJF/KrhYaAgetZ31TP/j/rFyoe9aS4MLv7sbSUitsSpF9O+X+jiiTzFZRnfJATXf/Rg mCurU2lnRW5k --------------------- [ END DIGITAL SIGNATURE ] ---------------------
"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." I believe that is wrong: the kernel will try to open /dev/console first and not even run init, if that fails. so two files are needed: /dev/console and /init. Regards, Andreas -- ------------------------ [ SECURITY NOTICE ] ------------------------ To: klibc@zytor.com, daniel@dthaler.de. For your security, aj@ciphirelabs.com digitally signed this message on 10 August 2005 at 09:12:39 UTC. Verify this digital signature at http://www.ciphire.com/verify. ------------------- [ CIPHIRE DIGITAL SIGNATURE ] ------------------- Q2lwaGlyZSBTaWcuAVdrbGliY0B6eXRvci5jb20sIGRhbmllbEBkdGhhbGVyLmRlAGFqQ GNpcGhpcmVsYWJzLmNvbQBlbWFpbCBib2R5AEQBAAB8AHwAAAABAAAAB8X5QkQBAADJAg ACAAIAAgAghZSFWfYeisbzljA2qz+9FGrRjKrLtBrgUie1aQqxAIcBAFxY4npAnfA18dO ZSdJF/KrhYaAgetZ31TP/j/rFyoe9DJbgzSIrMGExD/PxXsy4HQP6kxgxOmiswWS6IbPA SGL/U2lnRW5k --------------------- [ END DIGITAL SIGNATURE ] ---------------------
On Tuesday 09 August 2005 20:56, Daniel Thaler wrote:> 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.unless that changed: pivot_root plus unmount = kernel panic, right? so what about replacing "bad things" with "kernel panic" ? Regards, Andreas -- ------------------------ [ SECURITY NOTICE ] ------------------------ To: klibc@zytor.com, daniel@dthaler.de. For your security, aj@ciphirelabs.com digitally signed this message on 10 August 2005 at 09:16:50 UTC. Verify this digital signature at http://www.ciphire.com/verify. ------------------- [ CIPHIRE DIGITAL SIGNATURE ] ------------------- Q2lwaGlyZSBTaWcuAVdrbGliY0B6eXRvci5jb20sIGRhbmllbEBkdGhhbGVyLmRlAGFqQ GNpcGhpcmVsYWJzLmNvbQBlbWFpbCBib2R5AEEBAAB8AHwAAAABAAAAAsb5QkEBAADCAg ACAAIAAgAghZSFWfYeisbzljA2qz+9FGrRjKrLtBrgUie1aQqxAIcBAFxY4npAnfA18dO ZSdJF/KrhYaAgetZ31TP/j/rFyoe9smIbBCuFED5f+85hUq5j8Nd6K6P/FIrgLZ7i+i/s wayzU2lnRW5k --------------------- [ END DIGITAL SIGNATURE ] ---------------------
Andreas Jellinghaus wrote:> please kill the part about glibc being to big and replace it > with some moderate sentence like "most people prefer a small > initramfs and thus want a libc optimized for size like klibc > which is considereably smaller than glibc". > > I have 160MB+ (compressed) initramfs with absolutely no problems, > containing everything I could possibly ever need, and that is > very, very, very nice to have. porting several hundred applications > to klibc would not make the end result significantly smaller and only > waste a lot of time. > > "but glibc is _way_ too big" is simply wrong, there is no _technical_ > reason why it is too big. please present the benefits and tradeoffs > with pure technical arguments (size versus the need to port and recompile > every app), and people can make a decission on their own.What I was thinking about when I wrote that was using initramfs to move functionality out of the kernel into userspace. Once that happens everyone will have an initramfs containing a small set of utilities. It would increase the kernel image size noticably and especially _for everyone_ if thoses utilities were linked to glibc. Do you like this better? "Userspace programs need a C library, but using glibc would lead to (comparatively) large binaries, thereby increasing the kernel image size." Daniel
-------------- next part -------------- INITRAMFS HOWTO 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 using glibc would lead to (comparatively) large binaries, thereby increasing the kernel image size. 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. Before starting /init the kernel will also try to open /dev/console to provide fd0,1,2 to /init. If /dev/console does not exist /init will still be run, but will need to be extra careful about its startup or create and open /dev/console itself. 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 unpacked. 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 a kernel panic _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.
what about: the binaries in your initramfs can be linked to any libc and both shared and static linking will work fine. however if you seek limited functionality for your initramfs and want it to be integrated in the kernel binary, a special libc like klibc will work well and keep the result small. for external initramfs files you can choose any libc, klibc will give you a small initramfs, but requires the programs to be compiled and linked against it. the usual glibc will also work and provide all the features glibc has and allow you to use standard applications without special recompiling or linking, but glibc is bigger and thus needs more memory. ? seriosly, glibc is 1.2 MB on my hard disk. many appliances these day have 32 or 64 MB ram, so spending one MB on glibc is not a big deal I think, compared to possibly many hours people might spend to port application XYZ to other libc. (sorry, I have no idea how easy it is to port to klibc/ulibc/dietlibc, but even simple recompiling and repackaging and maintaining something on your own, those all take time.)> "Userspace programs need a C library, but using glibc would lead to > (comparatively) large binaries, thereby increasing the kernel image size."I think the text should be balanced to give the disavantage (big) as well as the advantage (huge feature set, no need to recompile or relink). Regards, Andreas -- ------------------------ [ SECURITY NOTICE ] ------------------------ To: daniel@dthaler.de, klibc@zytor.com. For your security, aj@ciphirelabs.com digitally signed this message on 10 August 2005 at 12:17:18 UTC. Verify this digital signature at http://www.ciphire.com/verify. ------------------- [ CIPHIRE DIGITAL SIGNATURE ] ------------------- Q2lwaGlyZSBTaWcuAVdkYW5pZWxAZHRoYWxlci5kZSwga2xpYmNAenl0b3IuY29tAGFqQ GNpcGhpcmVsYWJzLmNvbQBlbWFpbCBib2R5AHAEAAB8AHwAAAABAAAATvD5QnAEAABqAw ACAAIAAgAghZSFWfYeisbzljA2qz+9FGrRjKrLtBrgUie1aQqxAIcBAFxY4npAnfA18dO ZSdJF/KrhYaAgetZ31TP/j/rFyoe9HIy2EhcKOEq8aIPjIcTw67bsIc3NoUJyTpFjxBGF 99JnU2lnRW5k --------------------- [ END DIGITAL SIGNATURE ] ---------------------