To build a new kernel from scratch, do the following steps.
In these notes, we'll call the new kernel "2.x.y". You may want to append a
revision number to the kernel, if you will have multiple kernels for a
particular version, in which case, the new kernel would be "2.x.y-nn". Do
everything as root.
- Create a new directory in the directory tree
/usr/src called "/usr/src/linux-2.x.y".
- Unlink the "/usr/src/linux" symlink from wherever it points and link
it to the new directory:
ln -s /usr/src/linux-2.x.y /usr/src/linux
Much of the build process uses this
symlink to find the actual stuff it is working on. Make sure that
"/usr/src/linux" is a link to the proper kernel version or the build
process will overwrite an existing kernel.
- Download the new kernel source, unpack it and untar it. If you untar
it while in "/usr/src", tar will put the source tree in "linux" which will
cause it to end up in "/usr/src/linux", hence "/usr/src/linux-2.x.y":
cd /usr/src
tar -xvf /usr/src/linux-2.x.y/linux-2.x.y.tar
- For the rest of the process, you'll want to be in the build source
tree:
cd /usr/src/linux
- If you have any patches to apply, now is the time to do them, before
you start building the kernel. If you build the kernel first and then
apply the patches, chances are good that most of the build will only have
to be done over anyway. Typically:
patch -p1 < abc.2.x.y.nnnn.patch
Make sure that you have the correct
patches for your version of the kernel because there isn't really an undo
command. You may want to try a dry run first:
patch -p1 --dry-run < abc.2.x.y.nnnn.patch
You may also want to create back-em-up
files as the patches are applied so that they can be backed out:
patch -p1 -b < abc.2.x.y.nnnn.patch
- Clean out the source tree of any previously built modules, if you
wish (note that this step deletes any file that starts with ".config"
so, if you care about such files, make sure you have a copy of them handy):
make mrproper
The first time around, you shouldn't
need to do this but it couldn't hurt. If you move any modules from the
loadable module directory into the kernel or out of the kernel into the
module directory, you had better do this step to reset the old module
definitions.
- If you'd like to get started from an existing kernel, copy ".config"
from "/usr/src/linux-orig.kernel.tree" or "/boot" to "/usr/src/linux":
cp ../linux-orig.kernel.tree/.config .
At this point, you should make the old
configuration. This will prompt you for any new options that were added
since the version of the kernel that you copied the configuration from:
make oldconfig
You can also run "oldconfig" with no
".config" file present, in which case it will extract all of the kernel
options from the currently running kernel and then prompt for any new
options.
If you are just creating a new
version of the kernel to add an option or really know what you're doing,
you can just hack the ".config" file with a text editor.
- Alternately, you can start from scratch by building a new configuration
through one of GUI kernel configurators. Run either the X-Windows version
of the configurator or the n-curses version:
make xconfig
or
make menuconfig
If you want text-only configuration, run:
make config
This will ask you about each
configuration option in sequence.
- You may want to diff the original kernel configuration and the one left
behind by the configurator. We do this to see if anything too crazy has
been selected:
diff .config /usr/src/linux-orig.kernel.tree/.config
- Build the dependency files:
make dep
This will ensure that all of the header
files and other stuff needed for the build are present.
- If you would like to recompile the build from scratch at any time, you
can clean out the previously built modules from the source tree:
make clean
However, if you move any modules from
the loadable module directory into the kernel or out of the kernel into
the module directory, you had better start at "make mrproper" (Step 6) to
reset the old module definitions. Note that you should pay attention to
the part about the ".config" file being deleted by "make mrproper".
- If you want a revision number for the kernel, edit the "Makefile" and
change the line: "EXTRAVERSION =" to a unique revision number:
EXTRAVERSION = -nn
You can add any string that you want,
so you can add your initials or anything else you'd like.
Even if you don't want a unique version,
number for your kernel, you should probably hack the Makefile. The
standard build is given a suffix of "-nn.n.ncustom" which can screw things
up later on down the road. If you don't want a suffix, at least remove
the word "custom" from the suffix set in the Makefile. Typically, you
would do this if you're just building the kernel itself (no modules) to
make a small change that is essentially a direct replacement for your
existing kernel.
- Build the kernel itself:
make bzImage
Note that, if the build of the kernel
fails to find "as86", you may need to install the "dev86" RPM (found on
one of your system CDs). For example:
rpm -i ../../dev86-x.y.z-n.i386.rpm
- Build all of the modules used by the kernel:
make modules
- Install the modules used by the kernel in the "/lib/modules" tree under
this kernel's directory:
make modules_install
This will not overwrite any existing
kernel modules. It will create a new modules directory for
"/lib/modules/linux-2.x.y". You should do this step, even if you didn't
build any modules.
- Build the module dependency tree (this should be done automatically at
boot time but wouldn't you like to know that it actually works). If you
asked to keep version numbers on the kernel symbols, be sure you point
depmod at the system map for the kernel you've built:
/sbin/depmod -a 2.x.y -F System.map
The result is placed in
"/lib/modules/2.x.y/modules.dep" and "modules.pcimap".
- Copy the new, compressed kernel to the boot directory:
cp arch/i386/boot/bzImage /boot/vmlinuz-2.x.y
For the time being, don't link
"/boot/vmlinuz" to this new kernel. We'll test it first.
- Copy the system map to the boot directory:
cp System.map /boot/System.map-2.x.y
Don't link "/boot/System.map" to this
new map. That gets done automatically at boot time.
- If you have a SCSI adapter and made your SCSI driver modular, build a
new initrd image (note that there are few practical reasons to make the
SCSI driver modular in a custom kernel). The initrd image is needed for
loading your SCSI module at boot time. However, unless you have a
specific reason to create an initrd image, do not create one and do not
add it to lilo.conf.
The shell script /sbin/mkinitrd can
build a proper initrd image for your machine if the following conditions
are met:
Change to "/boot" and make the initial
RAM disk with:
cd /boot
/sbin/mkinitrd initrd-2.x.y.img 2.a.b
If the conditions above are not met and
you wish to make the initial RAM disk by hand, perhaps using a special
disk driver, change to "/boot" and make it with:
cd /boot
/sbin/mkinitrd --preload scsi_mod --preload sd_mod --with SpecialDriver
initrd-2.x.y.img 2.a.b
Note that "2.a.b" is the kernel whose
modules (from "/lib/modules") should be used in the initrd image (not
necessarily the same as the version number of the currently running
kernel).
- Edit "/etc/lilo.conf" to boot the new kernel. Add a new section for
the kernel so that it can be tested first, before it is installed for
good. To do this, if the existing "lilo.conf" reads:
image=/boot/vmlinuz-2.2.16-22
label=linux
read-only
root=/dev/hda6
add:
image=/boot/vmlinuz-2.x.y
label=test-2.x.y
read-only
root=/dev/hda6
or, if you built an initrd in the step above, add:
image=/boot/vmlinuz-2.x.y
label=test-2.x.y
initrd=/boot/initrd-2.x.y.img
read-only
root=/dev/hda6
- Set up lilo to use the new configuration:
/sbin/lilo -v
Incidentally, if you recompile the
kernel at some point in the future, you should rerun lilo each time you
copy a new kernel image into the /boot directory. If you skip this step,
sometimes you will get lucky and it will work but sometimes you will get
a failure to load the kernel. Its best to just remember to do it always.
- When you are happy that all is working well, make the new kernel be the
default. Label the new kernel "linux" and label the original kernel
something like "RedHat-orig" in "/etc/lilo.conf". For example:
image=/boot/vmlinuz-2.x.y
label=linux
read-only
root=/dev/hda6
image=/boot/vmlinuz-2.2.16-22
label=RedHat-orig
read-only
root=/dev/hda6
- Rerun lilo to use the new configuration:
/sbin/lilo -v
- It is pretty safe to say that you can ignore the symlinks in "/boot"
that point to "kernel.h", "module-info" and "vmlinuz". They don't appear
to have any impact on things. Its not even clear what "module-info" does,
nor the link to "vmlinuz".