Bootdisk-HOWTO@linuxdoc.org
Copyright © 1995-2002 by Tom Fawcett
v4.5, January 2002
This document describes how to design and build boot/root diskettes for Linux. These disks can be used as rescue disks or to test new system components. You should be reasonably familiar with system administration tasks before attempting to build a bootdisk. If you just want a rescue disk to have for emergencies, see Appendix A.1.
![]() |
This document may be outdated. If the date on the title page is more than six months ago, please check the Bootdisk-HOWTO homepage to see if a more recent version exists. |
Although this document should be legible in its text form, it looks much better in Postscript, PDF or HTML forms because of the typographical conventions used.
Graham Chapman wrote the original Bootdisk-HOWTO and supported it through version 3.1. Tom Fawcett started as co-author around the time kernel v2 was introduced, and he is the document's current maintainer. Chapman has disappeared from the Linux community and his whereabouts are currently unknown.
This information is intended for Linux on the Intel platform. Much of this information may be applicable to Linux on other processors, but I have no first-hand experience or information about this. If you have experience with bootdisks on other platforms, please contact me.
User-mode-linux ( http://user-mode-linux.sourceforge.net) seems like a great way to test out bootdisks without having to reboot your machine constantly. I haven't been able to get it to work. If anyone has been using this consistently with homemade bootdisks, please let me know.
Re-analyze distribution bootdisks and update the "How the Pros do it" section.
Figure out just how much of the init-getty-login sequence can be simplified, and rip it out. A few people have said that init can be linked directly to /bin/sh; if so, and if this imposes no great limitations, alter the instructions to do this. This would eliminate the need for getty, login, gettydefs, and maybe all that PAM and NSS stuff.
Go through the 2.4 kernel source code again and write a detailed explanation of how the boot process and ramdisk-loading process work, in detail. (If only so that I understand it better.) There are some issues about initrd and limitations of booting devices (eg flash memory) that I don't understand yet.
Delete section that describes how to upgrade existing distribution bootdisks. This is usually more trouble than it's worth.
Replace rdev commands with LILO keywords.
I welcome any feedback, good or bad, on the content of this document. I have done my best to ensure that the instructions and information herein are accurate and reliable, but I don't know everything and I don't keep up on kernel development. Please let me know if you find errors or omissions. When writing, please indicate the version number of the document you're referencing. Be nice.
We thank the many people who assisted with corrections and suggestions. Their contributions have made it far better than we could ever have done alone.
Send comments and corrections to the author at the email address above. Please read Section 7 before asking me questions. Do not email me disk images.
Copyright © 1995-2002 by Tom Fawcett and Graham Chapman. This document may be distributed under the terms set forth in the Linux Documentation Project License. Please contact the authors if you are unable to get the license.
This is free documentation. It is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose.
Linux boot disks are useful in a number of situations, such as testing a new kernel, recovering from a disk failure (anything from a lost boot sector to a disk head crash), fixing a disabled system, or upgrading critical system files safely (such as libc.so).
There are several ways of obtaining boot disks:
Use one from a distribution such as Slackware. This will at least allow you to boot.
Use a rescue package to set up disks designed to be used as rescue disks.
Learn what is required for each of the types of disk to operate, then build your own.
This document assumes some basic familiarity with Linux system administration concepts. For example, you should know about directories, filesystems and floppy diskettes. You should know how to use mount and df. You should know what /etc/passwd and fstab files are for and what they look like. You should know that most of the commands in this HOWTO should be run as root.
Constructing a bootdisk from scratch can be complicated. If you haven't read the Linux FAQ and related documents, such as the Linux Installation HOWTO and the Linux Installation Guide, you should not be trying to build boot diskettes. If you just need a working bootdisk for emergencies, it is much easier to download a prefabricated one. See Appendix A.1, below, for where to find these.
A bootdisk is basically a miniature, self-contained Linux system on a diskette. It must perform many of the same functions that a complete full-size Linux system performs. Before trying to build one you should understand the basic Linux boot process. Here we present the basics, which are sufficient for understanding the rest of this document. Many details and alternative options have been omitted.
All PC systems start the boot process by executing code in ROM (specifically, the BIOS) to load the sector from sector 0, cylinder 0 of the boot drive. The boot drive is usually the first floppy drive (designated A: in DOS and /dev/fd0 in Linux). The BIOS then tries to execute this sector. On most bootable disks, sector 0, cylinder 0 contains either:
code from a boot loader such as LILO, which locates the kernel, loads it and executes it to start the boot proper; or
the start of an operating system kernel, such as Linux.
If a Linux kernel has been raw-copied to a diskette, the first sector of the disk will be the first sector of the Linux kernel itself. This first sector will continue the boot process by loading the rest of the kernel from the boot device.
When the kernel is completely loaded, it initializes device drivers and its internal data structures. Once it is completely initialized, it consults a special location in its image called the ramdisk word. This word tells it how and where to find its root filesystem. A root filesystem is simply a filesystem that will be mounted as ``/''. The kernel has to be told where to look for the root filesystem; if it cannot find a loadable image there, it halts.
In some boot situations — often when booting from a diskette — the root filesystem is loaded into a ramdisk, which is RAM accessed by the system as if it were a disk. RAM is several orders of magnitude faster than a floppy disk, so system operation is fast from a ramdisk. Also, the kernel can load a compressed filesystem from the floppy and uncompress it onto the ramdisk, allowing many more files to be squeezed onto the diskette.
Once the root filesystem is loaded and mounted, you see a message like:
VFS: Mounted root (ext2 filesystem) readonly.
|
Once the system has loaded a root filesystem successfully, it tries to execute the init program (in /bin or /sbin). init reads its configuration file /etc/inittab, looks for a line designated sysinit, and executes the named script. The sysinit script is usually something like /etc/rc or /etc/init.d/boot. This script is a set of shell commands that set up basic system services, such as running fsck on hard disks, loading necessary kernel modules, initializing swapping, initializing the network, and mounting disks mentioned in /etc/fstab.
This script often invokes various other scripts to do modular initialization. For example, in the common SysVinit structure, the directory /etc/rc.d/ contains a complex structure of subdirectories whose files specify how to enable and shut down most system services. However, on a bootdisk the sysinit script is often very simple.
When the sysinit script finishes control returns to init, which then enters the default runlevel, specified in inittab with the initdefault keyword. The runlevel line usually specifies a program like getty, which is responsible for handling commununications through the console and ttys. It is the getty program which prints the familiar ``login:'' prompt. The getty program in turn invokes the login program to handle login validation and to set up user sessions.
Having reviewed the basic boot process, we can now define various kinds of disks involved. We classify disks into four types. The discussion here and throughout this document uses the term ``disk'' to refer to floppy diskettes unless otherwise specified, though most of the discussion could apply equally well to hard disks.
A disk containing a kernel which can be booted. The disk can be used to boot the kernel, which then may load a root file system on another disk. The kernel on a bootdisk usually must be told where to find its root filesystem.
Often a bootdisk loads a root filesystem from another diskette, but it is possible for a bootdisk to be set up to load a hard disk's root filesystem instead. This is commonly done when testing a new kernel (in fact, ``make zdisk'' will create such a bootdisk automatically from the kernel source code).
A disk with a filesystem containing files required to run a Linux system. Such a disk does not necessarily contain either a kernel or a boot loader.
A root disk can be used to run the system independently of any other disks, once the kernel has been booted. Usually the root disk is automatically copied to a ramdisk. This makes root disk accesses much faster, and frees up the disk drive for a utility disk.
A disk which contains both the kernel and a root filesystem. In other words, it contains everything necessary to boot and run a Linux system without a hard disk. The advantage of this type of disk is that is it compact — everything required is on a single disk. However, the gradually increasing size of everything means that it is increasingly difficult to fit everything on a single diskette, even with compression.
A disk which contains a filesystem, but is not intended to be mounted as a root file system. It is an additional data disk. You would use this type of disk to carry additional utilities where you have too much to fit on your root disk.
In general, when we talk about ``building a bootdisk'' we mean creating both the boot (kernel) and root (files) portions. They may be either together (a single boot/root disk) or separate (boot + root disks). The most flexible approach for rescue diskettes is probably to use separate boot and root diskettes, and one or more utility diskettes to handle the overflow.
Creating the root filesystem involves selecting files necessary for the system to run. In this section we describe how to build a compressed root filesystem. A less common option is to build an uncompressed filesystem on a diskette that is directly mounted as root; this alternative is described in Section 9.1.
A root filesystem must contain everything needed to support a full Linux system. To be able to do this, the disk must include the minimum requirements for a Linux system:
The basic file system structure,
Minimum set of directories: /dev, /proc, /bin, /etc, /lib, /usr, /tmp,
Basic set of utilities: sh, ls, cp, mv, etc.,
Minimum set of config files: rc, inittab, fstab, etc.,
Devices: /dev/hd*, /dev/tty*, /dev/fd0, etc.,
Runtime library to provide basic functions used by utilities.
Of course, any system only becomes useful when you can run something on it, and a root diskette usually only becomes useful when you can do something like:
Check a file system on another drive, for example to check your root file system on your hard drive, you need to be able to boot Linux from another drive, as you can with a root diskette system. Then you can run fsck on your original root drive while it is not mounted.
Restore all or part of your original root drive from backup using archive and compression utilities such as cpio, tar, gzip and ftape.
We describe how to build a compressed filesystem, so called because it is compressed on disk and, when booted, is uncompressed onto a ramdisk. With a compressed filesystem you can fit many files (approximately six megabytes) onto a standard 1440K diskette. Because the filesystem is much larger than a diskette, it cannot be built on the diskette. We have to build it elsewhere, compress it, then copy it to the diskette.
In order to build such a root filesystem, you need a spare device that is large enough to hold all the files before compression. You will need a device capable of holding about four megabytes. There are several choices:
Use a ramdisk (DEVICE = /dev/ram0). In this case, memory is used to simulate a disk drive. The ramdisk must be large enough to hold a filesystem of the appropriate size. If you use LILO, check your configuration file (/etc/lilo.conf) for a line like RAMDISK = nnn which determines the maximum RAM that can be allocated to a ramdisk. The default is 4096K, which should be sufficient. You should probably not try to use such a ramdisk on a machine with less than 8MB of RAM. Check to make sure you have a device like /dev/ram0, /dev/ram or /dev/ramdisk. If not, create /dev/ram0 with mknod (major number 1, minor 0).
If you have an unused hard disk partition that is large enough (several megabytes), this is acceptable.
Use a loopback device, which allows a disk file to be treated as a device. Using a loopback device you can create a three megabyte file on your hard disk and build the filesystem on it.
Type man losetup for instructions on using loopback devices. If you don't have losetup, you can get it along with compatible versions of mount and unmount from the util-linux package in the directory ftp://ftp.win.tue.nl/pub/linux/utils/util-linux/ .
If you do not have a loop device (/dev/loop0, /dev/loop1, etc.) on your system, you will have to create one with ``mknod /dev/loop0 b 7 0''. Once you've installed these special mount and umount binaries, create a temporary file on a hard disk with enough capacity (eg, /tmp/fsfile). You can use a command like:
dd if=/dev/zero of=/tmp/fsfile bs=1k count=nnn
|
Use the file name in place of DEVICE below. When you issue a mount command you must include the option -o loop to tell mount to use a loopback device.
After you've chosen one of these options, prepare the DEVICE with:
dd if=/dev/zero of=DEVICE bs=1k count=4096
|
This command zeroes out the device.
![]() |
Zeroing the device is critical because the filesystem will be compressed later, so all unused portions should be filled with zeroes to achieve maximum compression. Keep this in mind whenever you move or delete files on the filesystem. The filesystem will correctly de-allocate the blocks, but it will not zero them out again. If you do a lot of deletions and copying, your compressed filesystem may end up much larger than necessary. |
Next, create the filesystem. The Linux kernel recognizes two file system types for root disks to be automatically copied to ramdisk. These are minix and ext2, of which ext2 is preferred. If using ext2, you may find it useful to use the -N option to specify more inodes than the default; -N 2000 is suggested so that you don't run out of inodes. Alternatively, you can save on inodes by removing lots of unnecessary /dev files. mke2fs will by default create 360 inodes on a 1.44Mb diskette. I find that 120 inodes is ample on my current rescue root diskette, but if you include all the devices in /dev you will easily exceed 360. Using a compressed root filesystem allows a larger filesystem, and hence more inodes by default, but you may still need to either reduce the number of files or increase the number of inodes.
So the command you use will look like:
mke2fs -m 0 -N 2000 DEVICE
|
(If you're using a loopback device, the disk file you're using should be supplied in place of this DEVICE.)
The mke2fs command will automatically detect the space available and configure itself accordingly. The ``-m 0'' parameter prevents it from reserving space for root, and hence provides more usable space on the disk.
Next, mount the device:
mount -t ext2 DEVICE /mnt
|
Here is a reasonable minimum set of directories for your root filesystem [1]:
/dev -- Device files, required to perform I/O
/proc -- Directory stub required by the proc filesystem
/etc -- System configuration files
/sbin -- Critical system binaries
/bin -- Essential binaries considered part of the system
/lib -- Shared libraries to provide run-time support
/mnt -- A mount point for maintenance on other disks
/usr -- Additional utilities and applications
Three of these directories will be empty on the root filesystem, so they only need to be created with mkdir. The /proc directory is basically a stub under which the proc filesystem is placed. The directories /mnt and /usr are only mount points for use after the boot/root system is running. Hence again, these directories only need to be created.
The remaining four directories are described in the following sections.
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 mkdir 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 devices files from your existing hard disk /dev directory. The only requirement is that you copy the device special files using -R option. This will copy the directory without attempting to copy the contents of the files. Be sure to use an upper case R . For example:
cp -dpR /dev/fd[01]* /mnt/dev
cp -dpR /dev/tty[0-6] /mnt/dev
|
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.
However the devices files are created, check 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 if you intend to access your floppy tape drive from the bootdisk.
Note that one inode is required for each device special file, and inodes can at times be a scarce resource, especially on diskette filesystems. You'll need to be selective about the device files you include. For example, if you do not have SCSI disks you can safely ignore /dev/sd*; if you don't intend to use serial ports you can ignore /dev/ttyS*.
If, in building your root filesystem, you get the error No space left on device but a df command shows space still available, you have probably run out of inodes. A df -i will display inode usage.
![]() |
Be sure to include the following files from this directory: console, kmem, mem, null, ram0 and tty1. |
The /etc directory contains configuration files. What it should contain depends on what programs you intend to run. On most systems, these can be divided into three groups:
Required at all times, e.g. rc, fstab, passwd.
May be required, but no one is too sure.
Junk that crept in.
ls -ltru
|
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:
The ones I must configure for a boot/root system:
rc.d/* -- system startup and run level change scripts
fstab -- list of file systems to be mounted
inittab -- parameters for the init process, the first process started at boot time.
gettydefs -- parameters for the init process, the first process started at boot time.
The ones I should tidy up for a boot/root system:
passwd -- Critical list of users, home directories, etc.
group -- user groups.
shadow -- passwords of users. You may not have this.
termcap -- the terminal capability database.
If security is important, passwd and shadow should be pruned to avoid copying user passwords off the system, and so that unwanted logins are rejected when you boot from diskette.
Be sure that passwd contains at least root. If you intend other users to login, be sure their home directories and shells exist.
termcap, the terminal database, is typically several hundred kilobytes. The version on your boot/root diskette should be pruned down to contain only the terminal(s) you use, which is usually just the linux or linux-console entry.
The rest. They work at the moment, so I leave them alone.
Out of this, I only really have to configure two files, and what they should contain is surprisingly small.
rc should contain:
#!/bin/sh
/bin/mount -av
/bin/hostname Kangaroo
|
fstab should contain at least:
/dev/ram0 / ext2 defaults
/dev/fd0 / ext2 defaults
/proc /proc proc defaults
|
Your inittab should be changed so that its sysinit line runs rc or whatever basic boot script will be used. Also, if you want to ensure that users on serial ports cannot login, comment out all the entries for 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.
A minimal inittab file looks like this:
id:2:initdefault:
si::sysinit:/etc/rc
1:2345:respawn:/sbin/getty 9600 tty1
2:23:respawn:/sbin/getty 9600 tty2
|
Note that some programs cannot be moved elsewhere because other programs have hardcoded their locations. 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 cannot 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 listing in Appendix C. Probably it will suffice to copy only those files, but systems differ a great deal, so you cannot be sure that the same set of files on your system is equivalent to the files in the list. The only sure method is to start with inittab and work out what is required.
Most systems now use an /etc/rc.d/ directory containing shell scripts for different run levels. The minimum is a single rc script, but it may be simpler just to copy inittab and the /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.
The /bin directory is a convenient place for extra utilities you need to perform basic operations, utilities such as ls, mv, cat and dd. See Appendix C for an example list of files that go in a /bin and /sbin directories. It does not include any of the utilities required to restore from backup, such as cpio, tar and gzip. That is because I place these on a separate utility diskette, to save space on the boot/root diskette. Once the boot/root diskette is booted, it is copied 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 Section 9.2. It is probably desirable to maintain a copy of the same version of backup utilities used to write the backups so you don't waste time trying to install versions that cannot read your backup tapes.
![]() |
Be sure to include the following programs: init, getty or equivalent, login, mount, some shell capable of running your rc scripts, a link from sh to the shell. |
In /lib you place necessary shared libraries and loaders. If the necessary libraries 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.
Nearly every program requires at least the libc library, libc.so. N, where N is the current version number. Check your /lib directory. The file libc.so.N is usually a symlink to a filename with a complete version number:
% ls -l /lib/libc* -rwxr-xr-x 1 root root 4016683 Apr 16 18:48 libc-2.1.1.so* lrwxrwxrwx 1 root root 13 Apr 10 12:25 libc.so.6 -> libc-2.1.1.so* |
In this case, you want libc-2.1.1.so. To find other libraries you should go through all the binaries you plan to include and check their dependencies with ldd. For example:
% ldd /sbin/mke2fs
libext2fs.so.2 => /lib/libext2fs.so.2 (0x40014000)
libcom_err.so.2 => /lib/libcom_err.so.2 (0x40026000)
libuuid.so.1 => /lib/libuuid.so.1 (0x40028000)
libc.so.6 => /lib/libc.so.6 (0x4002c000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
|
Note that some libraries are quite large and will not fit easily on your root filesystem. For example, the libc.so listed above is about 4 meg. You will probably need to strip libraries when copying them to your root filesystem. See Section 8 for instructions.
In /lib you must also include a loader for the libraries. The loader will be either ld.so (for A.OUT libraries, which are no longer common) or ld-linux.so (for ELF libraries). Newer versions of ldd tell you exactly which loader is needed, as in the example above, but older versions may not. If you're unsure which you need, run the file command on the library. For example:
% file /lib/libc.so.4.7.2 /lib/libc.so.5.4.33 /lib/libc-2.1.1.so /lib/libc.so.4.7.2: Linux/i386 demand-paged executable (QMAGIC), stripped /lib/libc.so.5.4.33: ELF 32-bit LSB shared object, Intel 80386, version 1, stripped /lib/libc-2.1.1.so: ELF 32-bit LSB shared object, Intel 80386, version 1, not stripped |
Copy the specific loader(s) you need to the root filesystem you're building. Libraries and loaders should be checked carefully against the included binaries. If the kernel cannot load a necessary library, the kernel may hang with no error message.
Your system may require dynamically loaded libraries that are not visible to ldd. If you don't provide for these, you may have trouble logging in or using your bootdisk.
If your system uses PAM (Pluggable Authentication Modules), you must make some provision for it on your bootdisk. Briefly, PAM is a sophisticated modular method for authenticating users and controlling their access to services. An easy way to determine if your system uses PAM is run ldd on your login executable; if the output includes libpam.so, you need PAM.
Fortunately, security is usually of no concern with bootdisks since anyone who has physical access to a machine can usually do anything they want anyway. Therefore, you can effectively disable PAM by creating a simple /etc/pam.conf file in your root filesystem that looks like this:
OTHER auth optional /lib/security/pam_permit.so OTHER account optional /lib/security/pam_permit.so OTHER password optional /lib/security/pam_permit.so OTHER session optional /lib/security/pam_permit.so |
This configuration allows anyone complete access to the files and services on your machine. If you care about security on your bootdisk for some reason, you'll have to copy some or all of your hard disk's PAM setup to your root filesystem. Be sure to read the PAM documentation carefully, and copy any libraries needed in /lib/security onto your root filesystem.
You must also include /lib/libpam.so on your bootdisk. But you already know this since you ran ldd on /bin/login, which showed this dependency.
If you are using glibc (aka libc6), you will have to make provisions for name services or you will not be able to login. The file /etc/nsswitch.conf controls database lookups for various servies. If you don't plan to access services from the network (eg, DNS or NIS lookups), you need only prepare a simple nsswitch.conf file that looks like this:
passwd: files
shadow: files
group: files
hosts: files
services: files
networks: files
protocols: files
rpc: files
ethers: files
netmasks: files
bootparams: files
automount: files
aliases: files
netgroup: files
publickey: files
|
If you plan to access the network from your bootdisk, you may want to create a more elaborate nsswitch.conf file. See the nsswitch man page for details. You must include a file /lib/libnss_ service .so.1 for each service you specify.
If you have a modular kernel, you must consider which modules you may want to load from your bootdisk after booting. You might want to include ftape and zftape modules if your backup tapes are on floppy tape, modules for SCSI devices if you have them, and possibly modules for PPP or SLIP support if you want to access the net in an emergency.
These modules may be placed in /lib/modules. You should also include insmod, rmmod and lsmod. Depending on whether you want to load modules automatically, you might also include modprobe, depmod and swapout. If you use kerneld, include it along with /etc/conf.modules.
However, the main advantage to using modules is that you can move non-critical modules to a utility disk and load them when needed, thus using less space on your root disk. If you may have to deal with many different devices, this approach is preferable to building one huge kernel with many drivers built in.
![]() |
In order to boot a compressed ext2 filesystem, you must have ramdisk and ext2 support built-in. They cannot be supplied as modules. |
Some system programs, such as login, complain if the file /var/run/utmp and the directory /var/log do not exist. So:
mkdir -p /mnt/var/{log,run}
touch /mnt/var/run/utmp
|
Finally, after you have set up all the libraries you need, run ldconfig to remake /etc/ld.so.cache on the root filesystem. The cache tells the loader where to find the libraries. You can do this with:
ldconfig -r /mnt
|
When you have finished constructing the root filesystem, unmount it, copy it to a file and compress it:
umount /mnt
dd if=DEVICE bs=1k | gzip -v9 > rootfs.gz
|
At this point you have a complete compressed root filesystem. The next step is to build or select a kernel. 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. If you are building a single boot/root diskette, the kernel will be one of the largest files on the diskette so you will have to reduce the size of the kernel as much as possible. To reduce kernel size, build it with the minumum set of facilities necessary to support the desired system. This means leaving out everything you don't need. Networking is a good thing to leave out, as well as support for any disk drives and other devices which you don't need when running your boot/root system. As stated before, your kernel must have ramdisk and ext2 support built into it.
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 to read your backups.
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. If you have trouble building a kernel, you should probably not attempt to build boot/root systems anyway. Remember to compress the kernel with ``make zImage''.
At this point you have a kernel and a compressed root filesystem. If you are making a boot/root disk, check their sizes to make sure they will both fit on one disk. If you are making a two disk boot+root set, check the root filesystem to make sure it will fit on a single diskette.
You should decide whether to use LILO to boot the bootdisk kernel. The alternative is to copy the kernel directly to the diskette and boot without LILO. The advantage of using LILO is that it enables you to supply some parameters to the kernel which may be necessary to initialize your hardware (Check the file /etc/lilo.conf on your system. If it exists and has a line like ``append=...'', you probably need this feature). The disadvantage of using LILO is that building the bootdisk is more complicated and takes slightly more space. You will have to set up a small separate filesystem, which we shall call the kernel filesystem, where you transfer the kernel and a few other files that LILO needs.
If you are going to use LILO, read on; if you are going to transfer the kernel directly, skip ahead to Section 6.2.
First, make sure you have a recent version of LILO.
You must create a small configuration file for LILO. It should look like this:
boot =/dev/fd0
install =/boot/boot.b
map =/boot/map
read-write
backup =/dev/null
compact
image = KERNEL
label = Bootdisk
root =/dev/fd0
|
Save this file as bdlilo.conf.
You now have to create a small filesystem, which we shall call a kernel filesystem, to distinguish it from the root filesystem.
First, figure out how large the filesystem should be. Take the size of your kernel in blocks (the size shown by ``ls -s KERNEL'') and add 50. Fifty blocks is approximately the space needed for inodes plus other files. You can calculate this number exactly if you want to, or just use 50. If you're creating a two-disk set, you may as well overestimate the space since the first disk is only used for the kernel anyway. Call this number KERNEL_BLOCKS.
Put a floppy diskette in the drive (for simplicity we'll assume /dev/fd0) and create an ext2 kernel filesystem on it:
mke2fs -N 24 -m 0 /dev/fd0 KERNEL_BLOCKS
|
mount -o dev /dev/fd0 /mnt
rm -rf /mnt/lost+found
mkdir /mnt/{boot,dev}
|
Next, create devices /dev/null and /dev/fd0. Instead of looking up the device numbers, you can just copy them from your hard disk using -R:
cp -R /dev/{null,fd0} /mnt/dev
|
cp /boot/boot.b /mnt/boot
|
cp bdlilo.conf KERNEL /mnt
|
lilo -v -C bdlilo.conf -r /mnt
|
total 361 1 –rw–r––r–– 1 root root 176 Jan 10 07:22 bdlilo.conf 1 drwxr–xr–x 2 root root 1024 Jan 10 07:23 boot/ 1 drwxr–xr–x 2 root root 1024 Jan 10 07:22 dev/ 358 –rw–r––r–– 1 root root 362707 Jan 10 07:23 vmlinuz boot: total 8 4 –rw–r––r–– 1 root root 3708 Jan 10 07:22 boot.b 4 –rw––––––– 1 root root 3584 Jan 10 07:23 map dev: total 0 0 brw–r––––– 1 root root 2, 0 Jan 10 07:22 fd0 0 crw–r––r–– 1 root root 1, 3 Jan 10 07:22 null |
Do not worry if the file sizes are slightly different from yours.
Now leave the diskette in the drive and go to Section 6.3.
If you are not using LILO, transfer the kernel to the bootdisk with dd:
% dd if=KERNEL of=/dev/fd0 bs=1k
353+1 records in
353+1 records out
|
Finally, set the root device to be the diskette itself, then set the root to be loaded read/write:
rdev /dev/fd0 /dev/fd0
rdev -R /dev/fd0 0
|
Inside the kernel image is the ramdisk word that specifies where the root filesystem is to be found, along with other options. The word can be accessed and set via the rdev command, and its contents are interpreted as follows:
| Bit field | Description |
|---|---|
| 0-10 | Offset to start of ramdisk, in 1024 byte blocks |
| 11-13 | unused |
| 14 | Flag indicating that ramdisk is to be loaded |
| 15 | Flag indicating to prompt before loading rootfs |
If bit 15 is set, on boot-up you will be prompted to place a new floppy diskette in the drive. This is necessary for a two-disk boot set.
There are two cases, depending on whether you are building a single boot/root diskette or a double ``boot+root'' diskette set.
If you are building a single disk, the compressed root filesystem will be placed right after the kernel, so the offset will be the first free block (which should be the same as KERNEL_BLOCKS). Bit 14 will be set to 1, and bit 15 will be zero. For example, say you're building a single disk and the root filesystem will begin at block 253 (decimal). The ramdisk word value should be 253 (decimal) with bit 14 set to 1 and bit 15 set to 0. To calculate the value you can simply add the decimal values. 253 + (2^14) = 253 + 16384 = 16637. If you don't quite understand where this number comes from, plug it into a scientific calculator and convert it to binary,
If you are building a two-disk set, the root filesystem will begin at block zero of the second disk, so the offset will be zero. Bit 14 will be set to 1 and bit 15 will be 1. The decimal value will be 2^14 + 2^15 = 49152 in this case.
After carefully calculating the value for the ramdisk word, set it with rdev -r. Be sure to use the decimal value. If you used LILO, the argument to rdev here should be the mounted kernel path, e.g. /mnt/vmlinuz; if you copied the kernel with dd, instead use the floppy device name (e.g., /dev/fd0).
rdev -r KERNEL_OR_FLOPPY_DRIVE VALUE
|
If you used LILO, unmount the diskette now.
![]() |
Do not believe what the rdev/ramsize manpage says about ramdisk size. The manpage is obsolete. As of kernel 2.0 or so, the ramdisk word no longer determines the ramdisk size; the word is instead interpreted according to the table at the beginning of section Section 6.3. For a detailed explanation, see the documentation file ramdisk.txt or http://www.linuxhq.com/kernel/v2.4/doc/ramdisk.txt.html. |
The last step is to transfer the root filesystem.
If the root filesystem will be placed on the same disk as the kernel, transfer it using dd with the seek option, which specifies how many blocks to skip:
dd if=rootfs.gz of=/dev/fd0 bs=1k seek=KERNEL_BLOCKS
|
If the root filesystem will be placed on a second disk, remove the first diskette, put the second diskette in the drive, then transfer the root filesystem to it:
dd if=rootfs.gz of=/dev/fd0 bs=1k
|
Congratulations, you are done!
![]() |
You should always test a bootdisk before putting it aside for an emergency. If it fails to boot, read on. |
When building bootdisks, the first few tries often will not boot. The general approach to building a root disk is to assemble components from your existing system, and try and get the diskette-based system to the point where it displays messages on the console. Once it starts talking to you, the battle is half over because you can see what it is complaining about, and you can fix individual problems until the system works smoothly. If the system just hangs with no explanation, finding the cause can be difficult. The recommended procedure for investigating the problem where the system will not talk to you is as follows:
You may see a message like this:
Kernel panic: VFS: Unable to mount root fs on XX:YY |
If you see many errors like:
end_request: I/O error, dev 01:00 (ramdisk), sector NNN |
Ramdisk driver initialized : 16 ramdisks of 4096K size
|
Check that the root disk actually contains the directories you think it does. It is easy to copy at the wrong level so that you end up with something like /rootdisk/bin instead of /bin on your root diskette.
Check that there is a /lib/libc.so with the same link that appears in your /lib directory on your hard disk.
Check that any symbolic links in your /dev directory in your existing system also exist on your root diskette filesystem, where those links are to devices which you have included in your root diskette. In particular, /dev/console links are essential in many cases.
Check that you have included /dev/tty1, /dev/null, /dev/zero, /dev/mem, /dev/ram and /dev/kmem files.
Check your kernel configuration -- support for all resources required up to login point must be built in, not modules. So ramdisk and ext2 support must be built-in.
Check that your kernel root device and ramdisk settings are correct.
Once these general aspects have been covered, here are some more specific files to check:
Make sure init is included as /sbin/init or /bin/init. Make sure it is executable.
Run ldd init to check init's libraries. Usually this is just libc.so, but check anyway. Make sure you included the necessary libraries and loaders.
Make sure you have the right loader for your libraries -- ld.so for a.out or ld-linux.so for ELF.
Check the /etc/inittab on your bootdisk filesystem for the calls to getty (or some getty-like program, such as agetty, mgetty or getty_ps). Double-check these against your hard disk inittab. Check the man pages of the program you use to make sure these make sense. inittab is possibly the trickiest part because its syntax and content depend on the init program used and the nature of the system. The only way to tackle it is to read the man pages for init and inittab and work out exactly what your existing system is doing when it boots. Check to make sure /etc/inittab has a system initialisation entry. This should contain a command to execute the system initialization script, which must exist.
As with init, run ldd on your getty to see what it needs, and make sure the necessary library files and loaders were included in your root filesystem.
Be sure you have included a shell program (e.g., bash or ash) capable of running all of your rc scripts.
If you have a /etc/ld.so.cache file on your rescue disk, remake it.
If init starts, but you get a message like:
Id xxx respawning too fast: disabled for 5 minutes
|
If you get a login prompt, and you enter a valid login name but the system prompts you for another login name immediately, the problem may be with PAM or NSS. See Section 4.4. The problem may also be that you use shadow passwords and didn't copy /etc/shadow to your bootdisk.
If you try to run some executable, such as df, which is on your rescue disk but you yields a message like: df: not found, check two things: (1) Make sure the directory containing the binary is in your PATH, and (2) make sure you have libraries (and loaders) the program needs.
One of the main problems with building bootdisks is getting everything to fit into one (or even two) diskettes. Even when files are compressed this can be very difficult, because Linux system components keep growing. Here are some common techniques used to make everything fit.
By default, floppy diskettes are formatted at 1440K, but higher density formats are possible. Whether you can boot from higher density disks depends mostly on your BIOS. fdformat will format disks for the following sizes: 1600K, 1680K, 1722K, 1743K, 1760K, 1840K, and 1920K. See the fdformat man page and /usr/src/linux/Documentation/devices.txt.
But what diskette densities/geometries will your machine support? Here are some (lightly edited) answers from Alain Knaff, the author of fdutils.
This is more an issue of the BIOS rather than the physical format of the disk. If the BIOS decides that any sector number greater than 18 is bad, then there is not much we can do. Indeed, short of disassembling the BIOS, trial and error seems to be the only way to find out. However, if the BIOS supports ED disks (extra density: 36 sectors/track and 2.88MB), there's a chance that 1722K disks are supported as well.
Superformatted disks with more than 21 sectors/track are likely not bootable: indeed, those use sectors of non-standard sizes (1024 bytes in a sector instead of 512, for example), and are likely not bootable. It should however be possible to write a special bootsector program to work around this. If I remember correctly, the DOS 2m utility has such a beast, as does OS/2's XDF utilities.
Some BIOSes artificially claim that any sector number greater than 18 must be in error. As 1722K disks use sector numbers up to 21, these would not be bootable. The best way to test would be to format a test DOS or syslinus disk as 1722K and make it bootable. If you use LILO, don't use the option linear (or else LILO would assume that the disk is the default 18 sectors/track, and the disk will fail to boot even if supported by the BIOS).
Much root filesystem space is consumed by common GNU system utilities such as cat, chmod, cp, dd, df, etc. The BusyBox project was designed to provide minimal replacements for these common system utilities. BusyBox supplies one single monolithic executable file, /bin/busybox, about 150K, which implements the functions of these utilities. You then create symlinks from different utilities to this executable; busybox sees how it was called and invokes the correct code. BusyBox even includes a basic shell. BusyBox is available in binary packages for many distributions, and source code is available from the BusyBox site.
Some of the popular shells for Linux, such as bash and tcsh, are large and require many libraries. If you don't use the BusyBox shell, you should still consider replacing your shell anyway. Some light-weight alternatives are ash, lsh, kiss and smash, which are much smaller and require few (or no) libraries. Most of these replacement shells are available from http://www.ibiblio.org/pub/Linux/system/shells/ . Make sure any shell you use is capable of running commands in all the rc files you include on your bootdisk.
Many libraries and binaries are distributed with debugging information. Running file on these files will tell you ``not stripped'' if so. When copying binaries to your root filesystem, it is good practice to use:
objcopy --strip-all FROM TO |
![]() |
When copying libraries, be sure to use strip-debug instead of strip-all. |
If some of your binaries are not needed immediately to boot or login, you can move them to a utility disk. See Section 9.2 for details. You may also consider moving modules to a utility disk as well.
Section 4 gave instructions for building a compressed root filesystem which is loaded to ramdisk when the system boots. This method has many advantages so it is commonly used. However, some systems with little memory cannot afford the RAM needed for this, and they must use root filesystems mounted directly from the diskette.
Such filesystems are actually easier to build than compressed root filesystems because they can be built on a diskette rather than on some other device, and they do not have to be compressed. We will outline the procedure as it differs from the instructions above. If you choose to do this, keep in mind that you will have much less space available.
Calculate how much space you will have available for root files. If you are building a single boot/root disk, you must fit all blocks for the kernel plus all blocks for the root filesystem on the one disk.
Using mke2fs, create a root filesystem on a diskette of the appropriate size.
Populate the filesystem as described above.
When done, unmount the filesystem and transfer it to a disk file but do not compress it.
Transfer the kernel to a floppy diskette, as described above. When calculating the ramdisk word, set bit 14 to zero, to indicate that the root filesystem is not to be loaded to ramdisk. Run the rdev's as described.
Transfer the root filesystem as before.
There are several shortcuts you can take. If you are building a two-disk set, you can build the complete root filesystem directly on the second disk and you need not transfer it to a hard disk file and then back. Also, if you are building a single boot/root disk and using LILO, you can build a single filesystem on the entire disk, containing the kernel, LILO files and root files, and simply run LILO as the last step.
Building a utility disk is relatively easy -- simply create a filesystem on a formatted disk and copy files to it. To use it with a bootdisk, mount it manually after the system is booted.
In the instructions above, we mentioned that the utility disk could be mounted as /usr. In this case, binaries could be placed into a /bin directory on your utility disk, so that placing /usr/bin in your path will access them. Additional libraries needed by the binaries are placed in /lib on the utility disk.
There are several important points to keep in mind when designing a utility disk:
Do not place critical system binaries or libraries onto the utility disk, since it will not be mountable until after the system has booted.
You cannot access a floppy diskette and a floppy tape drive simultaneously. This means that if you have a floppy tape drive, you will not be able to access it while your utility disk is mounted.
Access to files on the utility disk will be slow.
Appendix D shows a sample of files on a utility disk. Here are some ideas for files you may find useful: programs for examining and manipulating disks (format, fdisk) and filesystems (mke2fs, fsck, debugfs, isofs.o), a lightweight text editor (elvis, jove), compression and archive utilities (gzip, bzip, tar, cpio, afio), tape utilities (mt, ftmt, tob, taper), communications utilities (ppp.o, slip.o, minicom) and utilities for devices (setserial, mknod).
You may notice that the bootdisks used by major distributions such as Slackware, RedHat or Debian seem more sophisticated than what is described in this document. Professional distribution bootdisks are based on the same principles outlined here, but employ various tricks because their bootdisks have additional requirements. First, they must be able to work with a wide variety of hardware, so they must be able to interact with the user and load various device drivers. Second, they must be prepared to work with many different installation options, with varying degrees of automation. Finally, distribution bootdisks usually combine installation and rescue capabilities.
Some bootdisks use a feature called initrd (initial ramdisk). This feature was introduced around 2.0.x and allows a kernel to boot in two phases. When the kernel first boots, it loads an initial ramdisk image from the boot disk. This initial ramdisk is a root filesystem containing a program that runs before the real root fs is loaded. This program usually inspects the environment and/or asks the user to select various boot options, such as the device from which to load the real rootdisk. It typically loads additional modules not built in to the kernel. When this initial program exits, the kernel loads the real root image and booting continues normally. For further information on initrd, see your local file /usr/src/linux/Documentation/initrd.txt and ftp://elserv.ffm.fgan.de/pub/linux/loadlin-1.6/initrd-example.tgz
The following are summaries of how each distribution's installation disks seem to work, based on inspecting their filesystems and/or source code. We do not guarantee that this information is completely accurate, or that they have not changed since the versions noted.
Slackware (v.3.1) uses a straightforward LILO boot similar to what is described in Section 6.1. The Slackware bootdisk prints a bootup message (“Welcome to the Slackware Linux bootkernel disk!”) using LILO's message parameter. This instructs the user to enter a boot parameter line if necessary. After booting, a root filesystem is loaded from a second disk. The user invokes a setup script which starts the installation. Instead of using a modular kernel, Slackware provides many different kernels and depends upon the user to select the one matching his or her hardware requirements.
RedHat (v.4.0) also uses a LILO boot. It loads a compressed ramdisk on the first disk, which runs a custom init program. This program queries for drivers then loads additional files from a supplemental disk if necessary.
Debian (v.1.3) is probably the most sophisticated of the installation disk sets. It uses the SYSLINUX loader to arrange various load options, then uses an initrd image to guide the user through installation. It appears to use both a customized init and a customized shell.
![]() |
This section was contributed by Rizwan Mohammed Darwe (rizwan AT clovertechnologies dot com) |
This section assumes that you are familiar with the process and workings of writing CDs in linux. Consider this to be a quick reference to include the ability to boot the CD which you will burn. The CD-Writing-HOWTO should give you an in-depth reference.
For the x86 platform, many BIOS's have begun to support bootable CDs. The patches for mkisofs is based on the standard called "El Torito". Simply put, El Torito is a specification that says how a cdrom should be formatted such that you can directly boot from it.
The "El Torito" spec says that any cdrom drive should work (SCSI or EIDE) as long as the BIOS supports El Torito. So far this has only been tested with EIDE drives because none of the SCSI controllers that has been tested so far appears to support El Torito. The motherboard definately has to support El Torito. How do you know if your motherboard supports "El Torito"? Well, the ones that support it let you choose booting from hard disk, Floppy, Network or CDROM.
The El Torito standard works by making the CD drive appear, through BIOS calls, to be a normal floppy drive. This way you simply put any floppy size image (exactly 1440k for a 1.44 meg floppy) somewhere in the ISO filesystem. In the headers of the ISO fs you place a pointer to this image. The BIOS will then grab this image from the CD and for all purposes it acts as if it were booting from the floppy drive. This allows a working LILO boot disk, for example, to simply be used as is.
Roughly speaking, the first 1.44 (or 2.88 if supported) Mbytes of the CD-ROM contains a floppy-disk image supplied by you. This image is treated like a floppy by the BIOS and booted from. (As a consequence, while booting from this virtual floppy, your original drive A: (/dev/fd0) may not be accessible, but you can try with /dev/fd1).
First create a file, say "boot.img", which is an exact image of the bootable floppy-disk which you want to boot via the CD-ROM. This must be an 1.44 MB bootable floppy-disk. The command below will do this
dd if=/dev/fd0 of=boot.img bs=10k count=144
|
Place this image somewhere in the hierarchy which will be the source for the iso9660 filesystem. It is a good idea to put all boot related files in their own directory ("boot/" under the root of the iso9660 fs, for example).
One caveat -- Your boot floppy must load any initial ramdisk via LILO, not the kernel ramdisk driver! This is because once the linux kernel starts up, the BIOS emulation of the CD as a floppy disk is circumvented and will fail. LILO will load the initial ramdisk using BIOS disk calls, so the emulation works as designed.
The El Torito specification requires a "boot catalog" to be created as well. This is a 2048 byte file which is of no interest except it is required. The patchwork done by the author of mkisofs will cause it to automatically create the boot catalog, but you must specify where the boot catalog will go in the iso9660 filesystem. Usually it is a good idea to put it in the same place as the boot image, and a name like boot.catalog seems appropriate.
So we have our boot image in the file boot.img, and we are going to put it in the directory boot/ under the root of the iso9660 filesystem. We will have the boot catalog go in the same directory with the name boot.catalog. The command to create the iso9660 fs in the file bootcd.iso is then:
mkisofs -r -b boot/boot.img -c boot/boot.catalog -o bootcd.iso . |
Now burn the CD with the usual cdrecord command and it is ready to boot.
The first step is to get hold of the bootable image used by the source CD. But you cannot simply mount the CD under linux and dd the first 1440k to a floppy disk or to a file like boot.img. Instead you simply boot with the source CD-ROM.
When you boot the Win98 CD you are dropped to A: prompt which is the actual ramdisk. And D: or Z: is where all the installables are residing. By using the diskcopy command of dos copy the A: image into the actual floppy drive which is now B: The command below will do this.
diskcopy A: B: |
A: See Section 7, above.
A: See Section 10, above.
Q: How do I use higher-density (> 1440K) diskettes? How do I figure out which densities will work with my diskette drive?
A: See Section Section 8, above, for the comments by Alain Knaff on this subject. His is the most authoritative answer I know of.
A: This probably should be explained better in the text, but I'll put an answer here for the time being.
First, do not attempt to use the rdev or ramsize commands to do this, no matter what their documentation says. The ramdisk word no longer determines the size of ramdisks.
Second, keep in mind that ramdisks are actually dynamic; when you set a ramdisk size you aren't allocating any memory, you're just setting the limit of how large it can grow. Don't be afraid to set these fairly large (eg, 8 or even 16 meg). The RAM space is not actually consumed until you need it. You can set these limits in one of several ways.
Use the ramdisk_size=NNN command line parameter. You can either enter this manually or use a command like append="ramdisk_size=NNN" with LILO.
If you're using LILO, you can use a kernel option like ramdisk=8192K in the lilo.conf file.
Change the kernel configuration option CONFIG_BLK_DEV_RAM_SIZE and recompile your kernel.
A: See section Section 11.