#
# _._
# /_ _`. (c) 2001, David A. Desrosiers
# (.(.)| hacker at gnu dash designs dot com
# |\_/'|
# )____`\ kernel-HOWTO: All-in-One Kernel Building HOWTO
# //_V _\ \
# (( | `(_) If you find this useful, please drop me
# / \> ' / \ an email, or send me bug reports if you find
# \ \.__./ / problems with it. I accept PayPal too! =-)
# `-' `-'
#
##################
#
# License
#
##################
#
# This HOWTO is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This HOWTO is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc., 59
# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
###################
#
# After many hours of helping people on irc correct the assumptions found in
# other kernel HOWTO documents, I decided to write my own. This works, and
# is exactly how I build kernels for my production machines. I build roughly
# 400-500 kernels a year using both development and stable kernels for
# dozens of platforms, including ARM, x86, and Sparc. Many of the other
# kernel build HOWTOs available are simply wrong, and lead the user down the
# wrong direction. This one tries to make sure people are doing this right.
#
# It's purposely over-commented, because I already get too much email
#
# TODO:
#
# * add a section describing the configuration for GRUB as well as lilo.
# (pugfantus)
#
# * Explain where to find things in the kernel docs directory, like
# framebuffer options, finding that missing "LinkSys" kernel driver, and
# the packages required to upgrade (MonMotha)
#
# Last update: Thu Jan 17 23:31:56 PST 2002
#
##################
Short Linux Kernel Build HOWTO
------------------------------
Building a Linux kernel is a very satisfying process, both in terms of
personal accomplishment, as well as the ability to make your hardware work
at its optimum performance level.
When you build your own Linux kernel, you are building a kernel which should
exactly match the target hardware it will run on, without any unnecessary
drivers or resources consumed by code which will never be used (for example,
running a kernel with built-in sound drivers for a system with no sound
supporting hardware inside it, or SCSI drivers for a system without SCSI
devices or hardware).
Downloading the kernel source
-----------------------------
Before starting to build a Linux kernel, you will need at least one tarball
of the full Linux kernel sources or a set of patches to match your kernel
upgrade path. These tarballs can come in two formats, a "gzipped tarball"
which has the extension ".tar.gz" on it, or a "bzipped tarball", which has
the ".tar.bz2" extension on it. The bzipped tarballs tend to be much
smaller, so if bandwidth is a concern, use that version instead.
We will use the latest released kernel as of the writing of this HOWTO,
version 2.4.17. You can pick that up at the following site:
ftp://ftp.kernel.org/pub/linux/kernel/v2.4/linux-2.4.17.tar.bz2
ftp://ftp.kernel.org/pub/linux/kernel/v2.4/linux-2.4.17.tar.bz2.sign
If this location does not seem to respond, you can find a list of mirrors
that host the Linux kernel at the following URL:
http://www.kernel.org/mirrors/
There are two ways to build a kernel, full, and patch-upgrade. The full
kernel is one very large tarball of the full kernel sources, averaging over
20 megabytes in size at this version.
The "patch-upgrade" is a different way of building a kernel, where you take
an existing kernel source, apply a patch or series of patches incrementally
to it, and end up with the equivalent of what the full 20-meg tarball would
have given you.
If you decide to download the patch to upgrade your kernel, make sure you
have all cumulative patches prior to the kernel you wish to build, including
the one for your kernel. If your *CURRENT* kernel (found by using the
command 'uname -a') is 2.4.12, you'll need the following patches to be able
to build yourself a shiny new 2.4.17 Linux kernel:
patch-2.4.13.bz2 # the actual Linux kernel patch
patch-2.4.13.bz2.sign # the PGP signature verification file
patch-2.4.14.bz2
patch-2.4.14.bz2.sign
patch-2.4.15.bz2
patch-2.4.15.bz2.sign
patch-2.4.16.bz2
patch-2.4.16.bz2.sign
patch-2.4.17.bz2
patch-2.4.17.bz2.sign
Ensuring file integrity
-----------------------
To be sure you have the right kernel, you can verify it with md5sum. Your
hash should match the following for this kernel:
0628d142eeb6fc31856d7a60d3f30a82 linux-2.4.17.tar.bz2
Or, if you downloaded the kernel patch(es):
4f84bb410cba4bf9c4199107a9e5ecb7 patch-2.4.17.bz2
You should begin to get in the habit of using md5sum to check the files you
download against the md5 signatures that they are packaged with, if any.
This generally ensures that there is no corruption in the file itself. We
will test it before unpacking later in this HOWTO, just to be sure the file
is indeed intact, and not corrupted in any way.
Verifying the Linux kernel PGP key
----------------------------------
In the case of a linux kernel, you should also grab the .sign file which
matches it, and check the pgp signture. If you have gpg installed.
If you do not have GPG installed, you may skip this section, but it is
*HIGHLY* recommended that you install and use GPG to verify kernel
signatures (and learning how to use PGP in general is definately a "Good
Thing(tm)". You can find out more about GNU Privacy Guard at the following
URL: (http://www.gnupg.org/).
gpg is not required to build a Linux kernel, it is only required to validate
and verify that the kernel was signed by the authorized Linux kernel
maintainers.
Using gpg, you can verify the kernel signature by issuing the following
syntax:
$ gpg --verify linux-2.4.17.tar.bz2.sign linux-2.4.17.tar.bz2
gpg: Signature made Fri Dec 21 09:57:02 2001 PST using DSA key ID 517D0F0E
gpg: Good signature from "Linux Kernel Archives Verification Key "
Make sure to grab the right .sign file for your kernel, a .tar.bz2.sign will
not work with a .tar.gz kernel tarball, for example. The .sign file must
match the extension of the kernel or patch you have downloaded and are going
to build from.
Unless you have taken explicit steps to build a trust path to the Linux
Kernel Archives Verification Key, you should expect to see a warning message
similar to:
Could not find a valid trust path to the key. Let's see whether we
can assign some missing owner trust values.
No path leading to one of our keys found.
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
..after gpg has verified the signature. You should not be alarmed by this
warning.
Before you can do this, you must run 'gpg --import' the key below. This key
is also available from most common PGP key servers, such as
hkp://wwwkeys.pgp.net/0x517d0f0e (http://wwwkeys.pgp.net:11371/pks/lookup?op=get&search=0x517D0F0E).
To import it from the keyserver using GnuPG, simply execute:
$ gpg --keyserver wwwkeys.pgp.net --recv-keys 0x517D0F0E
More informtion on this process can be found on the Linux Kernel Archive
site itself here:
http://www.kernel.org/signature.html
If you are using a series of kernel patches, the syntax and process for
validating the gpg signatures is the same.
Testing and unpacking your Linux kernel sources (or patches)
------------------------------------------------------------
The kernel sources must be unpacked into a directory with enough space to
hold and build the sources. For the 2.4.x kernel series, this should be
roughly 200 megabytes. Unpacked, the clean kernel sources will be roughly 55
megabytes in size.
One mistake many people make is to unpack this into /usr/src directly, and
this is a *BIG* mistake. Many distributions incorrectly place Linux sources
into a "real" directory called /usr/src/linux, and that causes quite a few
problems if you're building new kernels on the machine.
The process shown here will *ALWAYS* ensure that will never happen. If you
were to unpack your linux-2.4.17 kernel sources into /usr/src/linux on a
standard distribution, you would blindly overwrite the /usr/src/linux
sources which came with your distribution, which in most cases would *NOT*
be 2.4.17.
We begin by creating a directory under /usr/src that exactly matches the
kernel version itself. In this case, if we were to build a 2.4.17 kernel,
the following command would be correct:
$ mkdir /usr/src/linux-2.4.17
Then the kernel sources must be unpacked into that location. Because the
kernel sources themselves include a directory called 'linux' inside the
tarball, you do not want to unpack them into /usr/src directly, or you will
overwrite the /usr/src/linux directory already there, which would be bad.
Let's test the file first, to make sure we did not get a corrupt file. We
can do that in several ways.
$ tar jtvf /tmp/linux-2.4.17.tar.bz2
You should see no errors from this test process, if the kernel tarball is
intact, and not corrupted. If you do see errors, you may want to re-download
the kernel tarball and test again. The bzip2-pipe equivalent of this test
would be:
$ bzip2 -dc /tmp/linux-2.4.17.tar.bz2 | tar tvf -
If this returns no errors, we can then safely unpack the kernel itself into
it's target destiation, /usr/src/linux-2.4.17 in this case.
$ tar jxvf /tmp/linux-2.4.17.tar.bz2 -C /usr/src/linux-2.4.17
Two new things are being used here. Notice that we're using tar, but we're
also unpacking a kernel tarball which has been compressed with bzip
compression. Additionally, the -C argument specifies that the directory
/usr/src/linux-2.4.17 be changed to before we unpack the tarball. This is
the equivalent of doing the following:
$ cd /usr/src/linux-2.4.17
$ bzip2 -d /tmp/linux-2.4.17.tar.bz2
$ tar xvf /tmp/linux-2.4.17.tar
You can also do this using bzip2 and a pipe, if your tar does not support
the bz2 extension via the -j option and compression as follows:
$ cd /usr/src/linux-2.4.17
$ bzip2 -dc /tmp/linux-2.4.17.tar.bz2 | tar xvf - -C /usr/src/linux-2.4.17
Passing this all in one command ensures that we have an intact tarball in
/src when we're done and not an unpacked tarball which takes up a lot of
space, and also makes sure that typos don't end up causing us any troubles.
If you were to uncompress the bz2 file in place, you would end up with a
50-meg tarball, which you would then have to untar into
/usr/src/linux-2.4.17, and this can consume valuable disk space. Whenever
/possible, uncompress and untar into a stream, so that the original file is
/left untouched.
If you were not on a Linux system to begin with, or did not have a GNU
version of tar which supported the 'j' switch (which tells tar to uncompress
the bzip-compressed file first).
The above command (using the pipe) is what is know as a 'portable' command.
This means it will work on various platforms without problems. It is the
lowest common denominator that will work on all platforms.
Now the structure inside this directory should resemble the following (among
dozens of other subdirectories):
/usr/src/linux-2.4.17/linux
|-- COPYING
|-- CREDITS
|-- Documentation
|-- MAINTAINERS
|-- Makefile
|-- README
|-- REPORTING-BUGS
|-- Rules.make
|-- arch
|-- driversa
|-- fs
|-- include
|-- init
|-- ipc
|-- kernel
|-- lib
|-- mm
|-- net
|-- scripts
`-- vmlinux
Using Kernel Patches Instead of full Linux Kernel Sources
---------------------------------------------------------
If you downloaded the kernel patches instead of the full Linux kernel
source, the process is a bit different for patching your kernel.
Let's assume you have your normal distro-supplied linux kernel sources in
/usr/src/linux-2.4.12 here. You will need to copy this to a new working
directory, so that you do not change your working kernel sources. To do
this, simply execute the following:
$ mkdir /usr/src/linux-2.4.17
$ mkdir /usr/src/linux-2.4.17/linux
$ cp -R /usr/src/linux-2.4.12 /usr/src/linux-2.4.17/linux
(using a 2.4.12 to 2.4.17 kernel upgrade as an example).
This will now create an identical copy of your 2.4.12 kernel sources in a
directory called /usr/src/linux-2.4.17/linux.
Let's begin patching!
$ cd /usr/src/linux-2.4.17
You should see one directory inside here called 'linux', and nothing else.
$ bzcat /tmp/patch-2.4.13.bz2 | patch -p0
You should see messages similar to the following, as the patch progresses:
[...]
patching file linux/kernel/exit.c
patching file linux/kernel/ksyms.c
patching file linux/kernel/printk.c
patching file linux/mm/filemap.c
This will unarchive and cat the patch into a pipe that the application
'patch' will intercept, and patch your kernel sources. *REMEMBER*, even
though the directory is named linux-2.4.17, the kernel sources inside it are
still version 2.4.12 sources until we patch them with each patch in order!
Also note that we did not 'untar' this patch, since it was only bzip2
compressed. If the patch were to be named 'patch-2.4.13.tar.bz2', the syntax
for unpacking it and sending it into patch would be identical to the way the
kernel unpacking was explained above.
Repeat the same process with all of the required patches. Remember, these
*MUST* be patched in order. They should patch 100% cleanly.
If the patch stops and asks you to "reverse" a patch, you've done something
wrong. If that happens, you should start over by removing the linux-2.4.17
directory and starting with the 'cp -R' syntax again. All of the kernel
patches *WILL* apply cleanly, if applied in the right order.
If you have successfully patched the kernel from 2.4.12 (in this example) to
2.4.17, you should now have a Makefile in /usr/src/linux-2.4.17/linux which
you verify contains the right kernel version:
$ head -4 /usr/src/linux-2.4.17/linux/Makefile
It should report the following:
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 17
EXTRAVERSION =
If it does not, something may have gone wrong, and must start over again, or
you missed a patch, and have to apply all of the missing parts. Once that's
done, you should have a full 2.4.17 linux kernel source tree sitting in
/usr/src/linux-2.4.17/linux
Onward!
Make & Break Linux Kernel Symlink
---------------------------------
The directory /usr/src/linux-2.4.17/linux should now be symlinked to
/usr/src/linux. If /usr/src/linux already exists as a real directory, you
must mv it to a new directory name.
$ find . -type d -name linux -maxdepth 1
If this returns a real directory called 'linux', it must be moved to another
directory name. You can find out which kernel sources reside in it by
looking at the top of the Makefile inside it.
$ head -4 linux/Makefile
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 12
EXTRAVERSION =
The concatenation of the first four lines of the Makefile will determine the
version of the sources in use in this tree. This will come in very handy
later on in the HOWTO.
The output of the above example tells us that the kernel sources inside
/usr/src/linux (a "real" directory) are for a 2.4.12 version kernel. That
directory must be moved out of the way so we can create the symlink in its
place.
$ mv /usr/src/linux /usr/src/linux-2.4.12
The structure inside /usr/src should now resemble the following:
/usr/src
|-- linux-2.4.12
`-- linux-2.4.17
Doing an 'ls -l' in this directory should show the following:
drwxr-xr-x 3 root root 1024 Jan 15 17:14 linux-2.4.12
drwxr-xr-x 3 root root 1024 Jan 1 11:33 linux-2.4.17
Now we have to create a symlink to the "current" Linux kernel sources in
this directory, we can do that with the following syntax:
$ ln -s /usr/src/linux-2.4.17/linux /usr/src/linux
Creating the symlink to /usr/src/linux from /usr/src/linux-2.4.17 should now
result in the following structure:
/usr/src
|-- linux -> linux-2.4.17 # the symlink we just created
|-- linux-2.4.12
`-- linux-2.4.17
Doing an 'ls -l' on this should now resemble the following:
lrwxrwxrwx 1 root root 23 Jan 15 16:21 linux -> linux-2.4.17/linux
drwxr-xr-x 3 root root 1024 Jan 15 17:14 linux-2.4.12
drwxr-xr-x 3 root root 1024 Jan 1 11:33 linux-2.4.17
The reason that this symlink is created is that it allows us to easily
manage multiple kernel versions and patches by simply breaking or making
this symlink so that it always points to the latest running kernel in use.
For example, let's say that kernel 2.4.18 is released, and you would like to
use that. You would unpack the kernel sources as described earlier into
/usr/src/linux-2.4.18, which would then create /usr/src/linux-2.4.18/linux,
and then simply deleting and making the new symlink will properly adjust
paths which rely on it, such as /usr/include/asm and others.
READ THOSE DOCS!
----------------
I know, everyone hates reading documentation, but this one's short, and it's
easy. Hidden within the kernel sources, is a file called 'Changes', found in
/usr/src/linux-2.4.17/linux/Documentation/Changes. This file details all of
the required packages you will need to upgrade in order to support features
found in this 2.4.17 kernel.
*DO NOT CONTINUE BUILDING* unless you read this file and upgrade packages
accordingly. Many things change from kernel to kernel, such as 'modutils' (a
package used to load, unload, and query kernel modules) and other important
pieces of software. Read this file, upgrade accordingly. Skipping this step
may cause more problems for you if you choose to ignore the required
upgrades.
Also within this directory is a series of other directories containing files
that you may want to read for additional information such as framebuffer
modelines (fb/*), device naming conventions (devices.txt) and other useful
files. The structure looks like this:
/usr/src/linux-2.4.17/linux/Documentation
.
|-- DocBook
|-- arm # For the Intel ARM architecture
|-- cdrom # CDROM device information
|-- cris
|-- fb # Kernel framebuffer information
|-- filesystems
|-- i2c
|-- i386 # Intel i386 PC architecture
|-- ia64 # 64-bit Intel architecture
|-- input # Input devices (keyboards, mice)
|-- isdn
|-- kbuild
|-- m68k # Motorola architecture
|-- mips # MIPS related information
|-- networking
|-- parisc # PA-RISC related build information
|-- power
|-- powerpc
|-- s390 # IBM s/390 Linux information
|-- sound
|-- sparc # Sparc
|-- sysctl
|-- telephony
|-- usb # Information related to the Universal Serial Bus
|-- video4linux
`-- vm # Virtual Machine
There are a lot of really good pieces of documentation in here, read them
when you need to find out something. Most of the answers you need for Linux
kernel questions ("Where is that device inode for my tape drive?"
[devices.txt]) can be found in here.
Cleaning, Building, Modularizing the Linux Kernel
-------------------------------------------------
Now we can begin the build process.
$ cd /usr/src/linux
$ make mrproper
Running 'mrproper' *FIRST* will remove any and all configurations, stale
object files (those with a .o extension), existing dependancies, and
anything else which may affect how your kernel is built.
Many people have reported problems where the default unpacked kernel had a
configuration option enabled, which breaks their ability to build a working
kernel on their architecture. I've only seen this happen in a development
kernel series, so I run this as a 'habitual precaution'. It can't hurt. Just
remember *NOT* to run it after you have configured your own kernel, or it
will remove the configuration file on you. Always back up your working
configurations first.
$ make {old|menu|x}config
This means one of three configuration options are available to you:
$ make oldconfig # This should be run first
$ make config
$ make menuconfig # ..and then this, which is preferred
$ make xconfig
make oldconfig
--------------
..will take your existing .config file, and prompt you for answers
to questions for things which are "new" in the kernel you are
building. If you copy a .config for a 2.2.19 kernel into your 2.4.17
directory, and run 'make oldconfig', all of the features which are
new in 2.4.17, but not found in 2.2.19 will prompt you for action.
Use this option if you are upgrading from any kernel that is older
than the one you are building, if you are re-using an existing
config file.
make config
-----------
..will use the standard ASCII text-mode configuration. This one is
guaranteed to work on any terminal. You cannot stop if you make a
mistake, and you cannot back up. It also does not recognize any
dependencies. You can make mistakes, and it will let you.
make menuconfig
---------------
..is a graphical text-mode style configuration process, but uses
ncurses and cursor keys to walk through menus for the configuration
options. It requires a working ncurses setup on the machine,
however. It will recognize dependencies and allows you to correct,
move around, and if you forget to include something, it will prompt
you for the missing parts.
make xconfig
------------
is a complete X-based configuration tool, using the mouse and menus.
It requires a working Tcl/Tk setup and X must be running to use it.
This option is for users who are easily distracted by shiny objects.
It will remember dependencies, and lets you go back if you make a
mistake. It requires some special libraries, so it may not work on
all systems.
Step through all of the options available to suit your needs for your target
system.
One thing you should enable by answering [Y] to is:
Prompt for development and/or incomplete code/drivers
(CONFIG_EXPERIMENTAL) [Y/n/?]
Doing this will open up other "experimental" options in the kernel
configuration, enabling full access to all of the kernel options available.
Sometimes you may want an option which is not in the generic configuration
enabled, and selecting [Y] here will ensure that you are presented with
those options.
It's important to make sure to go through every single menu and deselect all
of the things you are not going to use in your kernel. By default, many
standard options are selected (such as SCSI and the Toshiba busmouse).
Remember to start slow, using conservative options. Do not try to enable
everything first, or you'll have trouble tracking down kernel problems if it
should fail to build or boot. Once you have a working kernel, then begin to
add and tweak options as necessary.
Once your kernel is properly configured with all of your options, you can
exit and save the configuration. In /usr/src/linux (which is a symlink, as
you recall, not a real directory), you will now see a new file called
'.config' (/usr/src/linux/.config, or /usr/src/linux-2.4.17/linux/.config)
which contains all of your selected options. If you choose, you should back
up this file to another location for safekeeping, and stamp it with the
kernel version in the name, such as config-2.4.17.
You will only be able to see this file if you use 'ls -l' in that directory,
since the filename begins with a dot '.' character, it will be "hidden"
unless you use the "long" listing option of 'ls'.
The next step is to build the dependencies of the kernel, based on your
selected module options. This will walk through the .config file and your
selected options, and begin to build a .depend file for each directory.
Inside the file is a list of each .c file and all of the dependencies it
requires to build. An example of a portion of the contents of one
.depend file in /usr/src/linux/fs/autofs/.depend is:
inode.o: inode.c \
/usr/src/linux-2.4.17/include/linux/kernel.h \
/usr/src/linux-2.4.17/include/linux/slab.h \
/usr/src/linux-2.4.17/include/linux/file.h \
/usr/src/linux-2.4.17/include/linux/locks.h \
/usr/src/linux-2.4.17/include/asm/bitops.h \
autofs_i.h \
/usr/src/linux-2.4.17/include/linux/module.h
To build these dependancies, run the following in the kernel source
directory after successfully configuring and saving your kernel
configuration.
$ make dep
This step will also build in the proper kernel version into the modules
proper, so that a 'depmod' later on in the process will load the right
module for the right kernel in use.
At this point, a cleaning step can be run, though is not required. It
ensures that there are no stale .o object files lying around in the source
tree before you execute your final kernel build. Since this is the first
time we've built a kernel using this source tree as a base, there should not
be any "stale" object files lying around in the tree. Let's run the command
anyway, for 'habitual prevention' sake. This is different than the
'mrproper' target mentioned earlier because it will only discard object and
temporary files, but your kernel configuration (.config if you recall) will
remain intact.
$ make clean
It's a good point at this stage to back up your kernel configuration to
someplace safe. I usually create a directory under /usr/src called 'configs'
and put my configuration files in there. You can do that with the following
syntax:
$ mkdir /usr/src/configs
$ cp /usr/src/linux-2.4.17/linux/.config /usr/src/configs/config-2.4.17
You're nearly done. We can now compile all of those kernel sources into
objects and then begin linking those objects into a binary which your system
will boot as a kernel.
There are several output formats for your kernel, depending on your system
and requirements. Since this HOWTO was originally targeted for embedded
systems, we chose the one which gives us the most space savings; bzImage.
bzImage will created a compressed kernel image out of the sources linked
from the tree after compilation. You can safely use bzImage for your kernel
as well, even on PC architectures. It's the most-used kernel format now.
In the unlikely event that your system cannot boot bzImage kernels you can
still compile your kernel as zImage. zImage support will be removed at some
point in the future in favor of bzImage so we should get used to building it
as a bzImage file in this fashion now.
$ make bzImage
Once this process executes successfully (it is the longest step of the whole
process), we should have a shiny new kernel image sitting in
/usr/src/linux-2.4.17/linux/arch//boot/bzImage. On an Intel x86
machine, this would be in 'arch/i386/boot/bzImage'. On an ARM processor,
this would be in 'arch/arm/boot/bzImage'.
If the kernel process failed for any reason while making the kernel image,
examine the error and see if the problem can be determined by tracking back
into the file which caused the error. Many times it will be due to a source
file being mistakenly included, or a typo in the source itself. Remember,
start conservatively, then add tweaks later.
For example, if you are building a new kernel and aren't sure if it will
work, disable things like sound, USB, Infrared, and so on and just go with
the absolute bare-bones necessary components, such as IDE, video, keyboard.
With the kernel image properly built, we now have to contend with building
modules for the kernel itself. If we were on an embedded system, the
decision to build or not build modules is an important one.
If you choose to go with a monolithic kernel (where all modules required are
built into the bzImage binary itself), you can easily skip the two module
build/install steps here.
Using modules is the preferred approach in most cases, since modules can be
loaded and unloaded at runtime, without rebooting. Building the modules into
the kernel binary "monolithically" will take up unnecessary memory and
resource overhead, and cannot be unloaded without rebooting.
If you are building a very small kernel image, and using dynamically-loaded
modules, you will need to execute the following command in the kernel source
tree:
$ make modules
Each of the modules required by the .config file in /usr/src/linux will then
be built, and a resulting object file will be created from their contents.
In a standard Linux system, you can now move the kernel, System.map and
modules into place.
If you are *REBUILDING* a kernel, it is very important at this stage to
*REMOVE* any and all existing modules which match the kernel you are
building. If the 'make modules' command above finished without errors, you
can be sure that the modules are intact, and removing existing ones will not
cause you trouble.
Since we are dealing with a 2.4.17 kernel, we would want to remove modules
found in /lib/modules/2.4.17 before installing the newly built modules. You
can do that with the following command:
$ rm -Rf /lib/modules/2.4.17
*WARNING* -- be *VERY* careful with any use of the 'rm' command as the root
user. If you mistype a directory name, the command above can have very
drastic and unexpected results on your system. If unsure, alias the 'rm'
command to prompt you for the deletions, using the following:
$ alias rm='rm -i'
Once any conflicting existing modules are removed, we can then install the
newly built ones in our shiny new kernel source tree. To install the
modules, you can use the stock 'modules_install' target included in the
Makefile:
$ make modules_install
This will place the modules in a hierarchy under /lib/modules/2.4.17 (using
our 2.4.17 kernel as an example).
Now we must move the kernel into place for a bootloader to find it. Assuming
we're using LILO, we should move the
/usr/src/linux-2.4.17/linux/arch//boot/bzImage kernel image into
a file called /boot/vmlinuz-2.4.17.
$ cd /usr/src/linux-2.4.17/linux
$ mv arch/i386/boot/bzImage /boot/vmlinuz-2.4.17
This assumes an Intel x86 architecture. The file 'System.map' can be used as
a diagnostic tool when the kernel has a kernel 'oops' or crashes on you. It
will report a memory location and a driver or drivers which caused the crash
and System.map will tell you which location caused the problem.
You can use the tool ksymoops to determine where and why this happened. On a
tried and true embedded system, this file should no longer be required in
production systems. For now, the file should be placed in /boot with the
kernel version number following it.
$ mv /usr/src/linux/System.map /boot/System.map-2.4.17
You may also safely remove any System.map file found in /boot, since it
would be redundant in this case. All System.map files should have a kernel
version appended to the end of their filename.
At this point, we would re-initialize our bootloader with this new
information. If we were using LILO, you would make a final edit to
/etc/lilo.conf to point to this new kernel image. A very simplistic
example of an /etc/lilo.conf file to boot this kernel could be:
$ vi /etc/lilo.conf
boot=/dev/hda
root=/dev/hda1
compact
install=/boot/boot.b
map=/boot/map
delay=3
default=Linux
image=/boot/vmlinuz-2.4.12 # our original distribution kernel
label=Linux
read-only
image=/boot/vmlinuz-2.4.17
label=2.4.17
read-only
$ /sbin/lilo -v -v -t
Using '-v -v' here ensures more verbosity, so we can catch any errors that
occur, and we use the '-t' here to test what lilo would actually do, but not
actually write out anything. If it appears that lilo executed successfully,
you can then run:
$ /sbin/lilo -v -v
$ /sbin/lilo -R linux-2.4.17
You should now have a fully functional Linux kernel on your system, your
bootloader should be updated, and modules should be in place under
/lib/modules/2.4.17. You may safely reboot the system, and see if the new
kernel works for you.
If the kernel fails to boot for any reason whatsoever, just simply reboot
again, and your previous kernel should boot as normal. The use of the '-R'
command with the second lilo syntax above allowed us to change the kernel
arguments to lilo for one-boot-only, which lets the machine boot to the new
kernel, and if it fails, boot to the old kernel again as normal.
If you find that this kernel suits your needs, you may then change the
'default=Linux' line in your lilo.conf to point to the new 'linux-2.4.17'
label instead, so that the new 2.4.17 linux kernel boots by default.
-DD