The preceding discussion has covered the most important options you'll encounter in configuring a kernel to use the networking protocols on your network, and the hardware you use to connect a computer to that network. The process of compiling the kernel, however, is another matter, and one that's not, strictly speaking, a networking task. Nonetheless, this task is important if you need to recompile your kernel to add or delete support for specific network features, so this section provides an overview of some of the decisions and procedures involved.
Drivers: Modules or Built-In
The preceding discussion made many references to enabling or disabling particular kernel features, such as drivers for your particular Ethernet adapter. If you check Figure 1.1, though, you'll find that many options can be set to more than two values. Consider the Packet Socket option in Figure 1.1. This option can be set to any of three values: Y , M , or N . The Y and N values, as you might expect, stand for yes and no, respectively, meaning that the code is compiled directly into the main kernel file or not compiled at all. The M option falls in-between these two extremes. If you select M , the feature will be compiled, but it won't be linked into the main kernel file; instead, the code will be available as a kernel module, which can be loaded and unloaded as required. Options that are suboptions of others, such as Packet Socket: Mmapped IO in Figure 1.1, often lack the M option because they're compiled into the kernel or as modules, depending on their parent options' settings. Thus, selecting Y for such an option may place it in the kernel or in a module.
A feature that's compiled into the kernel is always available, and is available early in the boot process. There's no chance that the feature will become unavailable because it's been unloaded. Some features must be compiled in this way, or not at all. For instance, the filesystem used for the root directory must be available in the kernel at boot time, and so must be compiled directly into the kernel. If you use the Root File System on NFS option, described earlier, you'll need to compile support for your network hardware into the kernel.
The down side to compiling a feature directly into the kernel is that it consumes RAM at all times. It also increases the size of the kernel on disk, which can complicate certain methods of booting Linux. For these reasons, Linux distributions ship most options that can be compiled as modules in this way. This allows the distribution maintainers to keep their default kernels manageable, while still providing support for a wide array of hardware. Because most network hardware can be compiled as modules, most distributions compile drivers for network cards in this way.
As somebody who's maintaining specific Linux computers, though, you might decide to do otherwise . If you compile a network card driver directly into the kernel, you won't need to configure the system to load the module before you attempt to start networking. (In truth, most distributions come preconfigured to handle this task correctly, so it's seldom a problem.) On the other hand, if you maintain a wide variety of Linux systems, you might want to create a single kernel and set of kernel modules that you can install on all the computers, in which case you might want to compile network drivers as modules.
Features such as network stacks can also be compiled as modules or directly into the kernel. (TCP/IP is an exception; it must be compiled directly into the kernel or not at all, although a few of its suboptions can be compiled as modules.) You might decide to compile, say, NFS client support as a module if the computer only occasionally mounts remote NFS exports. Doing this will save a small amount of RAM when NFS isn't being used, at the cost of greater opportunities for problems and a very small delay when mounting an NFS export.
As you might gather, there's no single correct answer to the question of whether to compile a feature or driver directly into the kernel or as a module, except of course when modular compilation isn't available. As a general rule of thumb, I recommend you consider how often the feature will be in use. If it will be used constantly, compile the feature as part of the kernel; if it will be used only part of the time, compile the feature as a module. You might want to favor modular compilation if your kernel becomes large enough that you can't boot it with LOADLIN (a DOS utility for booting Linux), though, because this can be an important way to boot Linux in some emergency situations.
A Typical Kernel Compilation
After you've configured your kernel with make xconfig or some other configuration command, you must issue four commands to compile the kernel and install the kernel modules:
# make dep # make bzImage # make modules # make modules_install
The first of these commands performs some housekeeping tasks . Specifically, dep is short for dependency make dep determines which source code files depend on others, given the options you've chosen . If you omit this step, it's possible that the compilation will go awry because you've added or omitted features, which requires adjusting the dependency information for the features you have.
The second of these commands builds the main kernel file, which will then reside in the /usr/src/linux/arch/i386/boot directory under the name bzImage . There are variants on this command. For instance, for particularly small kernels, make zImage works as well (the bzImage form allows a boot loader like LILO to handle larger kernels than does the zImage form). Both zImage and bzImage are compressed forms of the kernel. This is the standard for x 86 systems, but on some non- x 86 platforms, you should use make vmlinux instead. This command creates an uncompressed kernel. (On non- x 86 platforms, the directory in which the kernel is built will use a name other than i386 , such as ppc for PowerPC systems.)
The make modules command, as you might guess, compiles the kernel modules. The make modules_install command copies these module files to appropriate locations in /lib/modules . Specifically, a subdirectory named after the kernel version number is created, and holds subdirectories for specific classes of drivers.
The entire kernel compilation process takes anywhere from a few minutes to several hours, depending on the options you select and the speed of your computer. Typically, building the main kernel file takes more time than does building modules, but this might not be the case if you're building an unusually large number of modules. At each step, you'll see many lines reflecting the compilation of individual source code files. Some of these compilations may show warning messages, which you can usually safely ignore. Error messages, on the other hand, are more serious, and will halt the compilation process.
Common Kernel Compilation Problems
Kernel compilation usually proceeds smoothly if you configured the kernel correctly, but occasionally errors pop up. Common problems include the following:
If you can't resolve a kernel compilation problem yourself, try posting a query to a Linux newsgroup, such as comp.os.linux.misc . Be sure to include information on your distribution, the kernel version you're trying to compile, and any error messages you see. (You can omit all the nonerror compilation messages.)
Installing and Using a New Kernel
Once you've built a new kernel, you'll need to install and use it. As noted earlier, the fresh-built kernel normally resides in /usr/src/linux/arch/ i386/boot (or a similar directory with a name matched to your CPU type rather than i386 ). You normally copy or move the kernel file (such as bzImage ) to the /boot directory. I recommend renaming the file to something that indicates its version and any customizations you may have made. For instance, you might call the file bzImage-2.4.17 or bzImage-2.4.17-xfs . You should also type make modules_install , if you haven't already, to install your kernel modules in /lib/modules/ x.y.z , where x.y.z is the kernel version number.
Unfortunately, copying the kernel to /boot isn't enough to let you use the kernel. You must also modify your boot loader to boot the new kernel. Most Linux distributions use the Linux Loader (LILO) as a boot loader, and you configure LILO by editing /etc/lilo.conf . Listing 1.1 shows a short lilo.conf file that's configured to boot a single kernel.
Listing 1.1 A sample lilo.conf file
boot=/dev/sda map=/boot/map install=/boot/boot.b prompt default=linux timeout=50 image=/boot/vmlinuz label=linux root=/dev/sda6 read-only
To modify LILO to allow you to choose from the old kernel and the new one, follow these steps:
The next time you boot the computer, LILO should present you with the option of booting your old kernel or the new one, in addition to any other options it may have given you in the past. Depending upon how it's configured, you may see the new name you entered in Step 4 in a menu, or you may be able to type it at a lilo: prompt.
If you can boot the computer and are satisfied with the functioning of your new kernel, you can make it the default by modifying the default= line in /etc/lilo.conf . Change the text after the equal sign to specify the label you gave the new kernel in Step 4, then type lilo again at a command prompt.
There are ways to boot a Linux kernel other than LILO. Some distributions use the Grand Unified Boot Loader (GRUB) instead of LILO. Consult the GRUB documentation for details on how to configure it. You can also use the DOS program LOADLIN to boot Linux. To do this, you need to place a copy of the kernel on a DOS-accessible diska DOS partition or a floppy disk. You can then boot Linux by typing a command like the following:
C:> LOADLIN BZIMAGE root=/dev/sda6 ro
In this example, BZIMAGE is the name of the kernel file, as accessed from DOS, and /dev/sda6 is the Linux identifier for the root partition. The ro option specifies that the kernel should initially mount this partition read-only, which is standard practice. (Linux later remounts it for read-write access.) LOADLIN can be a useful tool for testing new kernels, if you prefer not to adjust your LILO setup initially. It's also a good way to boot Linux in an emergency, should LILO become corrupt. If you don't have a copy of DOS, FreeDOS (http://www.freedos.org) is an open source version that should do the job. LOADLIN ships on most Linux distributions' installation CD-ROMs, usually in a directory called dosutils or something similar.