The Linux kernel now supports two file system types for root disks to be automatically copied to ramdisk. These are minix and ext2, of which ext2 is the preferred file system. The ext2 support was added sometime between 1.1.17 and 1.1.57, I'm not sure exactly which. If you have a kernel within this range then edit /usr/src/linux/drivers/block/ramdisk.c and look for the word "ext2". If it is not found, then you will have to use a minix file system, and therefore the "mkfs" command to create it. (If using mkfs, use the -i option to specify more inodes than the default; -i 2000 is suggested).
To create an ext2 file system on a diskette on my system, I issue the following command:
mke2fs -m 0 /dev/fd0
The mke2fs command will automatically detect the space available and configure itself accordingly. If desired, the diskette size in 1Kb blocks can be specified to speed up mke2fs operation. The -m 0 parameter prevents it from reserving space for root, and hence provides more usable space on the disk.
An easy way to test the result is to create a system using the above command or similar, and then attempt to mount the diskette. If it is an ext2 system, then the command:
mount -t ext2 /dev/fd0 /<mount point>
should work.
In most cases it would be possible to copy your current kernel and boot the diskette from that. However there may be cases where you wish to build a separate one.
One reason is size. The kernel is one of the largest files in a minimum system, so if you want to build a boot/root diskette, then you will have to reduce the size of the kernel as much as possible. The kernel now supports changing the diskette after booting and before mounting root, so it is not necessary any more to squeeze the kernel into the same disk as everything else, therefore these comments apply only if you choose to build a boot/root diskette.
There are two ways of reducing kernel size:
make zImage
Refer to the documentation included with the kernel source
for up-to-date information on building compressed kernels.
Note that the kernel source is usually in /usr/src/linux.Having worked out a minimum set of facilities to include in a kernel, you then need to work out what to add back in. Probably the most common uses for a boot/root diskette system would be to examine and restore a corrupted root file system, and to do this you may need kernel support.
For example, if your backups are all held on tape using Ftape to access your tape drive, then, if you lose your current root drive and drives containing Ftape, then you will not be able to restore from your backup tapes. You will have to reinstall Linux, download and reinstall Ftape, and then try and read your backups.
It is probably desirable to maintain a copy of the same version of backup utilities used to write the backups, so that you don't waste time trying to install versions that cannot read your backup tapes.
The point here is that, whatever I/O support you have added to your kernel to support backups should also be added into your boot/root kernel.
The procedure for actually building the kernel is described in the documentation that comes with the kernel. It is quite easy to follow, so start by looking in /usr/src/linux. Note that if you have trouble building a kernel, then you should probably not attempt to build boot/root systems anyway.
A /dev directory containing a special file for all devices to be used by the system is mandatory for any Linux system. The directory itself is a normal directory, and can be created with the mkdir command in the normal way. The device special files, however, must be created in a special way, using the mknod command.
There is a shortcut, though - copy your existing /dev directory contents, and delete the ones you don't want. The only requirement is that you copy the device special files using the -R option. This will copy the directory without attempting to copy the contents of the files. Note that if you use lower caser, as in "-r", there will be a vast difference, because you will probably end up copying the entire contents of all of your hard disks - or at least as much of them as will fit on a diskette! Therefore, take care, and use the command:
cp -dpR /dev /mnt
assuming that the diskette is mounted at /mnt. The dp switches
ensure that symbolic links are copied as links (rather than
the target file being copied) and that the original file attributes
are preserved, thus preserving ownership information.
If you want to do it the hard way, use ls -l to display the major and minor device numbers for the devices you want, and create them on the diskette using mknod.
Many distributions include a shell script called MAKEDEV in the /dev directory. This shell script could be used to create the devices, but it is probably easier to just copy your existing ones, especially for rescue disk purposes.
Whichever way the device directory is copied, it is worth checking that any special devices you need have been placed on the rescue diskette. For example, Ftape uses tape devices, so you will need to copy all of these.
It might be possible to get away with just /dev, /proc and /etc to run a Linux system. I don't know - I've never tested it. However a reasonable minimum set of directories consists of the following:
Required to perform I/O with devices
Required by the ps command
System configuration files
Utility executables considered part of the system
Shared libraries to provide run-time support
A mount point for maintenance on other disks
Additional utilities and applications
Note that the directory tree presented here is for root diskette use only. Refer to the Linux File System Standard for much better information on how file systems should be structured in "standard" Linux systems.
Four of these directories can be created very easily:
The remaining 3 directories are described in the following sections.
This directory must contain a number of configuration files. On most systems, these can be divided into 3 groups:
Files which are not essential can be identified with the command:
ls -ltru
This lists files in reverse order of date last accessed, so if any
files are not being accessed, then they can be omitted from a root
diskette.
On my root diskettes, I have the number of config files down to 15. This reduces my work to dealing with three sets of files:
rc system startup script
fstab list of file systems to be mounted
inittab parameters for the init process - the
first process started at boot time.
passwd list of logins
shadow contains passwords
These should be pruned on secure systems to avoid copying
user's passwords off the system, and so that when you boot
from diskette, unwanted logins are rejected.Out of this, I only really have to configure two files, and what they should contain is suprisingly small.
#!/bin/sh
/etc/mount -av
/bin/hostname boot_root
and I don't really need to run hostname - it just looks nicer
if I do. Even mount is actually only needed to mount /proc to
support the ps command - Linux will run without it.
/dev/fd0 / ext2 defaults
/proc /proc proc defaults
I don't think that the first entry is really needed, but I
find that if I leave it out, mount won't mount /proc.Inittab should be ok as is, unless you want to ensure that users on serial ports cannot login. To prevent this, comment out all the entries for /etc/getty which include a ttys or ttyS device at the end of the line. Leave in the tty ports so that you can login at the console.
Inittab defines what the system will run or rerun in various states including startup, move to multi-user mode, powerfail, and others. A point to be careful of here is to carefully check that the commands entered in inittab refer to programs which are present and to the correct directory. If you place your command files on your rescue disk using the sample directory listing in this HOWTO as a guide, and then copy your inittab to your rescue disk without checking it, then the probability of failure will be quite high, because half of the inittab entries will refer to missing programs or to the wrong directory.
It is worth noting here as well that some programs cannot be moved
from one directory to another or they will fail at runtime because
they have hardcoded the name of another program which they attempt
to run. For example on my system, /etc/shutdown
has hardcoded in
it /etc/reboot
. If I move reboot to /bin/reboot, and then
issue a shutdown command, it will fail because it can't find the
reboot file.
For the rest, just copy all the text files in your /etc directory, plus all the executables in your /etc directory that you cannot be sure you do not need. As a guide, consult the sample ls listing in "Sample Boot/Root ls-lR Directory Listing" - this is what I have, so probably it will be sufficient for you if you copy only those files.
In practice, a single rc file is restrictive; most systems now use an /etc/rc.d directory containing shell scripts for different run levels. The absolute minimum is a single rc script, but it will probably be a lot simpler in practice to copy the inittab and /etc/rc.d directory from your existing system, and prune the shell scripts in the rc.d directory to remove processing not relevent to a diskette system environment.
Here is a convenient point to place the extra utilities you need to perform basic operations, utilities such as ls, mv, cat, dd etc.
See the section titled "Sample Boot/Root ls-lR Directory Listing" for the list of files that I place in my boot/root /bin directory. You may notice that it does not include any of the utilities required to restore from backup, such as cpio, tar, gzip etc. That is because I place these on a separate utility diskette, to save space on the boot/root diskette. Once I have booted my boot/root diskette, it then copies itself to the ramdisk leaving the diskette drive free to mount another diskette, the utility diskette. I usually mount this as /usr.
Creation of a utility diskette is described below in the section titled "Adding Utility Diskettes".
Two libraries are required to run many facilities under Linux:
If they are not found in your /lib directory then the system will be unable to boot. If you're lucky you may see an error message telling you why.
These should be present in you existing /lib directory. Note that libc.so.4 may be a symlink to a libc library with version number in the filename. If you issue the command:
ls -l /lib
you will see something like:
libc.so.4 -> libc.so.4.5.21
In this case, the libc library you want is libc.so.4.5.21.
For the boot/root to be any use, it must be bootable. To achieve this, the easiest way is to install a boot loader, which is a piece of executable code stored at sector 0, cylinder 0 of the diskette. See the section above titled "BOOT DISKETTE" for an overview of the boot process.
LILO is a tried and trusted boot loader available from any Linux mirror site. It allows you to configure the boot loader, including:
This provides a very convenient place to specify to the kernel how it should boot. My root/boot LILO configuration file, used with LILO 0.15, is:
boot = /dev/fd0
install = ./mnt/boot.b
map = ./mnt/lilo.map
delay = 50
message = ./mnt/lilo.msg
timeout = 150
compact
image = ./mnt/zImage
ramdisk = 1440
root = /dev/fd0
Note that boot.b, lilo.msg and the kernel must first have been copied to the diskette using a command similar to:
cp /boot/boot.b ./mnt
If this is not done, then LILO will not run correctly at boot time if the hard disk is not available, and there is little point setting up a rescue disk which requires a hard disk in order to boot.
I run lilo using the command:
/sbin/lilo -C <configfile>
I run it from the directory containing the mnt directory where I have mounted the diskette. This means that I am telling LILO to install a boot loader on the boot device (/dev/fd0 in this case), to boot a kernel in the root directory of the diskette.
I have also specified that I want the root device to be the diskette, and I want a ramdisk created of 1440 1K blocks, the same size as the diskette. Since I have created an ext2 file system on the diskette, this completes all the conditions required for Linux to automatically switch the root device to the ramdisk, and copy the diskette contents there as well.
The ramdisk features of Linux are described further in the section above titled "RAM DISKS AND BOOT/ROOT SYSTEMS".
It is also worth considering using the "single" parameter to cause Linux to boot in single-user mode. This could be useful to prevent users logging in on serial ports.
I also use the "DELAY" "MESSAGE" and "TIMEOUT" statements so that when I boot the disk, LILO will give me the opportunity to enter command line options if I wish. I don't need them at present, but I never know when I might want to set a different root device or mount a filesystem read-only.
The message file I use contains the message:
Linux Boot/Root Diskette
========================
Enter a command line of the form:
zImage [ command-line options]
If nothing is entered, linux will be loaded with
defaults after 15 seconds.
This is simply a reminder to myself what my choices are.
Readers are urged to read the LILO documentation carefully before atttempting to install anything. It is relatively easy to destroy partitions if you use the wrong "boot = " parameter. If you are inexperienced, do NOT run LILO until you are sure you understand it and you have triple-checked your parameters.
Note that you must re-run LILO every time you change the kernel, so that LILO can set up its map file to correctly describe the new kernel file. It is in fact possible to replace the kernel file with one which is almost identical without rerunning LILO, but it is far better not to gamble - if you change the kernel, re-run LILO.
One other thing I might as well add here while I'm on the LILO topic: if you mess up lilo on a drive containing DOS, you can always replace the boot sector with the DOS boot loader by issuing the DOS command:
FDISK /MBR
where MBR stands for "Master Boot Record". Note that some purists disagree with this, and they may have grounds, but it works.
LILO has several useful options which are worth keeping in mind when building boot disks:
zImage aha152x=0x340,11,3,1 ro
will pass the aha152x parameters through to the aha152x scsi disk
driver (provided that driver has been included when the kernel was
built) and will ask for the root filesystem to be mounted read-only.
zImage aha152x=0x340,11,3,1 root=/dev/sda8 ro lock
APPEND = "aha152x=0x340,11,3,1"
Next Chapter, Previous Chapter
Table of contents of this chapter, General table of contents
Top of the document, Beginning of this Chapter