April 14, 2011, 9:20 p.m.
posted by lambda
Compile a Kernel
Linux device support is largely a double-edged sword. On the one hand, an up-to-date distribution with a recent kernel is likely to configure all your hardware automatically, and you won't need to lift a finger. On the other hand, if you have some hardware that is not supported within the kernel itself, life suddenly becomes a lot more difficult; manuals need to be read, Google needs to be searched, and your head needs to be scratched. Lack of universal device support is why Linux users need to research their peripheral purchases before they buy.
When your Linux kernel doesn't already support a particular device, you often need to compile in support yourself. If the code for your device is experimental, you might need to patch the kernel before you compile it. Many users are nervous about compiling any program, and recompiling the kernel makes them even more so. The "archaic" process of compiling the kernel is often avoided by many users who live in hope that the kernel that ships with the next version of their distribution will provide the hardware support they need.
Although daunting at first, compiling a kernel can provide a number of benefits, both for yourself and for your humble computer. The first boon is that you are able to tweak your kernel so that it is custom-built for your specific hardware configuration. This can potentially increase your computer's performance. Another benefit is that you can patch the kernel with the latest "experimental" drivers, which might not be present in the official source code or in your vendor-provided kernel. Although patching code can seem a little nerve-wracking, it can greatly extend your system's flexibilitythe bar for getting drivers in the official kernel release is quite high, and sometimes patching is the only way you can use a specific feature or driver.
The process described here is a generic approach that should work on any Linux system. However, many Linux distributions provide certain tools for compiling and packaging a kernel specifically to work with that distribution. If you use a distribution such as Debian, which provides kernel packaging tools, you should probably use them if possible for maximum convenience.
Get the Code
First, you need to download the source code for the tree from one of the mirrors at http://www.kernel.org/mirrors/. Once you have downloaded the tree, copy it to /usr/src, and unzip and extract it. If you are downloading a .bz2-compressed tree, extract it with this:
[email protected]:~$ bunzip2 -d linux-x.x.x. tar.bz2
where x.x.x represents the kernel version number you downloaded. Then you can extract the tar file with this:
[email protected]:~$ tar xvf linux-x.x.x. tar
Now you have a new directory called linux-x.x.x. For simplicity in managing your kernel, you should rename this to linux:
[email protected]:~$ mv linux-x.x.x linux
An alternative is to keep the linux-x.x.x directory and instead create a symlink called linux to point to it:
[email protected]:~$ ln -s linux-x.x.x linux
This enables you to keep multiple source trees on your machine and just change the symlink to point to whichever is your current tree. It also helps you remember which version of the source you are working with.
Configure the Code
Before you begin to configure your kernel, first you should ensure that you have all the software necessary to compile it. This list of requirements is shown in the README file in /usr/src/linux. If you are satisfied that everything required is installed, you can launch the configuration tool by running one of the following commands.
- make menuconfig
This is for text-based color menus, radio button lists, and dialogs.
- make xconfig
This X Windows (Qt)-based configuration tool is available only in the 2.6 kernel series and higher.
- make gconfig
This X Windows (Gtk)-based configuration tool is available only in the 2.6 kernel series and higher.
- make oldconfig
This option gives you the opportunity to take a .config file from an older kernel (such as a 2.4 series kernel), compare it to the options available in a new kernel, and then answer some configuration questions about the new options. This is a convenient way to upgrade a kernel, because it allows you to transfer your old settings to the new configuration file.
If you are running a graphical interface (such as KDE or GNOME), I recommend you use either xconfig or gconfig. If you need to configure the code in a console terminal, use menuconfig. I don't suggest you use oldconfig unless absolutely necessary; it can be a long and drawn-out process.
Each configuration program (apart from oldconfig) organizes options into a series of categories. If you start at the first category and go through each section, you can turn an option on, turn it off, or mark it to compile as a loadable module. I recommend you turn on essential features that you will use all the time and configure less essential features as loadable modules. For example, you should compile support for your filesystems into the kernel, but you might want to configure support for your webcam as a module. If you are going to be dealing with USB devices, you should read [Hack #93] .
Compile the Code
Once you have configured the kernel, save your changes and quit. Now you need to enter a series of commands to compile the code. The first command creates of list of dependencies. This list is a preconfiguration step that sets up various kernel configuration files based on your kernel configuration settings. To create the dependency list, run this command:
[email protected]:~$ make dep
The next command cleans out any unwanted junk, such as temporary compilation files that were collected from previous compiles or when you created your dependencies:
[email protected]:~$ make clean
Now you can actually compile the kernel. This process can take quite some time depending on which features you selected and how fast your computer is. Start the build with this:
[email protected]:~$ make bzImage
The next step is to compile the modules you selected in the configuration tool. Compile these with this:
[email protected]:~$ make modules
Finally, you must install the modules into the correct part of your system as root. This ensures that your modules are accessible when you boot the system:
[email protected]:~# make modules_install
Though you can run these steps one by one, most people combine them into a single command, such as this:
[email protected]:~# make dep && make clean bzImage modules modules_install
Joining the commands using && allows your system to proceed with each step automatically if no errors occur in the previous step. This is a very useful trick to remember for other situations in which you want to string a series of commands.
A few distributions might have specific methods you can follow to compile a kernel. For instance, Debian provides a method for compiling a kernel and creating a Debian package out of it. This makes it easy to install on your machine, and it makes a convenient package to transfer to other machines that need the same kernel. Debian Universe (http://www.debianuniverse.com/readonline/chapter/21), a web site created by Jonathan Oxer, has details on this method.
Install the Kernel
The compiled kernel is placed in /usr/src/linux/arch/<platform>/boot and is called bzImage, where <platform> is a placeholder for the type of computer on which you are performing the compile. For example, if you compiled your kernel on an x86 machine, such as a Pentium, Athlon, Celeron, etc., you will find the kernel image in /usr/src/linux/arch/i386/boot. You must copy this image over to /boot. You also should rename it to include the version of the kernel in the filename so that when you have multiple kernels you can easily tell which is which. Also, the Linux kernel image has traditionally been referred to as vmlinuz, and many users continue to call it this. So, if you have a 2.6.5 kernel, you could copy the file with this command as root:
[email protected]:~# cp /usr/src/linux/arch/i386/boot/bzImage /boot/vmlinuz-2.6.5
You should also copy the System.map file (this file has a map of the positions of symbols in the kernel and is used by programs such as depmod) to the /boot directory using a similar naming scheme:
[email protected]:~# cp /usr/src/linux/arch/i386/boot/System.map/boot/System.map-2.6.5
To complete the process, just adjust your bootloader to load the new kernel [Hack #1].