Special tools take the pain out of compiling and installing custom kernels.
Debian boasts some very useful tools to make the job of building and installing kernels much easier, and of course those same tools are available in Ubuntu as well. They streamline the process of compiling a custom kernel and building a .deb package around it, allowing you to install a new kernel the same way you would any other package. This makes it possible to build a kernel on one machine and then just install the package on other machines, without having to recompile or track down all the loose endsgreat if you need to upgrade a number of similar machines!
To build a custom kernel "the Ubuntu way," you will need to get hold of the kernel source and a variety of tools to configure, compile, and package it.
Get the Source
You can get the official kernel source yourself directly from http://ftp.kernel.org/pub/linux/kernel/, or a mirror if you like, but of course there are also packages of the kernel source. A quick:
$ apt-cache search linux-source
will get you a list of Linux kernel source packages all ready to go. Picking one as an example, you could just run:
$ sudo apt-get install linux-source-2.6.15
to download the source to your system. You'll then end up with an archive sitting in /usr/src, which is where most kernel work is done. Now you can extract the source package:
$ cd /usr/src
$ sudo tar -xjf linux-source-2.6.15.tar.bz2
That will leave you with a /usr/src/linux-source-2.6.15 directory, decompressed and ready to configure. First, though, create a symlink to it called linux, like this:
$ sudo ln -sf linux-source-2.6.15 linux
The f option forces creation of the new symlink even if there's already an existing link to an old kernel source. Now you can easily get to your kernel source tree just by typing:
$ cd /usr/src/linux
Tools You Will Need
To install the main tools, you will need to run:
$ sudo apt-get install kernel-package libncurses5-dev
This will also cause your computer to pull down a big list of supporting packages that are dependencies.
Configuration Methods
There are a number of ways to configure a kernel prior to compiling it, and all but the first are invoked as arguments to the make command. Make sure you have a shell open in the kernel source directory (which should be /usr/src/linux if you followed our directions earlier) before you try any of these. In increasing order of sophistication, they are:
editing .config
The actual configuration is saved in the source directory as a text file called .config. If you really want to (or if you are trying to find an option some README has listed by name, such as CONFIG_PACKET) you can edit this file directly using a text editor such as vim or Anjuta. This should need to be done very rarely, though.
make config
The most basic approach, this will just ask you a whole heap of questions, one after another. Personally, we hate configuring the kernel this way, because it's sequential and you have to go through a heap of stuff you probably couldn't care less about. Only bother with this as a last resort, such as if other options aren't available to you for some reason.
make menuconfig
This is the most common way to do the configuration. It displays a nice, keyboard-driven menu that you can navigate using arrows, Enter, and the spacebar. However, one catch that can trip you up is that you need to have the development libraries for Ncurses installed, not just Ncurses itself. That's why we had you install the libncurses5-dev package a few paragraphs ago!
make xconfig
The preferred method for machines with X, this option is very similar to menuconfig, except it's all done in a nice point-and-click GUI with mouse navigation. The possible gotcha to getting this working is you'll need tk8.3. If you get errors saying it can't find "wish," run:
$ sudo apt-get install tk8.3
and all should be well.
Configuring the Kernel
Whichever configuration method you choose, the next thing to do is to examine the settings for the different kernel options and make changes as required.
There are a huge number of kernel options, so to help you find things, they are grouped in a logical way in different major and minor sections. The different configuration methods have their own ways to represent this, but they should all be fairly straightforward to follow.
We won't go into details of how to do the kernel configuration here, because what you'll need to configure will vary dramatically, and there are plenty of tutorials on the Net, including the Kernel-HowTo, that explain this in detail. Basically, though, you need to work through each menu in turn to find options and modules you want to enable, and set them to either off (not available), on (compiled straight into the kernel), or module (compiled separately so it can be loaded when needed).
Once you've finished going through the options, quit and save to have your choices written out to a configuration file to be used by the compiler.
One little trick to note is that the actual configuration details are stored in a file called .config in the kernel source directory. Once you've gone to all the trouble of setting up a kernel the way you want it, moving to a new kernel can be painful if you have to go through the configuration process from scratch, and you'd be almost certain to miss something crucialwe know we usually do! To make things easier for yourself, you can copy the .config file into the new kernel source directory to have all your options carried over automatically. Then you can run the configuration again just to check things over, save, and go on as before. Provided you're not changing to a totally new kernel type, this trick can save you a lot of time. Beware if you're moving to a totally different kernel, though, such as from 2.4.x to 2.6.x, because many of the options will be totally different and while the old config will still work, it may not have some options activated that appear only in the new kernel. You can also run make oldconfig after copying in the old .config file, which will then prompt you only for options that are new or have changed since you configured your previous kernel.
Compiling and Packaging
This is the point when your kernel is actually compiled and placed in a package. Normally, that would be a lot of work, but thanks to the tools provided by kernel-package, it's now one of the easiest steps.
If you have read a traditional Kernel HOWTO, you've probably seen a sequence of commands such as make dep && make clean && make bzImage used to build the dependencies and then the kernel itself. You don't need to do any of that; instead, just type:
$ sudo make-kpkg kernel-image
while in the /usr/src/linux directory, and those steps will all be taken care of. The kernel-packaging tools first compile your kernel and modules according to the configuration you just generated and then build a Debian package called kernel-image-.deb outside the current source directoryi.e., in /usr/src.
This stage can take a while depending on your machine speed and which modules you selected. Expect anything from 10 minutes to a half hour, during which time you'll see a very long stream of debugging information that probably won't be of any interest to you at all, unless something goes seriously wrong.
Install Your Kernel Package
You're almost there! What you have now is a kernel, custom-compiled according to your requirements and set up as a Debian package ready to install.
Installing your new kernel is now just a matter of using dpkg to install the package as you would any other Debian package:
$ sudo dpkg -i
kernel-image-2.6.15_10.00.Custom_i386.deb
(replacing kernel-image-2.6.15_10.00.Custom_i386.deb with whatever your package is called). It may ask you if you want to create a boot floppy using that image; the dozens of machines we manage don't have a single floppy drive among them, so we always say no, but if you want to, you can say yes to have it create one for you.
dpkg will also take care of updating your bootloader configuration so your new kernel will be available next time you boot. Both GRUB and LILO are managed automatically, but if you use a different bootloader, you may need to update it yourself at this point.
What happens when you install the package is that dpkg puts your new kernel image in the /boot directory where kernels are normally stored, creates a symlink from /vmlinuz to your new kernel (you can verify this by typing ls -l /vmlinuz), modifies your /boot/grub/menu.lst or /etc/lilo.conf as appropriate so your bootloader can find your new kernel, and moves and renames the previous kernel so it's available as an emergency fallback in case your new kernel borks.
Note that at this point, you will not actually be running the new kernel; it's just set up, ready to go for next time you reboot. Installing a new kernel is one of the very few things that actually requires you to reboot a Linux system.
Rebooting and Testing
Time for the big test! If you are running X, exit the session and reboot. If not, just type sudo reboot. When GRUB loads, you will have the option of pressing Esc to see a list of available kernels, including your new one. Select it and hit Enter.
Once your machine has booted, you can use uname to check which kernel you are running:
$ uname -a
For more information about which modules were loaded and whether the new kernel correctly detected your hardware, you can look through the dmesg log:
$ dmesg | less
If everything worked as expected, congratulations! You've just compiled and installed a custom kernel "the [Debian|Ubuntu] way."
Installing on Other Machines
This is where the convenience of building kernels as packages becomes most obvious. If you want to install your custom kernel on other machines, the process is very simple: just copy the .deb package you created to the target machine and install it using dpkg exactly as before. Simple!
There's no need to compile the kernel on each machine, copy the source code to them, or even have a compiler installed on them. All the hard work was done once on one machine and doesn't need to be repeated.
If you run a server farm or computer lab and have a lot of local machines to install your kernel on, the best way to do so is probably to put the kernel package on a local package repository and have all your computers fetch it over the network.
Install Multiple Copies of One Kernel Version
Often you'll want to install multiple copies of the same kernel version while doing testing, but that can cause problems: modules are installed in a directory based on the kernel version number, so if you want to try out different configuration options, you'll run into problems. Luckily, the kernel package tools allow you to work around that limitation by appending an arbitrary version string to the regular version string. This means you can install multiple builds of the same kernel version and keep everything neatly organized on disk, as well as select which one you want to use at startup.
To modify the version string, just pass the --append-to-version option when creating the package, like so:
$ fakeroot make-kpkg --append_to_version=-jon17
kernel-package
This would generate a kernel package something like kernel-image-2.6.15-jon17_10.00.Custom_i386.deb.
...Read More