The Kernel: Configuration and Compilation NHF
V1.2
Last Updated: 23/11/99
Introduction
The odds are that every Linux user will have to compile
a kernel at some point in their time, and it sometimes
needs to be done straight after install.. to add support
for the various hardware and peripherals you may need/want
to use. This necessity makes it an important skill
to master, especially for the newbie, and in this
document I intend to run you through compiling a new
kernel, patching up a kernel, and the basics of how
the kernel development system works.
I'm going to make a few assumptions..
1. You have read about any dependency problems your
kernel upgrade may produce.. This warning mainly goes
to those upgrading from Linux 2.0.x to 2.2.x. A good
source of information on this is LinuxHQ
2. You have a bootdisk that works. We are going to
be editing your bootmanager, and if things go wrong,
you'll find that bootdisk comes in handy ;) If you
don't have one, put a floppy in, and try issuing the
following as root..
# dd if=/boot/bzImage of=/dev/fd0 bs=8192
- where /boot/bzImage is the location of your current
kernel image
3. Your bootmanager is LILO. LILO is the default
in most distributions these days.
If you have any suggestions regarding this document,
please mail
me.
1. The Linux Kernel: An overview
I will not dwell on history here, and will also not
attempt to provide an explanation as to how the Linux
kernel functions. It is enough to say that it is a
monolithic kernel, which in turn would require a monolithic
explanation. ;)
Instead, I will cover some of the fundamental aspects
of the linux kernel development, which will hopefully
make the rest of this document a little clearer.
The kernel holds its version numbers within its filename,
and are in the format linux-major.minor.patch
Where major and minor are the version numbers, and
patch is the patchlevel of that particular kernel
version.
For example, linux-2.2.6 is patchlevel six,
of kernel version 2.2
However, one important part of the development life
cycle, is the release of 'development' kernel versions..
in other words these versions are not stable.
To allow you to distinguish between the different
kernel types, even numbered kernels (2.0 2.2
etc) are stable releases, and odd numbered
kernels (2.1 2.3 etc) are the development releases.
2. How to compile a kernel
2.1 The Pre-compilation Stage
- First of all, you'll want to download your new
kernel.. The example I am using is upgrading one my
machines from 2.2.9 to 2.2.10, so you obviously need
to amend your commands to mention your kernel numbers,
not mine.
- log in as root
- copy your brand spanking new kernel to /usr/src/
I am assuming the file is a .tar.gz file. (Note: I
know bzip is a better tool to use, but .tar.gz still
seems to be the default)
- ok.. you'll see a few files in that directory.
and they may require a little explaining. An example
output of ls in /usr/src/ is shown below..
# ls
linux/
linux-2.2.9/
linux-2.2.10.tar.gz
linux-2.2.6/
From the above list we can see the proposed kernel
package (2.2.10), an old kernel source directory (2.2.6),
and my current kernel sources (2.2.9).
The directory called Linux is a symbolic link to whatever
kernel source I am using at the time.. At this stage
of the process it still points to linux-2.2.9/
Now.. Your linux directory may not be a symbolic link..
it may just be a regular directory. I use symbolic
links because it is a good way of making managing
your kernel sources, without having to move a lot
of files around, and reduces the risk of me losing
old kernel sources. You do not need to use symbolic
links, but i recommend it.
You can check your Linux directory to see if it is
a sym-link by typing..
# ls -l linux
and if you see something like.. linux -> linux-2.2.9
it means it is a sym-link.
The reason for mentioning this is.. if your linux
directory is not a symbolic link, you may well want
to rename it as something different, so as not lose
the kernel sources. Either way, you need to remove
the linux directory in /usr/src
- My next steps are
# rm linux - get rid of
that symbolic link to linux-2.2.9
# tar -xvzf linux-2.2.10.tar.gz - unpack the new
kernel sources
Now if you look at the directory you will see a directory
called linux with lots of lovely kernel related stuff
in there. Since I suggested you make linux a symbolic
link, then that is what we do next..
# mv linux linux-2.2.10 - the new kernel sources
are moved to a separate directory
# ln -s linux-2.2.10 linux - set up the new symbolic
link
- now you want to enter the directory /usr/src/linux
to start compilation.
2.2 The Compilation Stage
They're are too many options and possibilities in
the kernel configuration options to cover them here,
and the only advice I can give you whilst you are
choosing which modules to add is to read all the help
notes.. If in doubt read the help notes, and if you
are still in doubt, go with the default option. A
good book for an explanation on the various modules
is "Running Linux" by O'reilly. It is a little dated,
but the third edition is due out Aug 1999.
- You have a number of ways of going through the
possible modules to include.
# make config - a sequential text-based
selection method.. takes a looong time.
# make menuconfig - a menu driven interface
which works in X or at the CLI
# make xconfig - a version of menuconfig
for x-windows if you have it running.
# make zlilo - This one attempts to configure
lilo to boot your new kernel, and although useful,
can be somewhat unreliable, especially if you have
complex lilo setups.
I would suggest one of the latter two options, for
reasons of speed and sanity. There is nothing worse
than going through a make config to realise you've
forgotten something and you need to do it again.
There is also one other option worth mentioning,
which is...
# make oldconfig
This option looks in your /usr/src/linux directory
for a file named .config This file contains
all the compilation options you chose the last time
you compiled your kernel. So if you are simply upgrading
your kernel, and have the same requirements from your
kernel, you can simply use this option to load your
default values. Just make sure that your .config
file from your old kernel source tree is copied into
your new kernel source tree, and you will be able
to apply the same values you compiled into your last
kernel.
If you still need to make one or two changes to your
old kernel configuration, that is easily done with
xconfig, or menuconfig.
I cannot proceed any further without a brief discussion
on the options in a kernel. You have one of
three options for most configurable elements within
a kernel; compile them in, don't compile them in,
or add them as a module. Compiling them in means
that this function/element will always be available
in your new kernel, and the opposite applies if you
do not compile an element in. Adding an option
as a module, means that you can load the function
at run-time.. i.e. after the kernel has booted.
This allows you to keep the function available to
you, yet still gain the benefits from having a small
and fast kernel.
A modular approaches to kernels is best used for
systems in flux.. computers that have components changed
and/or removed frequently, or for systems that want
more options. For example, if you have three
soundcards for some reason, it is unlikely you will
want to use them all at once, so why compile support
for three different soundcards? just use each
driver as a module, and load and unload them as necessary.
There are programs that handle the loading and unloading
of modules, and some that even auto-load modules upon
referencing the device the function is related to,
but I will leave those programs beyond the scope of
this document for now (unless enough of you tell me
otherwise :-)).
Anyway...
- after you've chosen all your modules, you need
to do the following
# make dep
# make clean
# make bzImage
Note: You can substitiute bzImage with zImage. However
bzImage makes the kernel smaller, which is a good
idea in most cases.
# make modules
If you are using, for example, kernel version 2.2.10,
then when you issue the next command, the modules
are installed in /lib/modules/<kernel_release>,
so in this case /lib/modules/2.2.10 All well
and good, except, if this is not the first kernel
you have compiled from this kernel release, then you
are going to overwrite your modules. So, a good
idea at this point is to move them out of the way.
I usually perform a command similar to the following.
# mv /lib/modules/<kernel_release> /lib/modules/<kernel_release.old>
Then you are free to issue the following command.
# make modules_install
and your kernel is compiled!! If you have found one
of your make commands exits with an error, the chances
are you have chosen some conflicting modules. The
solution? Go back to the make config/menuconfig/xconfig
stage.
2.3 The Post-compilation Stage
This is the important stuff.. you will now have to
include your new configuration as an option in your
bootmanager. The method I will describe is to add
a new kernel to LILO. This way, you have the option
of booting the new kernel, as well as booting the
old kernel, just in case there are any problems.
your newly compiled kernel is in /usr/src/linux/arch/*architecture*/boot/
where *architecture* is the type of computer you are
using. If its a plain vanilla pc (like mine), then
you can substitiute *architecture* with i386. The
kernel's name is bzImage (or if you used make zImage
during compile, it will be zImage)
You must also know where you keep your current kernel's.
On my system it is /boot but some people use their
root directory.
- So.. bearing in mind your specifics.
# cd /boot
# mv bzImage vmlinuz-2.2.9 - renames
the old kernel so you dont overwrite it, and you know
what it is
# mv system.map systemp.map-2.2.9 -
moves the old system map
# cp /usr/src/linux/arch/i386/boot/bzImage
/boot/ - copies the new kernel to the boot directory
# cp /usr/src/linux/System.map /boot/
- copies the new system map to the boot directory
I will take moment here to discuss the System.map
file, and the organisation of this directory in general.
In the above example I have assumed that you have
a static System.map you want to replace, although
some systems have a symbolic link named system.map
pointing to a different file. I have assumed this
on the basis that most distributions install a static
system.map file, and so if you don't know whether
you have a static system.map file, or just a symbolic
link to another file, the odds are you have a static
one, and will be perfectly fine when following the
instructions given.
It is important to remember the differences and filenames
you've just changed, as they need to be reflected
in your lilo configuration file.
- Pull up /etc/lilo.conf with your favorite
editor
If you have only one kernel in here, and you have
no other OS on your system, their should only be one
stanza relating to kernel locations and names. Other
OS's you use will have identifiable labels. A stanza
with a label=windows should be left alone. You only
need to be concerned with your linux boot parameters.
- Find your old kernel's stanza.. an example of what
it may look like is shown below
image = /boot/bzImage
root = /dev/hda1
label = linux
As you remember I changed my old bzImage to vmlinuzold
so I need to edit that stanza to reflect the changes..
so it becomes
image = /boot/vmlinuzold
root = dev/hda1
label = old
- Then you need to add a new stanza for your new
kernel.. an example form my /etc/lilo.conf
is.
image = /boot/bzImage
root = /dev/hda1
label = new
- Now you need to save your lilo.conf and then run
the following to update LILO
# /sbin/lilo
- If lilo gives output of options without any errors..
well.. you've finished. All that remains is to reboot,
and at the LILO prompt (attained by pressing Shift
when the word LILO appears in the boot sequence) type
your new kernel label, which in my case is "new".
Obviously I'll leave out the inverted comma's :)
Once you've checked it, by booting (keeping that
boot floppy handy :)), and you are happy with it,
you can edit /etc/lilo.conf once more, to make your
new kernel the default kernel to boot. To do that,
just make your new kernel's stanza the first one in
the list of boot options. In my case, just switch
the vmlinuzold stanza with the bzImage stanza.
3. Patching a Kernel
The advantage of patching an existing kernel, over
downloading the next kernel release, is that people
with little time and/or bandwidth can keep their kernel's
up to date, just by applying a 20k (approx.) patch
file.
You need to download the patches you require, in
sequential order from the patchlevel of your current
kernel source, to the patchlevel you wish to upgrade
to.
For example, if I had kernel 2.2.6 and I wanted to
upgrade to kernel 2.2.11 i would need patches 2.2.7..
2.2.8.. 2.2.9 through to 2.2.11. Kernel patches follow
the same naming conventions as the kernel itself does.
i.e. patch-2.2.8 is he patch to upgrade from
2.2.7 to 2.2.8.
You do not have to store your kernel patches in any
specific location, rather it is the location where
you execute the patch command that is important. To
patch your kernel, you must do the following as root.
# cd /usr/src - You must execute your patch
command from this location
# gunzip -c patchfile | patch -p0
- Execute this command for every patch you have, where
patchfile is the name and location of
your patch
Note: You run the patch command above for each patchfile
in sequential order. Following the previous example,
if i had kernel 2.2.6 and wanted to patch up to 2.2.11
I would first apply patch 2.2.7, followed by 2.2.8,
2.2.9 through to 2.2.11
You cannot use any wildcards such as * either, as
this applies the patches in ASCII order, not numerical
order.
This is all you should need to do. To make sure all
the patches were applied successfully, issue the following
as root.
# find /usr/src/linux -follow -name "*.rej" -print
#find /usr/src/linux -follow -name "*#" -print
If either of the above two commands return any files,
then some parts of the patch process could not be
applied for some reason. If you are in doubt as to
what action should be taken to address such problems,
I would suggest you download a kernel source package,
and start from the beginning.
If everything went cleanly, you have successfully
patched your kernel source, and are free to compile
a new up-to-date kernel.
4. Other Sources of Information
The documents in your kernel sources are the most
detailed.. You should find them here
the LDP
has a good selection of kernel
info
For those of you who want to download your kernels/patches,
find your local mirror here
7DS
[-Next
Page-]
|