Compiling your own kernel

Valid HTML 4.01!


Although I have been using and promoting Linux for several years, like many others I have always fought shy of recompiling or upgrading my kernel because I was a little daunted by the idea. Add to that a few failures which have left systems unable to boot and required re-installing. The result, a marked reluctance to try... The experts all say it is easy, but the only way they have become experts is by doing, over and over again. The problem is that experts are sometimes not the best people to ask because they can assume too much knowledge.
I am not an expert, and the idea of this page is to try and outline some of the pitfalls I have been tripped up by and how to avoid them next time, so if I state the blindly obvious, it may not be to others....
If on the other hand you spot any deliberate errors (!!) please let me know so I can correct them.
This guide is developed whilst using Slackware 9.1, most of this should be generally applicable, some may however be specific.
 
What is the kernel? The kernel is the core of the operating system. It controls the overall execution of processes and applications. The parts which it is made up of are determined by the options set when it is compiled. Generally options can be compiled into the kernel or loaded dynamically as modules. So for instance a network card driver could be included in the kernel as a "Monolithic" driver or loaded as a module with modprobe. During the compiling process selecting an "*" compiles the option into the kernel, selecting a "M" compiles it as a module.
The methods below are not the only way to do things, but they have worked for me. If you have any other ways, email me and I will try to include them.
 
Steps to take
  • New kernel
    • Download the latest kernel source from www.kernel.org.
    • Save the .tar.gz to /usr/src/kernel-version.tar.gz (eg. /usr/src/linux-2.4.25.tar.gz)
    • cd /usr/src
    • Uncompress the file with "gunzip linux-2.4.25.tar.gz"
    • Extract the archive with "tar -xvf linux-2.4.25.tar"
    • These two steps can be combined with "tar -zxvf linux-2.4.25.tar.gz"
    • Remove the old symbolic link to /usr/src/linux with "rm linux"
    • Create a new symbolic link with "ln -s linux-2.4.25 linux"
    • Enter the new directory with "cd linux"
    • Next have a look in the Documentation directory, it has some good advice about the next steps.
    • Clean out all old configs etc. with "make mrproper"
    • Run the kernel curses based config with "make menuconfig" ( or the X equivalent)
    • --see the section below regarding options to choose....
    • Afer exiting from the config, run "make dep" to calculate dependencies.
    • Start the compile with "make bzImage"
    • Continue with "make modules" and then "make modules_install"
    • These can be abbreviated with "make dep bzImage modules modules_install"
    • Just for interest you can time the operation with "time make dep bzImage ...etc."
    • Assuming no errors, copy the System.map file to /boot with "cp System.map /boot/System.map"
      Resist the urge to call it System.map.2.4.25, the reason for this is that the kernel will look for /boot/System.map if it has a panic, it doesn't look for anything else. (see "man klogd")
    • "cd arch/i386/boot" and "cp bzImage /boot/vmlinuz-2.4.25" to copy the kernel image to /boot
    • Why is it called vmlinuz? I don't know, it just is so answers on a postcard please...
    • Create a sym link for the kernel, "ln -s vmlinuz-2.4.25 vmlinuz"
    • Check and check again the Linux loader config in /erc/lilo.conf, see below for more details.
    • Reboot and select the new kernel from Lilo's boot options
 
  • Modifying an existing kernel.
    • Enter the source directory "cd /usr/src/linux" .
    • Run the kernel curses based config with "make menuconfig" ( or the X equivalent)
    • --see the section below regarding options to choose....
    • Afer exiting from the config, run "make dep" to calculate dependencies.
    • Start the compile with "make bzImage"
    • Continue with "make modules" and then "make modules_install"
    • These can be abbreviated with "make dep bzImage modules modules_install"
    • Assuming no errors, copy the System.map file to /boot with "cp System.map /boot/System.map", you may want to rename the original or it will be overwritten.
    • "cd arch/i386/boot" and "cp bzImage /boot/vmlinuz-2.4.25" to copy the kernel image to /boot
    • if you want, do the same for the kernel, "ln -s vmlinuz-2.4.25 vmlinuz"
    • Check and check again the Linux loader config in /etc/lilo.conf, see below for more details.
    • Reboot and select the new kernel from Lilo's boot options
  • Upgrading a kernel with the same config as the previous one.
    • Say you have an older kernel already configured (eg 2.4.24) and you want to go to 2.4.25 without all the trouble of redoing all the kernel options, you can copy the old .config from 2.4.24 to the new kernel directory as .config AND .config.old, then run "make oldconfig".
      The "make oldconfig" will go through every question in the kernel config and answer it with the same answer as was in the .config from your previous configuration, but if there is a new config option which was not in the previous kernel, it will stop and prompt you for an answer before carrying on.
 
Lilo and lilo.conf
Lilo stands for the LInux LOader and is a boot manager. Grub is similar but as I have less experience of it, I will not discuss it further. Lilo takes its config from /etc/lilo.conf and writes the info to the boot sector of your hard disk. Lilo can boot other operating systems as well as Linux by specifying the partition to boot in the config.
*ALWAYS* run lilo after altering lilo.conf or installing a new kernel to ensure that the loader in the boot sector has been refreshed. Not doing this is a very good way to get an unbootable system.
boot = /dev/hda
prompt
timeout = 50
vga = normal
lba32

image = /boot/vmlinuz-2.4.25
root = /dev/hda1
label = Linux
read-only

image = /boot/vmlinuz-2.4.22
root = /dev/hda1
label = Backup
read-only

image = /boot/vmlinuz-original
root = /dev/hda1
label = Slackware
read-only
 
If the compile is just modifying an existing kernel, you can start with "make menuconfig" from a shell, X window supports the xconfig.
If the kernel is being produced from a new kernel tree (eg. upgrading from 2.4.22 to 2.4.25) you will need to run a make mrproper which cleans out the previous config which may have been version specific.
select architecture
test which options are needed by selecting modules first, test compile and the recompile with the correct drivers
lilo.conf
run lilo !!
read the man page, & apropos
 
Thanks to Darren Austin for proof reading this and making some helpful suggestions.

Up a level.