Rebuilding and Installing the Linux Kernel

This is a fairly brief and introductory howto concerning rebuilding the linux kernel, and actually
getting it to boot and run correctly.  Unfortunately, the Linux community can be a bit full of
themselves, and rather undisciplined when it comes to creating useable processes, and
documenting them in a way that can be read by people other than kernel developers.  So, I've
found it difficult to locate good instructions on how to do some very basic things.  Hence, this

Of course, with all howtos, I assume no responsibility for anything bad that happens if you
the advice contained in this document.  I'm merely trying to be helpful, by conveying
worked for me.   Comments are appreciated, though.


Just to clear up exactly what kind of Linux build I did, this document was written with SuSE
Linux 8.1 (kernel version 2.4.19 to 2.4.21) in mind. I also use the GRUB bootloader to
boot my kernels.  I'm sure much of this is consistent among other Linux distributions,
but I can't guarantee that, and want you to know that up front :)

The Steps

0) Most important step.  Backup everything.  Save your whole system to a tape drive, or CD-RW
or whatever you have.  Also, make sure you have a working boot disk and/or rescue disk in
case your failure leaves the system unbootable.  Do not skip this step!!!!

1) First, get yourself a new set of fresh kernel source, and unpack it into its own subdirectory
in /usr/src, such as

I often use the SuSE linux download site at  Also, and
can be good sources of this stuff.  Of course, these provide RPM packages, which aren't of
much use if your linux doesn't use the Redhat Package Manager.  SuSE does, so it's nicer than
just grabbing tarballs.

2) Then, I would start with the same basic configuration as you have for your existing kernel.  If that
kernel by chance still has its source tree hanging around, copy the config file from:


into your new /usr/src/linux* directory.

If this file doesn't exist, then just go into the new source directory (/usr/src/linux-new-version) and
>>make menuconfig

This will give you some decent defaults.  I would then carefully browse thru the menus and select or
deselect the things you’re absolutely sure you know you need (or don't).   If you're unsure, I would
highlight and item and hit 'M", which will select that piece of code to be compiled as a dynamically
loadable module, rather than be built directly into the new kernel.  If you know you definitely don't
want something (like IR support, Linux telephony, or USB support), then you can deselect those
items in the menuconfig, and save yourself some build time, which might be significant the first time
you do this, and possibly have to run thru the whole process a couple times.

3) when running the menu config utility, I would try to make sure you have everything in the kernel
that will be needed to boot the basic system.  So, if you have an important filesystem (like / or /var)
on a SCSI disk, I'd build in the SCSI drivers.  Specialty filesystems, like XFS, can also have their
support modules built into the kernel.  In general, you'll get better performance from a kernel built-in
module, assuming it's a module that's fundamental to your system running, and not some sparsely-
needed capability.

4). after running and saving out of  'make menuconfig', then execute
>> make dep

to make the dependencies for all the code.

5) next, it's time to build the kernel.  Execute,
>> make bzImage

to make the bz compressed version of the kernel.  Not everyone uses this kind of kernel, but it's what
I use.  Search specifically on kernel types if this doesn't work for you.  I might also recommend
saving all the kernel build output if you're not confident of success:

>> make bzImage > build.log 2>&1 &
>> tail -f build.log

this will allow you to go back and see errors if there are any.  The build will create voluminous output
that probably will swamp your terminal window's buffer.

6)  If that works, there should be a bzImage file in your source tree.  Find it with

>> cd /usr/src/linux-whatever
>> find . -name bzImage

Then, copy this file to the boot directory, probably like this:

>> cp /usr/src/linux-whatever/arch/i386/boot/bzImage /boot/bzImage.recompile.todaysdate

7)  Next, you have to build the kernel shared object modules.  Execute:
>> make modules > modules.log 2>&1 &
>> tail -f modules.log

If that succeeds, you should have a ton of *.o files under your source tree.

8)  The next step can be a little tricky, especially if this is a re-build of an existing kernel version,
rather than a build of a brand new version of kernel (e.g. old is 2.4.19, new is still 2.4.19, versus
migrating to 2.4.21).  If the kernel modules are inconsistent, maybe because you turned off some
features in the menuconfig, that you used to have, then booting and running the new kernel can be
a problem.  For that reason, I always like to have a new modules directory to install to under:

If you're migrating to a new kernel version, then the next step of the build process handles this for
you, but if you're just rebuilding the same basic kernel version, you have a problem.  I handle it like

>> cd /lib/modules
>> mv ./2.4.19-4GB ./2.4.19-oldmodules

to save a backup in case the new kernel flops.  Then, I create a new empty directory for the new
modules to go, where they won't be mixing with old modules that may cause conflicts.

>> mkdir ./2.4.19-4GB

This example shows me preparing to install a new build of a 2.4.19 kernel, which is also my current
kernel version.

9) Then go back to the /usr/src/linux* directory and execute:

>> make modules_install.

This should populate your empty /lib/modules/2.4.19-or-whatever directory with all the fresh modules.
To check the consistency and update dependencies, you should then do:

>> depmod -a

If this returns nothing to stdout, then it worked ok.  To note, if you are changing kernel versions, then
depmod will be updating dependencies for the old/current kernel, which is not what you want.  So,
in that case, be sure to do this

>> depmod -a -F /usr/src/linux-2.4.21-151-default/ 2.4.21-151-default

if you are moving to 2.4.21-151, with a source tree directory named 2.4.21-151.  

10)  You then need to update the file which is an index to all the new kernel modules.  Copy
it into an appropriately named file in your boot directory.

>> cp /usr/src/linux-2.4.21-151-default/ /boot/

By renaming it as such, you can allow multiple kernel versions to be bootable, which is certainly desirable,
at least until you verify the new one works.  You never want to delete the old kernel image (bzImage), the, the initrd (later), or the modules directory from an older kernel version until the new one
is working smoothly.  If the new kernel is bad, you can use a boot disk to access your system, and copy
the old files back into their original places to revert to your last working configuration.

11) Now a tricky issue.  If your kernel has been built with everything it needs to startup your system,
then we're probably in the clear.  However, often times there are more things needed to assist the kernel
in starting up.  The big thing that comes to my mind is SCSI drivers if one of your main filesystems needed
during bootup is on a SCSI disk.  Take a look at /etc/sysconfig/kernel.  Mine looks like this:
# This variable contains the list of modules to be added to the initial
# ramdisk by calling the script "mk_initrd"
# (like drivers for scsi-controllers, for lvm or reiserfs)

# # Size parameter for mounting the shmfs filesystem. The kernel defaults # to 50% of the available RAM size, but this might not be enough for # some special setups. # SHMFS_SIZE=""

If your system needs help booting, you may have some things listed under INITRD_MODULES (I don't).
If so, take a close look at these things.  Verify that these things are not now built into the kernel, which
you might have choosen to do during the menuconfig step.  You also may need to add things to this line,
but that's beyond the scope of this doc.  Google around for INITRD_MODULES and your particular
problem item (like SCSI, RAID, whatever) if your new kernel won't boot.  

Anyway, after verifying the contents of /etc/sysconfig/kernel, then you need to update the initial ramdisk
image file, called initrd, typically stored in the /boot directory. Do this by executing:

>> mk_initrd -k /boot/bzImage.recompile.todaysdate -i /boot/initrd.newversion

If mk_initrd isn't it, try mkinitrd.  I love it when Linux can't decide on simple names like this :(
By the way, if INITRD_MODULES is correctly empty, then you should get a message that
no initrd is needed.  From here on out, then, don't worry about the initrd.

12)  Similar to the INITRD_MODULES variable for the initial ramdisk definition, you want to make
sure that changes to your kernel's config don't conflict with the /etc/modules.conf file.

If you decided to build certain items into the kernel, rather than load them as modules, then there is no
need to have them listed in /etc/modules.conf.  So, you should comment them out with a # in modules.conf.
Here's an excerpt from my modules.conf file, after I moved scsi card support to my kernel.

#NATHAN: this is built into kernel now:
#alias scsi_hostadapter aic7xxx_old

After doing this, you should run the depmod command again as mentioned before.  Perhaps you should
do this before you run depmod for the first time, but it's not going to hurt anything to do them in this

13)  I admit I don't fully understand this step, but I'm sure it doesn't hurt to do it, and it has proven
necessary in the past, when my computer never even got past the bootloader startup stage (it just
hung with a screen that said "GRUB").  So, you can do it to make sure.  You are basically updating the
bootloader, GRUB.

>> grub --batch --device-map=/boot/grub/ < /etc/grub.conf

This may update the stage* files in the /boot/grub directory.  That's it for this step.

14)  Finally, you need to update your bootloader to reflect your new kernel and friends.  For me, I use
the GRUB bootloader, so the modification I make is to /boot/grub/menu.lst.  Here is a link to my version
of the file.

The important part is to create new entry for the new kernel (don't just overwrite the old kernel entry ..
until things work for sure, let the old and new versions be bootable).  Here is an entry for a new kernel
which does require an initial ramdisk, and the old kernel, which did.  My root directory (/) is mounted
on the /dev/hdb3 disk partition.  I believe the (hd0,2) syntax refers to the 0th (first) disk in the
/boot/grub/ file, and the 2 refers to the 3rd disk partition (0, 1, then 2), which is the same
thing as saying "/dev/hdb3".  Don't ask me why the mix in syntax.

title Linux-2.4.21
    kernel (hd0,2)/boot/ ro root=/dev/hdb3

title Linux-2.4.19     kernel (hd0,2)/boot/bzImage.recompile ro root=/dev/hdb3     initrd (hd0,2)/boot/initrd

15) You actually get to reboot your computer, and keep your fingers crossed.  Hopefully, this will do it.
Most probably seem to be with either not updating your bootloader correctly to load the new kernel
and kernel-related files.  Or, having an inconsistent or insufficient set of modules.  Usually, my very
deliberate process above will prevent module problems.  However, if you do have problems, and can
get back into your problem-child system, try re-running make 'menuconfig' and try removing fewer
modules from the build.  You can always go back later and slowly remove modules to put your source
tree (and kernel) on an object code diet.

The End

Some of these steps may be slightly redundant (although not much), but I like to do it this way every time
to see exactly what fails if something is done wrong.  And hey, this process works!  Good luck ....

powered by Debian

Copyright ©2003-2016 Enscand, Inc.
All Rights Reserved

Modified February 21, 2016