7.4. Building a New Kernel
Rebuilding the kernel sounds like a pastime for hackers, but it is an important skill for any system administrator. First, you should rebuild the kernel on your system to eliminate the device drivers you don't need. This reduces the amount of memory used by the kernel itself, as described in the section "Section 6.2, "Managing Swap Space"," in Chapter 6, "Managing Filesystems, Swap, and Devices", the kernel is always present in memory, and the memory it uses cannot be reclaimed for use by programs if necessary.
You also need to occasionally upgrade your kernel to a newer version. As with any piece of your system, if you know of important bug fixes or new features in a kernel release, you may want to upgrade to pick them up. Those people who are actively developing kernel code will also need to keep their kernel up to date in case changes are made to the code they are working on. Sometimes, it is necessary to upgrade your kernel to use a new version of the compiler or libraries. Some applications (such as the X Window System) require a certain kernel version to run.
Here, we see a machine running Version 2.0.35 of the kernel, which was last compiled on September 30. We see other information as well, such as the hostname of the machine, the number of times this kernel has been compiled (four), and the fact that the machine is a Pentium or equivalent (as denoted by i586). The manual page for uname can tell you more.rutabaga% uname -a Linux tigger 2.0.35 #4 Wed Sep 30 12:44:16 CEST 1998 i586
The Linux kernel is a many-tentacled beast. Many groups of people work on different pieces of it, and some parts of the code are a patchwork of ideas meeting different design goals. Overall, however, the kernel code is clean and uniform, and those interested in exploring its innards should have little trouble doing so. However, because of the great amount of development going on with the kernel, new releases are made very rapidly--sometimes daily! The chief reason for this is that nearly all device drivers are contained within the kernel code, and every time someone updates a driver, a new release is necessary. As the Linux community moves towards loadable device drivers, the maintainers of those drivers can release them independently of the main kernel, alleviating the necessity of such rapid updates.
Currently, Linus Torvalds maintains the "official" kernel release. Although the General Public License allows anyone to modify and rerelease the kernel under the same copyright, Linus's maintenance of an "official" kernel is a helpful convention that keeps version numbers uniform and allows everyone to be on equal footing when talking about kernel revisions. In order for a bug fix or new feature to be included in the kernel, all one must do is send it to Linus, who will usually incorporate the change as long as it doesn't break anything.
major is the major version number, which rarely changes, minor is the minor version number, which indicates the current "strain" of the kernel release, and patchlevel is the number of the patch to the current kernel version. Some examples of kernel versions are 2.0.36, (patch level 36 of kernel Version 2.0), and 2.1.52 (patch level 52 of kernel Version 2.1).major.minor.patchlevel
By convention, even-numbered kernel versions (2.0, 2.2, and so on) are "stable" releases, patches that contain only bug fixes and no new features. Odd-numbered kernel versions (2.1, 2.3, and so on) are "development" releases, patches that contain whatever new code developers wish to add and bug fixes for that code. When a development kernel matures to the point where it is stable enough for wide use, it is renamed with the next highest (even) minor version number, and the development cycle begins again.
For example, kernel Versions 2.0 and 2.1 were worked on concurrently. Patches made to 2.0 were bug fixes--meant only to correct problems in the existing code. Patches to 2.1 included bug fixes as well as a great deal of new code--new device drivers, new features, and so on. When kernel Version 2.1 was stable enough, it was renamed to 2.2; a copy was made and named Version 2.3. Development continued with Versions 2.2 and 2.3. 2.2 would be the new "stable" kernel while 2.3 was a development kernel for new features.
Note that this version-numbering convention applies only to Linus's official kernel release and only to kernel versions after 1.0. Prior to 1.0 (this is now ancient history), there was only one "current" kernel version and patches were consistently made to it. The kernel development community has found that having two concurrent kernel versions allows those who want to experiment to use the development kernel, and those who need a reliable platform to stick with the stable kernel. In this way, if the development kernel is seriously broken by new code, it shouldn't affect those who are running the newest stable kernel. The general rule is that you should use development kernels if you want to be on the leading edge of new features and are willing to risk problems with your system. Use the development kernels at your own risk.
If you are interested in how the kernel versions so far have evolved, check out http://ps.cus.mist.ac.uk/~rhw/kernel.versions.html.
On your system, the kernel sources most probably live in /usr/src/linux (unless you use the Debian distribution, where you can find the kernel sources in /usr/src/kernel-source-versionsnumber). If you are going to rebuild your kernel only from the current sources, you don't need to obtain any files or apply any patches. If you wish to upgrade your kernel to a new version, you need to follow the instructions in the following section.
7.4.1. Obtaining Kernel Sources
The official kernel is released as a gzipped tar file, containing the sources along with a series of patch files--one per patch level. The tar file contains the source for the unpatched revision; for example, there is a tar file containing the sources for kernel Version 1.1 with no patches applied. Each subsequent patch level is released as a patch file (produced using diff), which can be applied using the patch program. In the section "Section 14.2.9, "Patching Files"" in Chapter 14, "Tools for Programmers", we describe the use of patch in detail.
Let's say you're upgrading to kernel Version 1.1 patch level 15. You'll need the sources for 1.1 (the file might be named v1.1.0.tar.gz) and the patches for patch levels 1 through 15. These files would be named patch1, patch2, and so forth. (You need all of the patch files up to the version you're upgrading to. Usually, these patch files are rather small, and are gzipped on the archive sites.) All these files can be found in the kernel directory of the Linux FTP archive sites; for example, on ftp://ftp.kernel.org, the directory containing the 2.2 sources and patches is /pub/linux/kernel/v2.2. You will find the kernel sources here as tar archives, both compressed with gzip and bzip2.
If you are already at some patch level of the kernel (such as 2.1 patch level 15) and want to upgrade to a newer patch level, you can simply apply the patches from the version you have up to the version you'd like to upgrade to. If you're upgrading from, say, 2.1 patch level 15 to 2.1 patch level 19, you need the patch files for 2.1.16 to 2.1.19 inclusive.
22.214.171.124. Unpacking the sources
First, you need to unpack the source tar file from /usr/src. You do this with commands such as:
This saves your old kernel source tree as /usr/src/linux.old and creates /usr/src/linux, containing the new sources. Note that the tar file containing the sources includes the linux subdirectory.rutabaga# cd /usr/src rutabaga# mv linux linux.old rutabaga# tar xzf v1.1.0.tar.gz
You should keep your current kernel sources in the directory /usr/src/linux, because there are two symbolic links--/usr/include/linux and /usr/include/asm--that point into the current kernel source tree to provide certain header files when compiling programs. (You should always have your kernel sources available so that programs using these include files can be compiled.) If you want to keep several kernel source trees around, be sure that /usr/src/linux points to the most recent one.
126.96.36.199. Applying patches
If you are applying any patch files, you use the patch program. Let's say that you have the files patch1.gz through patch15.gz, which are gzipped. These patches should be applied from /usr/src. That doesn't mean the patch files themselves should be located there, but rather that patch should be executed from /usr/src. For each patch file, use the command:
from /usr/src. The -p0 option tells patch it shouldn't strip any part of the filenames contained within the patch file.gunzip -c patchfile | patch -p0
You must apply each patch in numerical order by patch level. This is very important. Note that using a wildcard such as patch* will not work because the * wildcard uses ASCII order, not numeric order. (Otherwise you'd get patch1 followed by patch10 and patch11, as opposed to patch2 and patch3.) It is best to run the previous command for each patch file in succession, by hand. This way you can ensure you're doing things in the right order.
You shouldn't encounter problems when patching your source tree in this way unless you try to apply patches out of order or apply a patch more than once. Check the patch manual page if you do encounter trouble. If all else fails, remove the new kernel source tree and start over from the original tar file.
To double-check that the patches were applied successfully, use the commands:
This lists any files that are "rejected" portions of the patch process. If any such files exist, they contain sections of the patch file that could not be applied for some reason. Look into these, and if there's any doubt start over from scratch. You cannot expect your kernel to compile or work correctly if the patch process did not complete successfully and without rejections.find /usr/src/linux -follow -name "*.rej" -print find /usr/src/linux -follow -name "*#" -print
7.4.2. Building the Kernel
Whether or not you've upgraded your kernel sources, you're ready to build a new kernel. The primary reason to do this is either to simply upgrade or to trim down your current kernel, excluding unneeded device drivers.
There are six steps to building the kernel, and they should be quite painless. All of these steps are described in more detail in the following pages.
All these commands are executed from /usr/src/linux, except for Step 5, which you can do anywhere.
There is a README included in the kernel sources, which should be located at /usr/src/linux/README on your system. Read it. It contains up-to-date notes on kernel compilation, which may be more current than the information presented here. Be sure to follow the steps described there, using the descriptions given later in this section as a guide.
The first step is to run make config. This executes a script that asks you a set of yes/no questions about which drivers to include in the kernel. There are defaults for each question, but be careful: the defaults probably don't correspond to what you want. (When several options are available, the default will be shown as a capital letter, as in [Y/n].) Your answers to each question will become the default the next time you build the kernel from this source tree.
Simply answer each question, either by pressing Enter for the default, or pressing y or n (followed by Enter). Not all of the questions have a yes/no answer; you may be asked to enter a number or some other value. A number of the configuration questions allow an answer of m in addition to y or n. This option allows the corresponding kernel feature to be compiled as a loadable kernel module, as opposed to building it into the kernel image itself. Loadable modules, covered in the following section, "Section 7.5, "Loadable Device Drivers"," allow portions of the kernel (such as device drivers) to be loaded and unloaded as needed on a running system. If you are unsure about an option, type ? at the prompt; for most options, a message will be shown that tells you more about the option.
An alternative to running make config is make xconfig, which compiles and runs an X-Window-based kernel configuration program. In order for this to work, you must have the X Window System running, have the appropriate X11 and Tcl/Tk libraries installed, and so forth. Instead of asking a series of questions, the X-based configuration utility allows you to use checkboxes to select which kernel options you want to enable. The system remembers your configuration options each time you run make config, so if you're only adding or removing a few features from your kernel, you need not reenter all the options.
Also available is make menuconfig, which uses the text-based curses library, providing a similar menu-based kernel configuration if you don't have X installed. make menuconfig and make xconfig are much more comfortable than make config, especially because you can go back to an option and change your mind until you save your configuration.
The following is part of a session with make config. When using make menuconfig or make xconfig, you will encounter the same options, only presented more user-friendly:
* * Code maturity level options * Prompt for development and/or incomplete code/drivers\ (CONFIG_EXPERIMENTAL) [N/y/?] * * Processor type and features * Processor family (386, 486/Cx486, 586/K5/5x86/6x86,Pentium/K6/TSC,\ PPro/6x86MX) [PPro/6x86MX] defined CONFIG_M686 Math emulation (CONFIG_MATH_EMULATION) [N/y/?] MTRR (Memory Type Range Register) support (CONFIG_MTRR) [N/y/?] Symmetric multi-processing support (CONFIG_SMP) [Y/n/?] * * Loadable module support * Enable loadable module support (CONFIG_MODULES) [Y/n/?] Set version information on all symbols for modules\ (CONFIG_MODVERSIONS) [N/y/?] Kernel module loader (CONFIG_KMOD) [N/y/?] * * General setup * Networking support (CONFIG_NET) [Y/n/?] The linux kernel is now hopefully configured for your setup. Check the top-level Makefile for additional configuration, and do a 'make dep ; make clean' if you want to be sure all the files are correctly re-made
If you understand the hardware present on your machine, the questions should be straightforward. The following questions are found in the kernel configuration for version 2.2. If you have applied other patches, additional questions might appear. The same is true for later versions of the kernel. Note that in the following list we don't show all of the kernel configuration options; there are simply too many of them, and most are self-explanatory. We have highlighted only those that may require further explanation. Remember that if you're not sure how to answer a particular question, the default answer is often the best choice. When in doubt, it is also a good idea to type ? and check the help message.
It should be noted here that not all Linux device drivers are actually built into the kernel. Instead, some drivers are available only as loadable modules, distributed separately from the kernel sources. (As mentioned earlier, some drivers can be either built into the kernel or compiled as modules.) One notable kernel driver available only as a module is the "floppy tape" driver for QIC-117 tape drives that connect to the floppy controller.
If you can't find support for your favorite hardware device in the list presented by make config, it's quite possible that the driver is available as a module or a separate kernel patch. Scour the FTP sites and archive CD-ROMs if you can't find what you're looking for. In the section "Section 7.5, "Loadable Device Drivers"" later in this chapter, kernel modules are covered in detail.
After running make config or its equivalent, you'll be asked to edit "the top-level Makefile," which means /usr/src/linux/Makefile. In most cases, it's not necessary to do this. If you wanted to alter some of the compilation options for the kernel, or change the default root device or SVGA mode, you could edit the makefile to accomplish this. Setting the root device and SVGA mode can easily be done by running rdev on a compiled kernel image, as we saw in the section "Section 5.2.1, "Using a Boot Floppy"" in Chapter 5, "Essential System Management".
The next step is to run make dep. This issues a series of commands that walk through the directory tree and gather dependencies for source files, adding information to the various makefiles for them. (If you really want to know what's going on here: make dep adds rules for the makefile so that certain code will be recompiled if, say, a header file included by a source file changes.) This step should take five or ten minutes at most to complete.
If you wish to force a complete recompilation of the kernel, you should issue make clean at this point. This removes all object files produced from a previous build from this source tree. If you have never built the kernel from this tree, you're probably safe skipping this step (although it can't hurt). If you are tweaking minor parts of the kernel, you might want to avoid this step so that only those files that have changed will be recompiled. At any rate, running make clean simply ensures the entire kernel will be recompiled "from scratch," and if you're in any doubt, use this command to be on the safe side.
Now you're ready to compile the kernel. This is done with the command make zImage. It is best to build your kernel on a lightly loaded system, with most of your memory free for the compilation. If other users are accessing the system, or if you're trying to run any large applications yourself (such as the X Window System, or another compilation), the build may slow to a crawl. The key here is memory. A slower processor completes the kernel compilation just as rapidly as a faster one, given enough RAM for the task.
The kernel compilation can take anywhere from a few minutes to many hours, depending on your hardware. There is a great deal of code--well over 10 MB--in the entire kernel, so this should come as no surprise. Slower systems with 4 MB (or less) of RAM can expect to take several hours for a complete rebuild; faster machines with more memory can complete in less than half an hour. Your mileage will most assuredly vary.
If any errors or warnings occur while compiling, you cannot expect the resulting kernel to work correctly; in most cases, the build will halt if an error occurs. Such errors can be the result of incorrectly applying patches, problems with the make config and make dep steps, or actual bugs in the code. In the "stock" kernels, this latter case is rare, but is more common if you're working with development code or new drivers under testing. If you have any doubt, remove the kernel source tree altogether and start over.
When the compilation is complete, you will be left with the file zImage in the directory /usr/src/linux/arch/i386/boot. (Of course, if you're attempting to build Linux on a platform other than the Intel x86, the kernel image will be found in the corresponding subdirectory under arch.) The kernel is so named because it is the executable image of the kernel, and it has been internally compressed using the gzip algorithm. When the kernel boots, it uncompresses itself into memory: don't attempt to use gzip or gunzip on zImage yourself! The kernel requires much less disk space when compressed in this way, allowing kernel images to fit on a floppy.
If you pick too much kernel functionality, it can happen that you get a kernel too big error at the end of the kernel compilation. This happens rarely, because you only need a very limited amount of hardware support for one machine, but it can happen. In this case, you have two options: Compile some kernel functionality as modules (see the next section, "Loadable Device Drivers") or use make bzImage instead of make zImage. This will create a kernel that loads itself into high memory but works only with not-so-old Intel machines. You will then find the kernel image in the same directory but with the name bzImage. Don't worry if it took you a lot of time to compile the kernel before. Most of the time spent during the first compile was creating object files that remain on your system and are still usable. So running make bzImage will pick up most of the compiled objects from the earlier run, and this build should go much faster.
You should now run rdev on the new kernel image to verify that the root filesystem device, console SVGA mode, and other parameters have been set correctly. This is described in the section "Section 5.2.1, "Using a Boot Floppy"" in Chapter 5, "Essential System Management".
With your new kernel in hand, you're ready to configure it for booting. This involves either placing the kernel image on a boot floppy, or configuring LILO to boot the kernel from the hard drive. These topics are discussed in the section "Section 5.2, "Booting the System"" in Chapter 5, "Essential System Management". To use the new kernel, configure it for booting in one of these ways, and reboot the system.
Copyright © 2001 O'Reilly & Associates. All rights reserved.