AUTHOR: Martial Daumas DATE: 2003-09-18 LICENSE: GNU Free Documentation License Version 1.2 SYNOPSIS: How to create a basic mk_initrd command that works nice with LFS and devfs. DESCRIPTION: Initial Ram-disk (AKA initrd) is a minimal linux system that is run before the actual root partition is mounted, it contains an executable file called linuxrc (either a simple script as well as a more complicated compiled program) which is automatically run, and when it's finished, normal boot sequence goes on. This is mostly needed to load kernel modules needed to mount the root partition, thus it can be either a FS module (ie: reiserfs, jfs...), hardware modules (scsi, raid controller, lvm...). If you use LFS for your own usage, you generally know in advance what will be the modules needed to get your root partition mounted, so you can simply have theses supports compiled in the kernel, and forget about initrd, and this hint. Initrd can be helpful in the following circumstances: -You want to distribute a pre-compiled kernel and keep it as small and scalable as possible and you build a modular kernel, so that only needed modules are loaded in memory (that's my case). -You are building an embedded system, for example on a live CD-ROM, and you don't know in advance on what kind of hardware it will be run, in which case linuxrc can be handy to proceed tests or interactive actions, or further tweakings. -Mounting your root partition requires features that are only available as a separate module for some reason. -Some features are impossible to compile at the same time in the kernel, due to conflicts, once again initrd can help. In previous versions of the kernel, creating an initrd was possibly complicated task, mainly in writing a correct linuxrc. This hint is intended for those using devfs, with a 2.4.x kernel, version 2.4.19 and later. 2.6 kernel is not covered here but this hint will be updated soon. You can build an initrd by hands easily, but here we'll rather create a mk_initrd command (as found on some other distros), that is strictly minimal, and can be reused whenever you setup change. This is primarily intended to explain how thing works. PREREQUISITES: - linux kernel 2.4.19 or later, compiled with maximum modules use. - the ash shell (optionnal). - sufficient knowledge of how kernel works at boot time, as well as modules and boot loaders usage. - You also need the latest versions of these files (subject to possible updates): http://nasgaia.org/~martial/lfs/initrd.conf http://nasgaia.org/~martial/lfs/linuxrc http://nasgaia.org/~martial/lfs/mk_initrd HINT: 1. Create the configuration file ================================ This file cans be use to scale the initrd to your needs. Copy the initrd.conf file in /etc, remember to edit it as needed to suit your libraries version. Syntax: In LFS_INITRD_BINARIES and LFS_INITRD_SHLIBS, the first fields specify where to find the needed file on the current system, the second ones specify where to place this file in the initrd, and its name (if you need to change it for some reasons). LFS_INITRD_LNS allows to create symbolic links within the initrd (the second field is the name of the link) Other options are quite self-explanatory, feel free to adapt to your needs. If you don't have the ash shell, you can replace by bash, but you'll have less space left for modules, just remember to replace #!/bin/ash by #!/bin/bash later on in linuxrc. 2. Create the linuxrc script ============================ When the kernel is passed an initrd option via the boot loader, it uncompresses the ram-disk into the memory, and always try to execute the /linuxrc command. What we create here is strictly minimal, and thanks to the use of devfs, we don't have to deal anymore with mounting the real root partition and no more needs for pivot_root, everything is done automatically by the kernel itself (which eases a _lot_ the whole process). Note: the value of the root partition is stored in the kernel at compile time, it that value is not correct (ie: you compiled the kernel somewhere else), see rdev(8) to change it. Create a /usr/share/mk_initrd directory to store linuxrc with: mkdir -p /usr/share/mk_initrd Now copy the file linuxrc as /usr/share/mk_initrd/linuxrc - please make it executable as needed (chmod +x). 3.Create the mk_initrd command ============================== Last but not the least, we now create the mk_initrd command itself. The use of that script is explained later. Copy mk_initrd in /usr/sbin/ and make it executable: 4. Using mk_initrd ================== As usage() tells, you simply have to call mk_initrd passing a space separated list of modules with full paths (most of the time only one module is needed). The important thing to remind is that modules will be probed in the same order as given on the command line, thus, if you want to load both a device support (let's SCSI or RAID controller) and a FS support (let's say reiserfs or jfs) the hardware support logically should be activated prior to the FS support. If the hardware support comes in several modules, the order is generally significant too; use lsmod to determine which is the modules order. The linuxrc provided here is to be considered as an example, in many cases you'll have to include an other set of binaries and libs, and have linuxrc behave in a more complicated (or safer) manner. 5. A word on booting with grub ============================== To boot with initrd enabled, it's really simple, just add an initrd line in /boot/grub/menu.lst , like this: initrd (hdX,Y)/boot/initrd.gz under the line starting with "kernel /boot/...." Remember that devfs auto-mounting is required for this to work, so if you didn't compiled your kernel with the "mount at boot time" option, add devfs=mount on the kernel line (or append line with lilo). 6. Ideas to make it better ========================== Since it's possible to use larger initrd (either specify it when compiling the kernel, or use special boot option), you might want to use initrd in other contexts, and it worth having more available commands; give BusyBox a try, you can obtain a nice set of Unix commands in something like 200Ko (dynamically linked against glibc, even less against ulibc or dietlibc). ACKNOWLEDGEMENTS: I especially wish to thank Richard Lightman for his help and explanations on how initrd now works, I'd certainly still be stuck with outdated docs without him :-) CHANGELOG: [2002-10-26] * initial release [2003-09-16] * new hints format update * English correctness updates [2003-09-18] * making separate files for scripts