Compiling the Linux kernel

About

The purpose of this document is to help beginner Linux users compile a custom 2.6.x kernel. The end result is adding to your system a newly configured and compiled kernel, keeping the option to boot the original kernel that the system was using previously. The instructions are overly verbose and targeted at those who have limited console experience and have never compiled the Linux kernel.

If you have trouble moving around in a Linux system using the command prompt you should probably see the Linux Console Introduction first. You’ll be doing many a cd and mv. Get comfortable with that stuff before attempting this.

The instructions given should be followed in spirit since all distributions have different configurations (i.e. symlinks to directories, storing the kernel files in different directories). They should only be used as a guide. I suppose that they could be followed exactly on a Slackware box, but that’s just speculation.

All commands in this document should be executed as root. Either log in as root or switch users to root using the su - command and the root user’s password.

Downloading and Extracting

Download a new kernel from kernel.org! You’ll need to select the full kernel 2.6.x source using the “F” link next to “The latest stable version of the kernel is…” I’ll call this new kernel linux-2.6.x.

Open a terminal of some sort like xterm or just use the console. Go to where you downloaded the sources. This was probably your home directory or Desktop directory.

$ cd
or
$ cd ~/Desktop

Most people keep their Linux kernel sources in /usr/src, so move the archive downloaded to that directory.

$ mv linux-2.6.x.tar.gz /usr/src
or
$ mv linux-2.6.x.tar.bz2 /usr/src

Change to the /usr/src directory and untar/gunzip the new kernel sources. This will create a directory containing the source.

$ cd /usr/src
$ tar zxf linux-2.6.x.tar.gz
or
$ tar jxf linux-2.6.x.tar.bz2

Change directory into the new sources.

$ cd linux-2.6.x

Configuring Kernel Options

Configure the kernel options by running make. The following command will take you into an interactive menu system where you can select the appropriate options. Read the rest of this section to gain a better understanding of kernel configuring, then look over the next subsection for some configuration tips.

$ make menuconfig

There are other ways to perform this step, such as make xconfig, which uses a graphical user interface written in QT. Also, if you are upgrading a minor version, such as moving from 2.6.14 to 2.6.15, the old configuration can be used. Copy the file .config from the 2.6.14 directory into the 2.6.15 directory and run make oldconfig. This will only ask you about new or changed options. You can just hold enter to accept all of the defaults and then review the configuration with make menuconfig.

If the last step is overwhelming or is going to take you a lot of time (and it probably will) you can safely stop here. You can always repeat make menuconfig, work on your configuration, save it, and come back to it. Once you’ve got one you think you want to try, continue. HOWEVER, once you continue past this section (and on to Backing Up Your Working Kernel) please finish the rest of this document so you don’t screw up your machine horribly!

Informational Programs

When configuring the Linux kernel, you basically read a LOT of help files and get to know your hardware. Select the options you need to make your hardware work. You will find the lsmod, lspci, and dmesg commands helpful in identifying hardware and options you need to enable.

Built In vs. Modules

Almost every kernel option may be built in statically or loaded dynamically via kernel modules. In many cases it is simply a matter of preference as to which way to build any particular part of the kernel. There are a few important exceptions to this rule such as statically including support for your IDE chipset, and making sound modules so that ALSA utilities will work correctly.

The following lists are suggestions, not the rule. The section in which each mentioned option can be found in is in parenthesis. Feel free to experiment, but keep a working kernel backed up as covered in a later section!

Build these components in statically / Make sure these are enabled:

  • Enable loadable module support (Loadable module support)
    • Module unloading
    • Automatic kernel module loading
  • (MTRR) Memory type range register support (Processor type and features)
  • ACPI support - This is a newer replacement for APM - (Processor type and features)
  • Kernel support for ELF binaries
  • Your IDE chipset (Device Drivers -> ATA/ATAPI/MFM/RLL support)
  • Your root filesystem type (Filesystems)
  • Packet Socket and mmaped IO (Network Options)
  • TCP/IP Networking (Network Options)

Build these components as modules:

  • SCSI and SCSI disk support - for USB disks - (Device Drivers -> SCSI device support)
  • Sound support and your particular sound device under ALSA (Device Drivers -> Sound)
  • Network card (Device Drivers -> Network Device Support)
  • Any connection ports such as USB, Firewire, Parallel (all under Device Drivers)
  • AGP (Device Drivers -> Character Devices) or PCI Express (BUS Options)
  • Any other non-critical (don’t need it to boot) device support

Do NOT select these components:

  • Auditing support (General Setup)
  • Legacy (BSD) PTY support (Device Drivers -> Character Devices)
  • Profiling support (Instrumentation Support)
  • Nothing in (Kernel Hacking) section

Seriously consider if you need support for:

  • Frame buffer stuff - this is not the X GUI - (Device Drivers -> Graphics Support)
  • Symmetric multiprocessor support - dual core and multiple processors - (Processor type and features)

Back Up Your Working Kernel

The following instructions describe how to backup your current kernel so it won’t be overwritten by the new one.

Systems using LILO bootloader

Check to see if you have lilo.

$ which lilo

That command should return something like the following.

/sbin/lilo

Change directory to where your current kernel file is located.

$ cd /boot

Rename the kernel file to another name. Most distributions use vmlinuz for the name of the kernel file since that is the default. If yours is different, refer to your boot loader configuration file (/etc/lilo.conf) to see what your current kernel image file is.

$ mv vmlinuz vmlinuz-old

Don’t reboot your machine without either:

  1. Giving the kernel its name back with mv vmlinuz-old vmlinuz
  2. Following through the rest of this document.

Now edit /etc/lilo.conf and prepare to have two kernels installed on the system. Open /etc/lilo.conf in your favorite text editor such as vim, emacs, or pico. It should look something like the following code block. Don’t worry if you don’t have all of the lines listed here, or if you have more lines. Don’t change them or add to them unless you know what you’re doing.

Do not change your file just to make it look like this. Follow the instructions below instead.

image=/boot/vmlinuz
label=linux
read-only
root=/dev/hda5

Copy the section beginning with image=/boot/vmlinuz exactly as it is. Then edit the image name, simply changing the image name to image=/boot/vmlinuz-old and the label to label=linux-old so that now /etc/lilo.conf looks like:

image=/boot/vmlinuz
        label=linux
        read-only
        root=/dev/hda5

image=/boot/vmlinuz-old
        label=linux-old
        read-only
        root=/dev/hda5

Now we’re ready to compile the new kernel and add it to the system.

Systems using GRUB bootloader

If someone would like to send me instructions for the GRUB bootloader I will include them here. I do not use GRUB on system that I custom compile kernels for.

Compiling and Installing

Go back to where you did make menuconfig.

$ cd /usr/src/linux-2.6.x

Execute the following instructions.

$ make
$ make modules_install
$ make install
or, all as one command
$ make && make modules_install && make install

The make install command does some nice things for you that normally wouldn’t be done when manually installing the kernel. It installs your kernel by copying vmlinuz and System.map files from their location in the source directory to /boot. Then it runs lilo for you, so the last thing you should see is:

Added linux *Added linux-old

If you get the above with no error messages from lilo you are good to go and can reboot to try your new kernel. If you get ANY error messages from lilo you should certainly get them straightened out before you reboot, since its a good indication that your machine won’t be able to boot up due to missing kernel files or similar problems.

If all goes well and you get “Welcome to linux 2.x.y” congratulations, otherwise something goofed and you’ll have to retrace your steps.

If bad stuff happens, remember you can boot back to your old kernel with linux-old.