AUTHOR: Bryan Kadzban $SCRIPTS/initramfs-list This will replace all occurrences of $SCRIPTS and $INITRAMFS in the file with the current values of the corresponding shell variables. Make SURE you don't miss the backslash escape character before the first $ in each sed script! If you feel the need to modify the init script, you should know a few things about it. First, it gets run under bash, so you can use *almost* any construct that bash provides. Second, we will not be copying glibc's NSS libraries, so anything that requires NSS will fail. (Name lookups are one thing that require NSS; this is why not everything bash is capable of will work. For instance, the fake /dev/tcp/www.kernel.org/80 "file" that bash provides won't actually work, because bash can't look up www.kernel.org.) Third, the last line of the script must *exec* run-init. You can't just run run-init without the exec statement, because if you do, your final system's /sbin/init won't work properly. (/sbin/init from the sysvinit package needs to have PID 1, otherwise it acts like /sbin/telinit, and tries to signal PID 1 to change runlevels. This obviously won't work unless PID 1 is also /sbin/init. If you don't exec the run-init utility, it won't have PID 1, so when it exec's /sbin/init, it won't work right.) Other than that, this script can do anything you want. For this hint, it just does what I consider the bare minimum (create the root block device, mount it, then change over to it and run the final system's /sbin/init). If you need to modify the initramfs-list file, the syntax should be fairly obvious. But run "usr/gen_init_cpio --help" from the base of your kernel tree to see the full syntax. Note that if you create any other directories to put files into, you have to list the directory before you list the file(s) that go into it. This will create about a 1-2 megabyte initramfs; this is definitely small enough to fit in even the most RAM-strapped machine's memory at startup. And it deletes everything from the initramfs just before running the final system's /sbin/init, so it won't take any more memory while your system is running, either. 5. Change the kernel's version string, so you won't overwrite your old kernel's modules (if you configured a modular kernel). The easiest way to do this is to edit the kernel's top-level Makefile, and change the EXTRAVERSION variable at the top. Adding "-initramfs" to the end would be sufficient, but you can make any change you wish. 6. Build and install the "new" kernel version. Make sure you set CONFIG_INITRAMFS_SOURCE (in menuconfig, it's under "General setup") to $SCRIPTS/initramfs-list during the kernel configuration. (You will need to manually expand the $SCRIPTS variable -- the kernel will not do it for you.) DO NOT move the initramfs-list file without updating the kernel configuration, and DO NOT move any files referred to by the initramfs-list file without updating it! Files referred to by initramfs-list can be upgraded at will (and the next time initramfs-list is touched, the kernel will rebuild the whole initramfs, including the new versions), but not moved. The kernel's build process will inspect the file that INITRAMFS_SOURCE points to, and build an initramfs using the files, directories, and devices described in the file. (You could also use a directory, and the build will create an initramfs from all the files in that directory. But I think using a file is simpler, and as above, just touching that file and rebuilding the kernel is enough to get upgrades to take effect. Also, I'm not sure whether using a directory requires the "cpio" tool to be installed; this method definitely does not.) 7. Create a grub menu.lst entry for your initramfs kernel. *DO NOT* overwrite a kernel you already have installed, just in case the initramfs doesn't work -- then you'll have a backup way to get a usable system, and you will be able to fix the initramfs from there. It's probably a good idea to always keep a kernel around that's not based on an initramfs, just in case. You don't have to pass any special parameters to the kernel to tell it to use the initramfs you just built (this is different from an initrd) -- the kernel will extract the initramfs image automatically, then check whether there's an /init file. If so, it will try to run it; if not, it will boot like normal. (This also means there's no way to disable the initramfs.) 8. Boot to the new kernel. If you see the LFS bootscripts running, then the initramfs worked. If you get an error before the bootscripts start, then you will have to investigate what's wrong in the initramfs -- probably the easiest way is to change the init script and add a "/bin/bash" line just before the point where the error happens. (Some echos won't hurt, either.) Then, you can look around the environment a bit. But note: you don't have very many commands. Just the shell builtins ("echo *" makes a halfway-decent replacement for ls, although it doesn't have an "ls -l" mode), cat, mount, mknod, and fstype. ============================= Appendices: ============================= A. Possible enhancements: This initramfs structure can do just about anything. Here are the first few things that I can think of that might be useful: (1) LVM, etc. for a root FS -- anything that requires special setup. (In fact, I got the basis for this /init script from an LVM howto.) (2) A "make allmodules" kernel -- an initramfs, like an initrd, gives you the ability to build *everything* as a module, including the driver for your root filesystem, the driver for your root disk, etc. (3) A LiveCD -- when making a LiveCD, you don't know which device file will be holding the LiveCD image. So you have to run a script that checks all possible devices to see whether each is actually holding the LiveCD. The current LiveCD hints use an initrd for this script, but it would not be difficult to adapt them to an initramfs. (4) Others -- anything that requires code to run before the kernel init= or root= arguments are interpreted is a prime candidate for an initrd or initramfs. B. Possible gotchas: (1) The /init script creates the correct root device based on the "root=" argument given to the kernel. But it can only handle IDE disks, and then only /dev/hda through /dev/hdd. Anything not meeting these criteria will give an error when /init gets run. It is certainly possible to modify /init to handle more devices, and I would suggest you do so if you use a SCSI hard drive or a secondary IDE card. (2) The "fstype" program can only handle certain filesystem types. If the filesystem on your root device is not among the supported list, fstype will output "unknown", and you will get an error from /init. You can test before you create the initramfs, if you have permission to read your raw root device, by running: $INITRAMFS/klibc-1.1.1/utils/static/fstype