\documentclass{lpiclab}

\RCS $Revision: 1.15 $

\usepackage{%
  key%  This package used to kill Table of Contents until neutered fancybox.sty
  ,alltt%
  ,makeidx%
  ,moreverb%
  ,multicol%
}
\ifx\pdftexversion\undefined \else
  \usepackage[pdfpagemode=None,pdfauthor={Nick Urbanik}]{hyperref}
\fi

\renewcommand*{\subject}{LPIC 102}
\newcommand*{\labTitle}{Using grub to Boot various Operating Systems}
\providecommand*{\grub}{\textsf{grub}\xspace}
\providecommand*{\LILO}{\acro{LILO}\xspace}
\providecommand*{\MBR}{\acro{MBR}\xspace}

% See page 367 of The LaTeX Companion:
\makeatletter
\renewenvironment{theindex}{%
  \addcontentsline{toc}{section}{\indexname}%
  \pagestyle{plain}\let\item\@idxitem
  \begin{multicols}{2}[\section*{\indexname}]%
    \raggedright%
    \raggedcolumns%
    \par\bigskip}%
  {\end{multicols}%
}
\makeatother

\makeindex

\begin{document}
\tableofcontents
\section{Aim}
\label{sec:aim}
After completing these exercises, you will:
\begin{itemize}
\item be able to set up \grub to boot multiple operating systems
\item be able to recover a hard disk with a corrupt \MBR
\item understand how to start a Linux system in single user mode
\item understand how to move between runlevels while the computer is running
\end{itemize}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{What You Will Do}
\label{sec:what-you-will-do}

Today, you will:
\begin{itemize}
\item boot Linux, and create a \grub installation disk.  I expect you
  will finish this in twenty minutes.
\item boot your computer from the \grub installation disk, and
  re-install \grub I expect this will take you about ten minutes.
  Then we will discuss what you have done.
\item You will then destroy your \MBR.  This is an exercise only; you
  should not do this at work!  The aim is to demonstrate that you can
  recover from a boot failure.  This should take no more than ten
  minutes.  We will then discuss what you have done.
\item You will re-install \grub into the \MBR, and be able to boot
  your computer again.  This should take less than ten minutes (you
  have done this already!)
\item You will modify your \grub configuration to boot the operating
  systems on the internal hard disk. This will take you less than
  twenty-five minutes.  We will discuss this after you have done it.
\item You will use \grub to boot your computer into \emph{single user
    mode}.  This will take no more than seven minutes.
\item You will investigate single user mode.  We will discus this as
  we investigate.
\item You will investigate all the other run levels.  This will occupy
  the remaining time in the laboratory.
\end{itemize}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Background}
\label{sec:background}

It is often useful to be able to boot more than one operating system
from one hard disk.  There are some commercial packages to achieve
this; examples include \emph{BootMagic} with \emph{Partition Magic}
and \emph{System Commander}\e.  There are a number of free software
packages also, such as \LILO and \acro{OSBS}.  However, we will use
\textsf{grub}, because it is very reliable and flexible, and we use it
to start Linux.  Today we see how to use \textsf{grub} to boot Linux
and one or more additional operating systems.


I assume that you have set up the \texttt{sudo} command, and
understand how to use it.  If not, please read the document I have
written about it first.


\subsection{Installing \grub in MBR from a floppy, and from the OS}
\label{sec:from-floppy-and-from-OS}

\textsf{Grub} can be installed into the \MBR either directly from a
floppy disk, or from within the operating system.  We will look at
both, since each has its advantages and disadvantages.


\subsubsection{Real and Protected Mode: OS cannot run BIOS routines}

When the operating system is running, it runs in \emph{protected}
mode.  When the \BIOS is running, it runs in \texttt{real} mode.  The
operating system cannot call \BIOS routines while it is running; it
can only guess what the \BIOS would do, and that is not always
correct.  For example, you can change the order in which hard disks
boot in the \BIOS setup, and the \OS cannot predict that you will do
that!

\subsubsection{Making sure \grub knows what the BIOS will do}

By creating a \grub installation floppy, you can be sure that \grub
and the \BIOS agree with each other, since \grub runs in real mode,
using the \BIOS, before the operating system boots.


\subsubsection{Using \texttt{grub-install} from the OS: the quick but
  less reliable way}
\index{Installing grub from the OS@Installing \grub from the \OS|(}
Sometimes, you may want to install \grub into the \MBR without
shutting down the \OS.  There is a slight possibility that the
\BIOS and the \OS disagree about which disk comes first, so there is a
slight possibility that you will need to use the \grub installation
disk (or a custom boot disk) to fix it.

To install \grub into the \MBR, we simply type:
\begin{alltt}
$ \textbf{sudo /sbin/grub-install /dev/hda}
\end{alltt}%$
This will install \grub into the \MBR of \texttt{/dev/hda} from the
current \grub installation.
\index{Installing grub from the OS@Installing \grub from the \OS|)}


\subsection{The way \grub refers to devices}
\label{sec:grub-devices}

\textsf{Grub} starts numbering devices from zero.

The device syntax used in \grub is a bit different from what you
may have seen before in your operating system(s), and you need to know
it so that you can specify a drive/partition.

Look at the following examples and explanations:
\begin{alltt}
(fd0)     
\end{alltt}
   
First of all, \grub requires that the device name is enclosed with
`\texttt{(}' and `\texttt{)}'. The `\texttt{fd}' part means that it is
a floppy disk. The number `\texttt{0}' is the drive number, which is
counted from \emph{zero}. This expression means that \grub will use
the whole floppy disk.
\begin{alltt}
(hd0,1)  
\end{alltt}

Here, `\texttt{hd}' means it is a hard disk drive. The first integer
`\texttt{0}' indicates the drive number, that is, the first hard disk,
while the second integer, `\texttt{1}', indicates the partition number
Once again, please note that the partition numbers are counted from
\emph{zero}, not from one.  This expression means the second partition
of the first hard disk drive. In this case, \grub is referring to one
partition of the disk, instead of the whole disk.
\begin{alltt}
(hd0,4)  
\end{alltt}

This specifies the first logical partition of the first hard disk
drive.  Note that the partition numbers for logical partitions are
counted from `\texttt{4}', regardless of the actual number of primary
partitions on your hard disk.

\index{files!\grub|(}
Now the question is, how to specify a file? Again, see this example:
\label{sec:specifying-a-file}
\begin{alltt}
(hd0,8)/boot/vmlinuz-2.4.18-14  
\end{alltt}

This specifies the file named `\texttt{/boot/vmlinuz-2.4.18-14}',
found on the ninth partition of the first hard disk drive.
\index{files!\grub|)}

\subsection{The Structure of the Master Boot Record}
\index{master boot record|(}
The master boot record (\MBR) has three sections; see
figure~\vref{fig:mbr}.  The first 446 bytes contain the code that boots
the operating system; the next 62 bytes contain the partition table.
The last two bytes contain a ``Magic number'' that helps identify this
sector as a master boot record.

\begin{figure}[htb]
  \centering%
  \begin{tabular}{r|c|}
    \cline{2-2}
    \tt 0x000 & \\
    & Program code \\
    & \\
    & \\
    \cline{2-2}
    \tt 0x1BE & Partition table \\
    & \\
    \cline{2-2}
    \tt 0x1FE & Magic number (0xAA55) \\
    \cline{2-2}
  \end{tabular}
  \caption{The master boot record structure.}
  \label{fig:mbr}
\end{figure}
\index{master boot record|)}

\subsection{What does \grub do when you install it using \texttt{setup}?}
\label{sec:grub-installation}

In section~\vref{sec:using-disk-to-install-grub-in-MBR}, you will use
a \grub installation floppy disk to install \grub into the \MBR of
your hard disk.  What is going on?

There are three steps:
\begin{alltt}
grub> \textbf{find /boot/grub/stage2}
grub> \textbf{root (hd0,8)}
grub> \textbf{setup (hd0)}
\end{alltt}
So what is going on in each step?

\subsubsection{using \texttt{find} in \grub to locate your Linux
  partition containing your \texttt{/boot} directory}
\label{sec:grub-find}

The aim of the first step is to identify paritions on your computer
that contain the directory \texttt{/boot}, and the \texttt{grub}
directory below that.  \textsf{Grub} needs this to be able to install
a good \MBR.  The \texttt{find} command searches all the disks on the
computer for the file \texttt{/boot/grub/stage2}, and it lists all
partitions where it found it.

The second step, using the \grub \texttt{root} command, mounts the
partition you found in the previous step.  This identifies the type
of file system (for example, \texttt{ext2})


\subsubsection{The \grub setup command}
\label{sec:grub-setup}

\index{grub setup command@\grub \texttt{setup} command|(}
The third step is the important one that actually sets up the \MBR
correctly.  The \grub \texttt{setup} command:
\begin{enumerate}
\item Determines the \ldots\texttt{\_stage1\_5} file that matches the
  type of file system found in the previous step
\item puts a list of the sector numbers that contain the file into the
  code for the \MBR
\item installs the code (446 bytes of it) into the \MBR.
\end{enumerate}
\index{grub setup command@\grub \texttt{setup} command|)}


\subsection{How does \grub work when it boots your computer from the
  hard disk?}
\label{sec:how-does-grub-work}

\index{grub!how it works|(}
Here is a summary:
\begin{enumerate}
\item \BIOS loads the code in the \MBR, Stage 1, that you installed in
  the procedure discussed in section~\vref{sec:grub-setup}.
  
\item This short assembly language code, Stage 1 from the \MBR, reads
  the file
  \texttt{/boot/\allowbreak{}grub/\allowbreak{}e2fs\_stage1\_5} (if
  your \texttt{/boot} partition has a file system of type
  \texttt{ext3}).  The physical location of this file is hard coded
  into the \MBR during the installation of Stage 1 into the \MBR, as
  described in section~\vref{sec:grub-setup}.
  
\item The code in
  \texttt{/boot/\allowbreak{}grub/\allowbreak{}e2fs\_stage1\_5} can
  now read the file system, and loads the file
  \texttt{/boot/grub/stage2} into \RAM, and then executes that code.

\item Stage 2 now contains a sophisticated boot loader, which reads
  your hard disk and loads the menu file
  \texttt{/boot/grub/grub.conf}.  The menu allows you to select an OS
  using arrow keys, and to select using the \key{Enter} key.  It also
  allows you to enter the same commands interactively, so that you can
  boot any operating system on the computer, even if you do not have a
  menu item for that \OS.
\end{enumerate}
\index{grub!how it works|)}


\index{grub!documentation|(}
\subsection{Reading the Documentation for \grub}
\label{sec:grub-documentation}
The \grub manual consists of about 50 pages of online material.  To
read it in Emacs, type \key{Ctrl-h Ctrl-i}, then \texttt{m\,grub}.
You can view the same documentation using another standalone browser
with \texttt{pinfo grub}.  As a last resort, you can view the same
documentation by typing \texttt{info grub}, but my favourite way is
in Emacs\@.
\index{grub!documentation|)}

\subsection{The \grub Configuration File \texttt{/boot/grub/grub.conf}}
\label{sec:grub.conf}

\index{grub!configuration file|(}
Here is an example \grub configuration file,
\texttt{/boot/grub/grub.conf}:
\begin{listing}{1}
default=0
timeout=10
splashimage=(hd0,8)/boot/grub/splash.xpm.gz
title Red Hat Linux (2.4.18-14)
        root (hd0,8)
        kernel /boot/vmlinuz-2.4.18-14 ro root=LABEL=/1
        initrd /boot/initrd-2.4.18-14.img
title Windows 2000
        rootnoverify (hd0,0)
        chainloader +1
\end{listing}
Let's examine this line by line.  Of course, the \grub manual (see
section~\vref{sec:grub-documentation}) gives details of each \grub
command.

\begin{alltt}
default=0
\end{alltt}
The first line selects which operating system will boot if no \grub
menu selection is made.  The first \texttt{title} line in the menu
has index 0, so this will boot Linux if you just turn the computer on
and do not press any arrow key and then press \key{Enter}.

The second \texttt{title} has index 1, so if you want to automatically
boot Windows, you would change the line to \texttt{default=1}.

\begin{alltt}
timeout=10
\end{alltt}
The second line is the time in seconds before the default entry will
be automatically booted.

\begin{alltt}
splashimage=(hd0,8)/boot/grub/splash.xpm.gz
\end{alltt}
The third line selects a graphics image that will be used as a
background to the menu.  See section~\vref{sec:specifying-a-file} for
the meaning of \texttt{(hd0,8)/boot/grub/splash.xpm.gz}.

\begin{alltt}
title Red Hat Linux (2.4.18-14)
\end{alltt}
Line 4 provides the text that will appear in the first menu entry.

\begin{alltt}
        root (hd0,8)
\end{alltt}
Line 5 means: select the ninth partition on the first hard disk as
containing the file \texttt{stage2}, and mount it.  Refer to
section~\vref{sec:grub-devices} for more about the way \grub names
devices and partitions.

\index{kernel!command line parameters|(}
\begin{alltt}
        kernel /boot/vmlinuz-2.4.18-14 ro root=LABEL=/1
\end{alltt}
Line 6 is the actual operating system kernel that will be loaded.  The
kernel can take command line arguments:
\begin{description}
\item[\texttt{ro}] means ``read only''; the root partition will be
  mounted read only at first.  Later, during the boot process, the
  partition will be re-mounted read write after it has been checked
  for errors.
  
  \index{partition labels|(}
  \index{LABEL|(}
\item[\texttt{root=LABEL=/1}] Each partition of type \texttt{ext2} or
  \texttt{ext3} can have a label.  You can view the labels of mounted
  partitions with \texttt{mount -l}; you can change the labels with
  the \texttt{e2label} command.

  Here we are telling the kernel that it should mount the partition
  with label ``\texttt{/1}'' as the root (`\texttt{/}') partition.
  
  Note that labels should be \texttt{unique} on a computer system: if
  two disks have the same label, then the kernel might mount the wrong
  partition as the `\texttt{/}' partition.
\end{description}
  \index{LABEL|)}%
  \index{partition labels|)}%
You can also add other command line arguments.  There are many that
the kernel can accept; a number will select the runlevel that the
operating system will default to---see
section~\vref{sec:booting-into-single-user-mode}, particularly item
number~\ref{itm:kernel-param-single}.
\index{kernel!command line parameters|)}

\begin{alltt}
        initrd /boot/initrd-2.4.18-14.img
\end{alltt}
Line 7 specifies a file containing device drivers that will be put
into a temporary \RAM disk before the kernel accesses the hard disk.
This solves a problem: if the kernel needs drivers to read the hard
disk, how can the kernel get the drivers?  The answer is from the
``\texttt{initrd}'' \RAM disk.  You can generate an \texttt{initrd}
image file using the program \texttt{mkinitrd}.

\begin{alltt}
title Windows 2000
\end{alltt}
Line 8 gives the text for the second item in the \grub boot menu.

\begin{alltt}
        rootnoverify (hd0,0)
\end{alltt}
Line 9 tells \grub that it should read from this partition
(\texttt{/dev/hda1}), but not try to mount it.

\begin{alltt}
        chainloader +1
\end{alltt}
Line 10 means: read from the root device (in this case, the device is
\texttt{(hd0,0)}, or \texttt{/dev/hda1}), starting at sector zero, and
finishing just before sector 1.  In other words, it loads the first
sector from this partition, and transfers control to it.  This will
boot Windows, since Windows has installed a boot loader in that
sector.
\index{grub!configuration file|)}

\index{grub!chainloading|(}
\index{chainloading|(}
\subsection{Chainloading: Can I Install \grub Anywhere Besides the MBR?}
\label{sec:install-in-partition}

Yes!  You can also install \grub in the boot partition of your
operating system.  This is an option when installing Red Hat Linux\@.
When would you want to do that?  You would do this if you are using
another boot loader to boot your operating system.  This is called
\emph{chainloading}.  We do this when we boot Windows: \grub
chainloads the Microsoft bootloader from the first sector of the
partition where Windows is installed.


\subsubsection{Example: many Linux installations on one hard disk:
  part time classes}
\begin{table}[htb]
  \centering%
  \begin{tabular}[t]{@{}cccc@{}}
    \toprule%
    \emph{group} & \emph{partition where \texttt{\textup{/}} mounted}
    & \emph{\grub device name} & \emph{where \grub \texttt{stage1} installed}\\
    \midrule%
    A1 & \texttt{/dev/hda1} & \texttt{(hd0,0)} & \MBR \texttt{(hd0)} \\
    A2 & \texttt{/dev/hda5} & \texttt{(hd0,4)} & \texttt{(hd0,4)}\\
    B & \texttt{/dev/hda7} & \texttt{(hd0,6)}  & \texttt{(hd0,6)} \\
    \bottomrule
  \end{tabular}
  \caption{The partitioning arrangement for part time classes.}
  \label{tab:part-time-partitions}
\end{table}

For example, in part-time \OSSI classes, three students share one hard
disk.  The first laboratory group, group~A1, boots Linux from the
first primary partition, \texttt{/dev/hda1}.  The second group A2
installs Linux into the logical partition \texttt{/dev/hda5}, while
students from the third laboratory class installs Linux into the
logical partition \texttt{/dev/hda7}.  See
table~\vref{tab:part-time-partitions}.  It is best if each class takes
responsibility for booting their own operating system.  The way it is
set up is like this.
\begin{enumerate}
\item Group A1 install \texttt{stage1} of \grub into the \MBR.  Their
  \grub cconfiguration file looks like this:
\begin{verbatim}
default=0
timeout=10
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
title Red Hat Linux for group A1 (2.4.18-14)
        password --md5 $1$tupXW/$yCwElzrIIVoE0cfnxTlUS0
        root (hd0,0)
        kernel /boot/vmlinuz-2.4.18-14 ro root=/dev/hda1
        initrd /boot/initrd-2.4.18-14.img
title Red Hat Linux for group A2
        rootnoverify (hd0,4)
        chainloader +1
title Red Hat Linux for group B
        rootnoverify (hd0,6)
        chainloader +1
\end{verbatim}%$
  
\item Group A2 has a \texttt{/boot/grub/grub.conf} file that
  looks like this:
\begin{verbatim}
default=0
timeout=1
splashimage=(hd0,4)/boot/grub/splash.xpm.gz
title Red Hat Linux A2 (2.4.18-14)
        password --md5 $1$r0qXW/$Y7.OuCvhJcKrOgERkZtkt.
        root (hd0,4)
        kernel /boot/vmlinuz-2.4.18-14 ro root=/dev/hda5
        initrd /boot/initrd-2.4.18-14.img
\end{verbatim}%$
  
\item Group B have a similar configuration to group A2, but with the
  root set to \texttt{/dev/hda7}.


\item The way it works is that if group A2 want to boot their \OS,
  they select their menu item and press \key{Enter}\@.  Their
  operating system then boots.  What is happening is:
  \begin{itemize}
  \item The menu installed by group A1 appears, offering to boot any of
    the three installed version of Linux
    
  \item If you select the second choice (for group A2), then the \grub
    installed in the \MBR and in \texttt{/dev/hda1} \emph{chainloads}
    \grub from the first sector of \texttt{/dev/hda5}.
    
  \item The second \grub starts up, and after a 1 second delay, boots
    the Linux installed in \texttt{/dev/hda5}.
  \end{itemize}
  This is a case of a chain of boot loaders, where one bootloader
  loads another boot loader, which finally loads the operating system.
  
\item The advantage is that the \grub set up in \texttt{/dev/hda1} by
  group A1 does not need to know what version of kernel is set up in
  partitions \texttt{/dev/hda5} or \texttt{/dev/hda7}.  The other two
  groups can upgrade their kernels without disturbing the boot
  process, which begins with the \grub installed by group A1\@.

\index{password!\grub|(}
\index{grub passwords@\grub passwords|(}
\item What about the ``\texttt{password}'' lines?  These require a
  password to be entered before that boot menu item will boot.  It
  provides protection for students of one group from
  accidentally booting the partition of another group.
\index{grub!chainloading|)}
\index{chainloading|)}

  How to generate the password?
  \begin{alltt}
$ \textbf{grub-md5-crypt}
Password: \meta{type your password here}
$1$r0qXW/$Y7.OuCvhJcKrOgERkZtkt.
  \end{alltt}
  Then use your mouse to copy and paste the hashed password into the
  test editor editing \texttt{/boot/grub/grub.conf}.
\end{enumerate}
\index{grub passwords@\grub passwords|)}
\index{password!\grub|)}

\subsection{Runlevels and \texttt{init}}
\label{sec:init-and-runlevels}

\begin{itemize}
\item  Linux has seven modes of operation
\item  Referred to as \emph{runlevels}
  
\item The Linux Standards Base
  (\url{http://www.linuxbase.org/spec/refspecs/LSB_1.1.0/gLSB/runlevels.html})
  defines the following standard runlevels that all distributions must
  follow to be compliant:

  \noindent%
  \begin{tabular}[t]{ll}
    0 & halt\\
    1 & single user mode \\
    2 & multiuser with no network services exported \\
    3 & normal/full multiuser \\
    4 & reserved for local use, default is normal/full multiuser \\
    5 & multiuser with \texttt{xdm} or equivalent \\
    6 & reboot
  \end{tabular}

\end{itemize}

\subsubsection{Single User Mode}
\label{sec:runlevels-and-single-user-mode}

\index{single user mode|(}%
Often, booting into \emph{single user mode} is the solution to a
problem.  Single user mode is a bit like ``Safe Mode'' in Windows\@.
No networking is started, and only one user (\texttt{root}) can log
in.  It is a quick way to fix a forgotten \texttt{root} password, and
it is a good way to fix problems that prevent services from starting.
Single user mode is also called runlevel 1.

\subsubsection{How to Change Runlevels with \texttt{init}}
\label{sec:how-to-change-runlevel}

\begin{itemize}
\item The \texttt{init} process governs runlevels.  \texttt{init} is
  \emph{the first program that the kernel runs}.

\item You can change runlevels as the administrator by
\begin{alltt}
$ \textbf{sudo /sbin/init \textnormal{\emph{level}}}
\end{alltt}%$

For example, if you are currently in runlevel 5, you can change to
runlevel 3 by executing the command:
\begin{alltt}
$ \textbf{sudo /sbin/init 3}
\end{alltt}%$
Runlevel 3 is useful for fixing problems with starting X (the
graphical user interface).

You can change to single user mode from any other level by:
\begin{alltt}
$ \textbf{sudo /sbin/init 1}
\end{alltt}%$

If you are in single user mode, you can change to runlevel 5 by the
same method:
\begin{alltt}
# \textbf{init 5}
\end{alltt}
\end{itemize}
\index{single user mode|)}%

The program \texttt{/sbin/runlevel} will show you the current
runlevel, and the previous runlevel.

There is an exercise in
section~\vref{sec:booting-into-single-user-mode} which explains how to
boot the computer directly into any runlevel, using \grub.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Procedure}
\label{sec:procedure}

Before you begin:
\begin{itemize}
\item Linux should be installed
  
\item You need a good floppy disk to create a \grub installation disk.
\end{itemize}

Here I am going to assume that you have installed Windows so that its
boot files are in partition \texttt{/dev/hda1}.


\subsection{Creating a Grub Installation Disk}
\label{sec:grub-installation-disk}


\begin{enumerate}
\item Use a good, empty, formatted disk.  In Linux, you can do:
\begin{alltt}
$ \textbf{fdformat /dev/fd0}
\end{alltt}%$
to make sure that the disk has no bad sectors.
\begin{explanation}
  This does a \emph{low-level format} of the floppy disk.  It divides
  the floppy into the appropriate number of cylinders (80), and the
  appropriate number of sectors per track (18), and writes information
  onto the disk so that the file system may be put into these
  sectors.  Each sector contains 512 bytes, so there  are $80 \times
  18 \times 512 = 737280$ bytes on one side, and so a total of $737280
  \times 2 = 1474560$ bytes, or 1440 kilobytes.
\end{explanation}


\item Then make the \FAT file system with:
\begin{alltt}
$ \textbf{/sbin/mkdosfs /dev/fd0}
\end{alltt}%$
\textbf{\emph{OR}}\\[1ex]
you could, instead of a \FAT filesystem, make an extended 2 file
system like this if you want to:
\begin{alltt}
$ \textbf{/sbin/mke2fs /dev/fd0}
\end{alltt}%$
\begin{explanation}
  Note that when formatting a floppy disk, Microsoft \texttt{format}
  does \emph{both} a low level format and adds the file system (with a
  ``high level format'') at the same time.  However, when the same
  program formats a hard disk, it performs a high level format only.
  Linux tools keep the two operations separate.
\end{explanation}

\item \label{itm:mount}Then mount the floppy disk.  You can do that
  easily with the shell functions \texttt{\textbf{a}} and
  \texttt{\textbf{z}} I appended to your $\sim$\texttt{/.bashrc} login
  script.  To do it manually:
\begin{alltt}
$ \textbf{mount /dev/fd0}
\end{alltt}%$
Or using my shell functions:
\begin{alltt}
$ \textbf{a}
\end{alltt}%$
\begin{explanation}
  The end result is that the floppy disk is mounted on the directory
  \texttt{/mnt/floppy}.  This means that the contents of the floppy
  disk are available under that directory.
\end{explanation}
\item Check the the floppy is \emph{mounted} with the \texttt{mount}
  command.  First type:
\begin{alltt}
$ \textbf{mount}
\end{alltt}%$
to see all the mounted filesystems on your computer.  Hmm, there is
rather a lot.  So let us filter out all but the one we are looking for
with \texttt{grep}:
\begin{alltt}
$ \textbf{mount | grep /dev/fd0}
\end{alltt}%$
\begin{explanation}
  You should see which directory the floppy disk device
  (\texttt{/dev/fd0}) is \emph{mounted} on.  If you see no output,
  your floppy disk is not mounted, so go back to item~\ref{itm:mount}.
\end{explanation}

\item Now install \grub into the floppy disk with:
  \begin{alltt}
$ \textbf{/sbin/grub-install --root-directory=/mnt/floppy '(fd0)'}
  \end{alltt}%$

\item When the installation completes successfully (no error
  messages), then unmount the floppy.  Do not remove the floppy before
  you unmount it:
  \begin{alltt}
$ \textbf{umount /dev/fd0}
  \end{alltt}%$
  \begin{explanation}
    Note that if your current directory is on the floppy disk, you
    will not be able to unmount it.  It is a bit like trying to lift
    a wooden plank you are standing on.  You need to get off any
    directory on the device before you can unmount it.
  \end{explanation}
Or, using my handy little shell functions:
\begin{alltt}
$ \textbf{z}
\end{alltt}%$

\item Remove your boot floppy only \emph{after} floppy disk activity has
  stopped, as shown by the light going out on the floppy drive.  You
  now have a \grub installation disk.
\end{enumerate}

\subsection{Using the \grub installation disk to install \grub into
  the MBR}
\label{sec:using-disk-to-install-grub-in-MBR}

Please refer to section~\vref{sec:grub-installation} while doing this
activity.
\begin{enumerate}
\item Put your \grub installation disk into the computer, and restart it.

\item After a while, you should see the \grub prompt.

\item Select which partition you are going to set up \grub for.  This
  is the partition that contains the file \texttt{/boot/grub/stage2}
%% \begin{alltt}
%% grub> \textbf{root (hd0,8)}
%% \end{alltt}
%% \begin{explanation}
%%   This corresponds to \texttt{/dev/hda9}.  \grub numbers devices from
%%   zero, so \texttt{(hd0)} is the first hard disk, \texttt{(hd1)} is
%%   the second hard disk (i.e., \texttt{/dev/hdc}), and so on.
%%   Similarly partitions are numbered from zero, with
%%   \texttt{/dev/hda1} called \texttt{(hd0,0)} by \grub,
%%   \texttt{/dev/hda3} is called \texttt{(hd0,2)}, and so on.
%% \end{explanation}
  It is best to let \grub determine which partition holds your Linux
  \grub files, as described in section~\vref{sec:grub-find}:
\begin{alltt}
grub> \textbf{find /boot/grub/stage2}
\end{alltt}
This will search all the disks in your computer for the file name
\texttt{/boot/grub/stage2} and show the partitions which contain the
file.  Look for the right partition, and select it as your root
device:
\begin{alltt}
grub> \textbf{root (hd0,8)}
\end{alltt}
This will determine the file system type of the partition, and mount
the partition.

\item Once you've set the root device correctly, run the command
  \texttt{setup}:
  \begin{alltt}
grub> \textbf{setup (hd0)}
  \end{alltt}
  \begin{explanation}
    This will put the file \texttt{stage1} into the \MBR on your hard
    disk, along with a list of hard disk block numbers telling it
    where to find the file \texttt{e2fs\_stage1\_5}.  Later, when
    \grub loads this file, it will then be able to read individual
    files on the hard disk, and will be able to load the file
    \texttt{/boot/grub/stage2}, which provides most of the
    functionality of \grub.
  \end{explanation}
\end{enumerate}


\subsection{Destroying your Master Boot Record!}
\label{sec:destroying-mbr}

Note: this is an exercise only.  Do not do this in your workplace!
The aim here is to get your computer into an unbootable state, and to
demonstrate that you can recover from this situation.  It is
\emph{never} necessary to delete the \MBR for you to install \grub.

Here we are going to do some very dangerous things, so \emph{be
  \textbf{very} careful}.  Look once, look twice, look \emph{three}
times before you press \key{Enter}\@.  There is no turning back if you
destroy data on your disk beyond your \MBR.

First you will mount your \grub installation disk, and make sure it is
mounted.  Then you will make a backup of your \MBR into a file on your
\grub installation boot disk by copying the first 512 bytes from your
hard disk to a file on your floppy disk.  Finally you will overwrite
the first 446 bytes of your master boot record with binary zeros,
making your computer unbootable.
  \begin{enumerate}
    \index{master boot record!backing up|(}
  \item Mount your \grub installation disk, and make sure it is mounted:
  \begin{alltt}
$ \textbf{mount /dev/fd0}
$ \textbf{mount | grep fd0}
  \end{alltt}
  
\item Now use the data dump program to backup the master boot record
  into a file on your floppy disk:
  \begin{alltt}
$ \textbf{sudo dd if=/dev/hda of=/mnt/floppy/master-boot-record.img bs=512 count=1}
  \end{alltt}%$
    \index{master boot record!backing up|)}

\item Now \emph{destroy} your master boot record, \emph{carefully}:
  \begin{alltt}
$ \textbf{sudo dd if=/dev/zero of=/dev/hda bs=\underline{446} count=1}
  \end{alltt}%$
  \begin{explanation}
    \textbf{Note} that the block size is 446 bytes and \emph{not}
    512.  The partition table is contained in the last 64 bytes of the
    \MBR, so don't delete that!  See figure~\vref{fig:mbr}.

    The device \texttt{/dev/zero} returns 0 whenever you read it, so
    this command will totally clear the code part of the \MBR, and
    replace it with all binary zero bits.
  \end{explanation}

\item Now try to boot your hard disk.  It should fail.
\end{enumerate}


\subsection{Recovering From Disaster}
\label{sec:disaster-recovery}

\begin{enumerate}
\item Now use your \grub installation disk to re-install \grub in the
  \MBR.
\item Verify that you can boot both Linux and Windows\@.
\end{enumerate}


\subsection{Booting an operating system interactively with a \grub
  installation disk}
\label{sec:using-grub-interactively}

\index{Windows!booting from second disk|(}
\index{grub map command@\grub \texttt{map} command|(}
\subsubsection{Overcoming a limitation of the Windows Bootloader}

The Windows bootloader will only boot from the first hard disk
(``first'' is defined by the \BIOS before the operating system
starts).  How can we boot Windows from the second hard disk?  By
having \grub tell the \BIOS to swap the hard disks, so that it thinks
\texttt{/dev/hdc} is the first hard disk, and \texttt{/dev/hda} is the
second hard disk.  Read about the \texttt{map} \grub command in the
\grub manual; see section~\vref{sec:grub-documentation}.

\subsubsection{Experiments with \grub}

You can use the \grub shell to interactively boot any operating system
installed on a computer.  Try this:
\begin{enumerate}
\item Boot your computer with your \grub installation disk
\item at the \texttt{grub>} prompt, type the following:
  \begin{alltt}
grub> \textbf{map (hd1) (hd0)}
grub> \textbf{rootnoverify (hd1,0)}
grub> \textbf{chainloader +1}
grub> \textbf{boot}
  \end{alltt}
\item What happens?  Which partition did this operating system boot
  from?
\item Try this sequence of \grub commands:
  \begin{alltt}
grub> \textbf{map (hd1) (hd0)}
grub> \textbf{rootnoverify (hd0)}
grub> \textbf{chainloader +1}
grub> \textbf{boot}
  \end{alltt}
\item Test it.  Explain what is happening.
\end{enumerate}
\index{Windows!booting from second disk|)}
\index{grub map command@\grub \texttt{map} command|)}

\subsection{Setting up a Menu to Boot other Operating Systems}

Refer to section~\vref{sec:grub.conf} to do this activity.
\begin{enumerate}
\item Make a backup of your grub configuration file to the
  \texttt{tmp} directory (the \texttt{root} user cannot write to your
  network home directory):
  \begin{alltt}
$ \textbf{sudo cp /boot/grub/grub.conf /tmp/grub.conf)}
  \end{alltt}%$

\item Now edit your grub configuration file so that it can boot Linux
  from the internal hard disk, and can also boot Windows from the
  internal hard disk.  You may need to refer to
  section~\vref{sec:using-grub-interactively} for some ideas on how to
  boot Windows from the second hard disk.
  
\item Test your setup and verify that you can boot these operating
  systems.
\end{enumerate}

\subsection{Investigating Runlevels}
\label{sec:investigating-runlevels}

Refer to section~\vref{sec:init-and-runlevels} when doing this
activity.

\subsubsection{Booting into Runlevel 1, or Single User Mode}
\label{sec:booting-into-single-user-mode}

\index{single user mode|(}%
Refer to the description of single-user mode in
section~\vref{sec:runlevels-and-single-user-mode} before doing this
activity.

\index{grub!editing menu entry|(}
You need to add a `\texttt{1}' at the end of the \grub line that
selects the \OS kernel.  To do this, do the following:
\begin{enumerate}
\item Select the desired kernel.
         
\item Press the \key{\texttt{e}} key to edit that entry.
  
\item Use the arrow keys to navigate to the kernel line (for example:\\
  \texttt{kernel /boot/vmlinuz-2.4.18-14 ro root=LABEL=/1})
  
\item Press the \key{\texttt{e}} key to edit the line.
  
\item \label{itm:kernel-param-single}Add the argument `\texttt{1}' (or
  `\texttt{single}') to the end of the line and press \key{Enter}.
The line will then look something like this:
\begin{alltt}
  kernel /boot/vmlinuz-2.4.18-14 ro root=LABEL=/1 1
\end{alltt}
  \begin{explanation}
    This selects the runlevel.  In the same way, you could boot the
    system into runlevel 3 instead of the normal runlevel 5 by adding a
    `\texttt{3}' at the end instead of `\texttt{1}'.
  \end{explanation}
  
\item Press the \key{\texttt{b}} key to boot.
\end{enumerate}
\index{grub!editing menu entry|)}
\index{single user mode|)}%

\subsubsection{Examining single user mode}

Examine the conditions of single user mode:
\begin{enumerate}
\item Did you need to enter your password?
  \begin{explanation}
    \index{password!lost root|(}
    \index{recover root password|(}
    You can change the root password by typing:
    \begin{alltt}
# \textbf{passwd}
    \end{alltt}
and, when prompted each of two times, enter a new password.
    \index{recover root password|)}
    \index{password!lost root|)}
  \end{explanation}

\item Can you change to another virtual console by pressing the key
  combination \key{Alt-Ctrl-F2}?

\index{networking!check enabled|(}
\item Is networking available?
  \begin{explanation}
    Some quick ways to check whether any network devices are active is
    by typing:
    \begin{alltt}
$ \textbf{/sbin/ifconfig}
    \end{alltt}%$
    You can also examine the \texttt{routing table} by typing
    \begin{alltt}
$ \textbf{/sbin/route -n}
    \end{alltt}%$
    Please try these two commands at a number of runlevels.
\index{networking!check enabled|)}
  \end{explanation}

\item Can you change to runlevel 5 without rebooting?
\end{enumerate}

\subsubsection{Investigating the Runlevels}

\begin{enumerate}
\item  Change to all the available runlevels.  At each runlevel,
  \begin{enumerate}
  \item determine whether networking is up;

  \item verify your current runlevel with the \texttt{/sbin/runlevel} program.
    
  \item Can you change to another virtual console (VC) (by pressing
    the key combinations \key{Alt-Ctrl-F2}, \ldots, \key{Alt-Ctrl-F6}?

\item Can you change to the graphical login screen by pressing the key
  combination \key{Alt-Ctrl-F7}?

\item Complete this table:

  \begin{tabularx}{\linewidth}{|c|X|X|X|}
    \hline%
    \emph{runlevel} & \emph{networking?} & \emph{can change VC?} &
    \emph{graphical login?}\\
    \hline%
    1 & & & \\
    \hline%
    2 & & & \\
    \hline%
    3 & & & \\
    \hline%
    4 & & & \\
    \hline%
    5 & & & \\
    \hline%
  \end{tabularx}
  \end{enumerate}

\item What happens when you switch to runlevel 0?

\item To runlevel 6?
\end{enumerate}

\subsubsection{The Runlevel Scripts}

The directory \texttt{/etc/rc.d} contains the shell scripts associated
with starting up \emph{services} on the system.  In it are a number of
other directories, and the scripts \texttt{rc}, \texttt{rc.sysinit}
and \texttt{rc.local}:
\begin{alltt}
$ \textbf{ls}
init.d  rc0.d  rc2.d  rc4.d  rc6.d        rc.sysinit
rc      rc1.d  rc3.d  rc5.d  rc.local      
\end{alltt}%$
\begin{enumerate}
\item Look in each of the directories \texttt{init.d}, \texttt{rc0.d},
  \texttt{rc1.d}, \ldots, \texttt{rc6.d}.  Change into each one, and
  list the contents of the directory:
\begin{alltt}
$ \textbf{cd /etc/rc.d/init.d}
$ \textbf{ls -l}
$ \textbf{cd ../rc0.d}
$ \textbf{ls -l}
$ \textbf{cd ../rc1.d}
$ \textbf{ls -l}
\ldots
$ \textbf{cd ../rc6.d}
$ \textbf{ls -l}
\end{alltt}

\item Discuss the purpose of what you see.
  \begin{explanation}
    The files in the directories \texttt{rc}\emph{n}\texttt{.d} are
    \emph{symbolic links}.  They are all linked to the shell scripts
    in the directory \texttt{/etc/rc.d/init.d}.
  \end{explanation}
\item You can start a service using the program
  \texttt{/sbin/service}.  The web server service is called
  \texttt{httpd}.

\item Go to see the default web site of your web server by opening the
  \URL in your web browser: \url{http://localhost/}.
  Can you see any web page?

\item Start the web server by typing:
  \begin{alltt}
$ \textbf{sudo /sbin/service httpd start}
  \end{alltt}%$
\item Now return to view the default web page.  Can you see it now?
\end{enumerate}
\printindex
\end{document}

This is what works on my hard disk in A204f:

# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You do not have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /, eg.
#          root (hd0,8)
#          kernel /boot/vmlinuz-version ro root=/dev/hda9
#          initrd /boot/initrd-version.img
#boot=/dev/hda
default=0
timeout=10
splashimage=(hd0,8)/boot/grub/splash.xpm.gz
title Red Hat Linux from this removable hard disk (2.4.18-14)
        root (hd0,8)
        kernel /boot/vmlinuz-2.4.18-14 ro root=LABEL=/1
        initrd /boot/initrd-2.4.18-14.img
title Red Hat Linux from internal hard disk (2.4.18-14)
        root (hd1,4)
        kernel /boot/vmlinuz-2.4.18-14 ro root=LABEL=/
        initrd /boot/initrd-2.4.18-14.img
title Windows from the Internal hard disk (hdc)
        map (hd1) (hd0)
        rootnoverify (hd1,0)
        chainloader +1
title Chainload bootloader from second hard disk
        map (hd1) (hd0)
        rootnoverify (hd0)
        chainloader +1
