\documentclass[10pt]{article}
\usepackage{boxes}
\pagestyle{empty}

\setlength{\parindent}{0em}
\setlength{\parskip}{0em}
\setlength{\textwidth}{7.5in}
\setlength{\textheight}{10.5in}
\setlength{\topmargin}{0pt}
\setlength{\headheight}{0pt}
\setlength{\headsep}{0pt}
\setlength{\marginparwidth}{0pt}
\setlength{\marginparsep}{0pt}
\setlength{\oddsidemargin}{-.5in}
\setlength{\evensidemargin}{-.5in}
\setlength{\footskip}{0mm}
\setlength{\voffset}{-0.75in}

\newcommand{\texts}[1]{\indent\textbf{\normalsize{#1}}}
\newcommand{\text}[1]{\texts{#1} \\ \vspace{1pt}}

\newcommand{\bull}{$\Rightarrow$ }
\newcommand{\cmd}{$\triangleright$ }

\begin{document}

\begin{center}
\textbf{\textsf{\Huge{Linux Kernel Compile \\ Quick Reference Card}}}
\\
\end{center}

\subsection*{The Process}

\subsubsection*{Downloading}
\text{The best way to download the kernel is to hit one of the mirror
sites.  You can visit \texttt{http://kernel.org/mirrors/} for a complete
list of kernel mirror sites.  Or you can connect to one of your closest
mirrors by connecting to:\\
\indent\bull\texttt{ftp://ftp.ca.kernel.org/pub/linux/kernel/v2.4}, or \\
\indent\bull\texttt{http://www.ca.kernel.org/pub/linux/kernel/v2.4}.   \\
Note that in both URL's the \emph{ca} part can be substituted for
another country code; again, see the mirror list for details.}
\text{Linux kernel releases take on the format of
\texttt{<version>.<patchlevel>.<sublevel>-<extraversion>} where: \\
\indent\bull the \texttt{version} changes with major milestones, \\
\indent\bull the \texttt{patchlevel} changes with minor milestones, \\
\indent\bull an even \texttt{patchlevel} implies a stable line of kernels, \\
\indent\bull an odd \texttt{patchlevel} imples a development line of kernels, \\
\indent\bull the \texttt{sublevel} changes with bug-fixes, updates and 
optimizations, \\
\indent\bull while \texttt{extraversion} is used to identify pre-releases,
test releases, and private development kernels.}
\text{A file listing of the above two URL's will reveal hundreds of
files.  There are two (more) important types of files:\\
\indent\bull\texttt{linux-2.4.*.tar.*}, and \\
\indent\bull\texttt{patch-2.4.*.*}. \\
Respectively these are whole kernel archives and patches between
complete archives.  Patch files are smaller to download and contain the
delta between the version they bare in their name and the minor release
just prior to it.}

\subsubsection*{ Validating}
\text{Along with any archive or patch file, one should download the
correcponding cryptographic signature (.sign) file.  A signature file
can be used to authenticate that the kernel source archive, or patch
file, is authentic.  To do this you will need gpg.}
\text{Before you verify your first kernel you will need to get the
``Linux Kernel Archives Verification Key''.  You do this by running: \\
\indent\cmd\texttt{gpg --keyserver wwwkeys.pgp.net --recv-keys 0x517D0F0E} \\
You can also get the PGP key from \texttt{http://www.kernel.org/signature.html}}
\text{Once you have a the key on your \emph{gpg keyring}, and have
downloaded the kernel file and its signature, you are ready to verify
the authenticity of the download: \\
\indent\cmd\texttt{gpg --verify linux-2.4.20.tar.gz.sign linux-2.4.20.tar.gz} \\
\emph{gpg} will notify you with success or failure of the test.}

\subsubsection*{Unpacking}
\text{Unpacking the kernel is a very simple operation, you just have to
use the \emph{tar} utility.  However some software may require the use
of the kernel headers.  Some software will blindly reference
\texttt{/usr/src/linux}, while the kernel may be unpacked to
\texttt{/usr/src/linux-2.4.20}.  To fix this it is common to create a
symlink for the most recent version of the kernel.  These steps are
shown below:}\hspace{6pt}
\begin{tabular}{lp{1cm}l}
\cmd\texttt{cd /usr/src} && \\
\cmd\texttt{rm linux} && assuming \texttt{linux} is a symlink \\
\cmd\texttt{tar xzf /tmp/linux-2.4.20.tar.gz} && creates a \texttt{linux} dir \\
\cmd\texttt{ln -s linux-2.4.20 linux} && link new kernel as default kernel \\
\end{tabular}\\ \hspace{6pt}
\hspace{12pt}
\text{If your archive has a bz2 extension then you will need to
uncompress them using bunzip2 and then run \texttt{tar xf} instead.  It
is also common for tar on many distributions to have a -j option to
uncompess bz2 files just the way that -z decompesses gz files.  If your
\emph{tar} utility has this feature you can run: \texttt{tar xjf
linux.tar.bz2} instead.}

\subsubsection*{Patching}
\text{If you have downloaded some patch file, say
\texttt{/tmp/patch-2.4.21-pre1.bz2}, and wish to apply it to your kernel 
directory, \texttt{/usr/src/linux}, you should first make sure that the
patch is compatible with your kernel sources:}\hspace{6pt}
\begin{tabular}{lp{1cm}l}
\cmd\texttt{cd /usr/src/linux} && \\
\cmd\texttt{bunzip2 -c /tmp/patch-2.4.20-pre1.bz2 | patch -p1 --dry-run} && \\
\end{tabular}\\ \hspace{6pt}
\hspace{12pt}
\text{If the output is full of \texttt{patching file foo} lines then
it's successful.  The \emph{--dry-run} does not do make any changes but
simply tests to see if the patch could be applied.  Once you are ready
to apply the patch for real run:}\hspace{6pt}
\begin{tabular}{lp{1cm}l}
\cmd\texttt{cd /usr/src/linux} && \\
\cmd\texttt{bunzip2 -c /tmp/patch-2.4.20-pre1.bz2 | patch -p1} && \\
\end{tabular}\\ \hspace{6pt}
\hspace{12pt}
\text{Note that if your patch file is gzipped and not bzipped you should
run \emph{gunzip} in place of \emph{bunzip2}.}

\subsubsection*{Configuration}
\text{The Linux kernel can be tailored to a specific computer it runs
on; each driver and system component can be compiled into the kernel,
compiled as a dynamically loadable component, or removed completely.
Starting from scratch your kernel sources will have a default
configuration that was picked by the maintainer.  Chances are very slim
that these defaults will match your system hardware; hence the
configuration step.  Most commonly you will run one of the following to
configure your kernel:}\hspace{6pt}
\begin{tabular}{lp{1cm}l}
\cmd\texttt{make menuconfig} && a text-menu (curses) based config interface\\
\cmd\texttt{make xconfig}    && a graphical (X) based config interface\\
\end{tabular}\\ \hspace{6pt}
\hspace{12pt}
\text{Most options in the kernel can be compiled into modules.  See the
Modules section to learn more about what should and should not be a
modules.  If the boot process requires a module you will need to create
an \emph{initrd} file (see below).}
\text{Configuration options are stored in a \emph{.config} file.  It
is humanly editable, but quite overwhelming.  If you have a
\texttt{.config} file from a previous working kernel you can copy it
into a new, and presumably unconfigured kernel, and run:}\hspace{6pt}
\begin{tabular}{lp{1cm}l}
\cmd\texttt{make oldconfig} && use a \emph{.config} file as is\\
\end{tabular}\\ \hspace{6pt}
\hspace{12pt}
\text{If you are bringing in a \emph{.config} file into a previously 
configured or compiled kernel tree you should clean up the kernel source
first.  Frequently \texttt{make clean} will not do the job; this is
because there have been too many changes between the original
configuration and the current.  In these cases you will have to run
\texttt{make mrproper} which will clean up the whole tree and even
delete the \emph{.config} file.}

\subsubsection*{Compiling}
\text{The next step is to compile the kernel and produce the kernel and 
the module binaries.}\hspace{6pt}
\begin{tabular}{lp{1cm}l}
\cmd\texttt{make bzImage} && make a big, compressed kernel binary \\
\cmd\texttt{make modules} && make all modules components \\
\end{tabular}\\ \hspace{6pt}
\hspace{12pt}
\text{The order of the commands is arbitrary; you can build modules
before you build the kernel.  After compling you will have a
\texttt{/usr/src/linux/arch/i386/boot/bzImage} kernel binary and module
files scattered through out the kernel tree.}
\text{If you are not building on an \emph{i386} use the directory, under
\emph{arch} that reflects your architecture.}

\subsubsection*{Installing}
\text{Finally, the kernel and modules are installed on the local system
by running:}\hspace{6pt}
\begin{tabular}{lp{1cm}l}
\cmd\texttt{make install} && the kernel \& System.map are installed in \texttt{/boot} \\
\cmd\texttt{make modules\_install} && modules are installed in \texttt{/lib/modules/<version>}\\
\end{tabular}\\ \hspace{6pt}
\hspace{12pt}
\text{If you compiled boot-critical functionality into modules then you
will need to setup an initrd file; to do this run the \emph{initrd}
program.  The specifics of this differ from distribution to
distribution.  On RedHat for example you would run this:}\hspace{6pt}
\begin{tabular}{llp{1cm}l}
\multicolumn{4}{l}{
\cmd\texttt{mkinitrd -f -v [options] /boot/initrd-<version>.img <version>} }\\
\emph{options:}
&\texttt{--fstab=file} && determine file system modules needed using \texttt{/etc/fstab}\\
&\texttt{--preload=module} && module will be loaded before SCSI system modules defined in \texttt{/etc/modules.conf} \\
&\texttt{--with=module} && module will be loaded after the SCSI subsystem \\
\end{tabular}\\ \hspace{6pt}
\hspace{12pt}
\text{On a recent Debian system, you could run the following after
editing your \emph{/etc/mkinitrd/mkinitrd.conf} -- see the man page for
details.}\hspace{6pt}
\begin{tabular}{llp{1cm}l}
\multicolumn{4}{l}{
\cmd\texttt{mkinitrd -o outfile [moduledir]} }\\
\end{tabular}\\ \hspace{6pt}
\hspace{12pt}
\text{An initrd is optional and usually not needed if you compile
boot-critical components into the kernel and not as modules.}

\subsubsection*{Bootloaders}
\text{Bootloader is the glue between the BIOS and the kernel.
Bootloaders allow the user to select what kernel, or other operating
system, to boot.  There are two commonly used boot loaders: \emph{LILO}
and \emph{GRUB}.  Check what your system uses; \emph{LILO} config file
lives in \texttt{/etc/lilo.conf}, while \emph{GRUB} lives in
\texttt{/boot/grub}.}\hspace{6pt}
\begin{tabular}{p{0.15\textwidth}p{0.85\textwidth}}
\parbox[t]{1cm}{\emph{menu.lst}} & \begin{verbatim} title 2.4.20 \\
    root (hd2,0) \\
    kernel /boot/vmlinuz-2.4.20 ro root=/dev/sda1 vga=ext \\
    initrd /boot/initrd-2.4.20.img 
\end{verbatim} \\
\parbox[t]{1cm}{\emph{lilo.conf}} & \begin{verbatim} image=/boot/vmlinuz-2.4.20
    label=2.4.20
    initrd=/boot/initrd-2.2.20.img
    read-only
    root=/dev/sda1
\end{verbatim} \\
\end{tabular}\\ \hspace{6pt}
\hspace{12pt}
\text{Note that on RedHat the \emph{GRUB} configuration file is named
\emph{grub.conf}.}
\text{After altering the \emph{lilo.conf} file you will have to run the
\texttt{/sbin/lilo} utility to ``install'' the configuration.  \emph{GRUB} 
requires no such step; it does need to be installed once -- RTFM.}


% mention the install env-variables

\vspace{12pt}

\subsection*{Files}

\subsubsection*{Source}
\texts{By convention the kernel source resides in \texttt{/usr/src/linux}.  
When multiple kernel sources reside on one machine it is customary to store 
them under \texttt{linux-<someversion>} directory and making \texttt{linux} 
a symlink to a \emph{current} Linux kernel. An example:}
\begin{verbatim} 
   $ ls linux* -ld
   lrwxrwxrwx    1 root     root           17 Jan 10 19:21 linux -> linux-2.4.21-pre1/
   drwxr-xr-x   14 root     root         4096 Mar 16 23:18 linux-2.4.18-pre9/
   drwxr-xr-x   14 root     root         4096 Apr 10 19:21 linux-2.4.19-pre2/
   drwxr-xr-x   16 root     root         4096 Jan  8  2002 linux-2.4.7-10/
\end{verbatim}

\text{The \texttt{linux} symlink is used to let other software packages
which assume that they can locate the kernel source in
\texttt{/usr/src/linux} to do just that.}

\text{Inside the \texttt{linux} directory we have the following:}\hspace{6pt}
\begin{tabular}{ll}
\texttt{Makefile}	& build rules for compiling the system \\
\texttt{MAINTAINERS}	& list pakcages and their maintainers \\
\texttt{REPORTING-BUGS}	& the right procedure for bug reporting\\
\texttt{Documentation/} & plethora of docs of varied vintage \\
\texttt{arch/} 		& architecture specific abstraction code stubs \\
\texttt{drivers/} 	& source tree of varous drivers \\
\texttt{fs/} 		& file system implementation \\
\texttt{include/}	& header files \\
\texttt{init/} 		& init code: main() of the kernel \\
\texttt{ipc/} 		& inter process communication implementation \\
\texttt{kernel/}	& kernel core: scheduler, timers, signals, system calls, etc. \\
\texttt{lib/} 		& small primitives and utility functions \\
\texttt{mm/} 		& memory management: allocators, slabs, memory maps, shared memory, etc.\\
\texttt{net/} 		& networking code: routing, firewalling, etc \\
\texttt{scripts/}	& scripts for build system, developer and user \\
\end{tabular}\\ \hspace{6pt}
\hspace{12pt}

\subsubsection*{The Makefile}
\text{The \texttt{Makefile}, and friends, have a variety of rules and
targets that can be invoked.  Here is a short summary:}\hspace{6pt}
\begin{tabular}{lll}
&\texttt{clean}		& removes all binary files from the tree \\
&\texttt{mrproper}	& \texttt{clean} \& removes all dependencies, architecture files, and documentation \\
&\texttt{distclean}	& \texttt{mrproper} \& removes all patching relics \\
\cline{1-1}
&\texttt{config}		& old style configuration; not worth using \\
&\texttt{xconfig}	& configuration through an X gui \\
&\texttt{menuconfig}	& configuration through a curses text-menu interface \\
&\texttt{oldconfig}	& uses existing \emph{.config} to configure the kernel \\
\cline{1-1}
&\texttt{bzImage}	& builds a 'big' gzip-compressed kerenl \\
&\texttt{bzdisk}		& \texttt{bzImage} \& copies it to a floppy \\
&\texttt{zImage}		& builds a gzip-compressed kerenl \\
&\texttt{zdisk}		& \texttt{zImage} \& copies it to a floppy \\
\cline{1-1}
&\texttt{modules}	& build all modules \\
\cline{1-1}
&\texttt{install}	& installs a bzImage in \texttt{/boot} \\
&\texttt{modules\_install}& installs all modules in \texttt{/lib/modules} \\
\cline{1-1}
&\texttt{spec}		& creates an \emph{rpm} spec file \\
&\texttt{rpm}		& \texttt{rpm} \& builds the source rpm \\
\cline{1-1}
&\texttt{htmldocs}	& build html docs in \texttt{Documentation/DocBook/} \\ 
&\texttt{pdfdocs}	& build pdf docs in \texttt{Documentation/DocBook/} \\
&\texttt{psdocs}		& build ps docs in \texttt{Documentation/DocBook/} \\
&\texttt{sgmldocs}	& build sgml docs in \texttt{Documentation/DocBook/} \\
\end{tabular}\\ \hspace{6pt}
\hspace{12pt}

\subsubsection*{Kernel}
\text{Once the kernel is compiled and installed you will have the
following files on your system:}\hspace{6pt}
\begin{tabular}{ll}
\texttt{/boot/vmlinuz-2.4.20.img} & the Linux kernel binary \\
\texttt{/boot/System.map-2.4.20.img} & map of kernel symbols and their memory offsets \\
\texttt{/boot/initrd-2.4.20.img} & \emph{optional}, an initial ram disk file\\
\end{tabular}\\ \hspace{6pt}
\hspace{12pt}

\subsubsection*{Modules}
\text{Modules are installed into \texttt{/lib/modules/<version>}
directory.  This directory has a specific structure:}\hspace{6pt}
\begin{tabular}{ll}
\texttt{build} & a sym links to the actual \texttt{/usr/src/linux-<version>} directory \\
\texttt{kernel} & drivers and system component modules \\
\texttt{pcmcia} & pcmcia only drivers \\
\texttt{misc} & other (not from the kernel) modules \\
\texttt{modules.dep} & dependency list (used by \emph{modprobe})\\
\end{tabular}\\ \hspace{6pt}
\hspace{12pt}

\text{Once the modules are installed there are a few utilities you
can use to manage them:}\hspace{6pt}
\begin{tabular}{ll}
\texttt{depmod} & build a dependency list; \texttt{/lib/modules/<version>/modules.dep} \\
\texttt{insmod} & install a module into a running kernel \\
\texttt{modprobe} & \texttt{insmod} a module and its dependents \\
\texttt{rmmod} & remove an installed module \\
\texttt{lsmod} & list installed modules \\
\end{tabular}\\ \hspace{6pt}
\hspace{12pt}


\begin{center}
Bart Trojanowski \tt{<bart@jukie.net>} \\
Dave O'Neill \tt{<dave@acm.org>}
\end{center}


\end{document}
