\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