You need to configure the options that you want to have in your kernel before you build it. Your goal is to have an appropriate .config file in your kernel source distribution. Here's an excerpt of a typical .config file:
# CONFIG_HIGHMEM64G is not set # CONFIG_MATH_EMULATION is not set CONFIG_MTRR=y CONFIG_HAVE_DEC_LOCK=y
This file isn't easy to write with a text editor, so there are several configuration utilities that generate the file for you. An easy, standard way to set up a kernel is to run this command:
After some initial setup, make menuconfig runs a text-based menu interface that is shown in Figure 10-1. The box in the center of the screen contains the options at the current configuration level. You can navigate the menu with the up- and down-arrow keys. An arrow next to an item (--->) indicates a submenu.
The bottom of the menu contains three actions that you can navigate to with the left- and right-arrow keys. Pressing ENTER while one of the menu items is highlighted performs whichever of the three following actions is also highlighted:
Select If the current menu item leads to a submenu, the configuration system activates the submenu.
Exit Exits the current submenu. If you are at the top-level menu, the configuration system asks whether you would like to save the current configuration. You can activate the Exit option by pressing ESC.
Help Shows any online help for the current item. You can also get at the help by pressing the ? key.
To get a general feel for how configuration options work, go into the Processor type and features submenu. You will see options such as these:
[ ] Math emulation [*] MTRR (Memory Type Range Register) support < > /dev/cpu/microcode - Intel IA32 CPU microcode support
You can alter an item's configuration value by moving to the item and pressing the SPACEBAR. The square brackets ([ ]) provide a simple on/off toggle:
[*] indicates that the feature is on.
[ ] indicates that the feature is off.
You may not configure on/off features as kernel modules. Active features go directly into the main kernel image.
By contrast, an item with angle brackets (< >) denotes a feature that you may compile as a module. You can use the SPACEBAR to toggle between these values:
<*> indicates that the feature is on.
<M> indicates that the feature is configured as a module.
< > indicates that the feature is off.
An item that includes regular parentheses like these, (), is a multiple-choice option or a number that you can customize. Press ENTER to see the option list, or enter a number.
When you are through with configuration and decide to exit, the menu system will ask if you would like to save the current configuration. If you choose Yes, the system backs up your previous .config file as .config.old and writes a new .config file.
Most of the configuration options are fairly self-explanatory. For example, in the menu shown in Figure 10-1 on page 205, the items under Device Drivers > SCSI device support > SCSI low-level drivers correspond to device drivers for SCSI host controllers.
Some configuration options depend on other options, and until you activate the dependency options you cannot reach configuration options that have dependencies. For example, to reach the SCSI low-level drivers submenu, you must first activate SCSI device support in the previous menu. These dependencies are not always obvious; you may need to do a little bit of experimentation to find what you're looking for. If you're really stumped on a dependency, go to the source. Look at arch/i386/Kconfig, the master file for all options and online help for the kernel configuration.
The following sections outline the most significant kernel options that reside within the important top-level menus. Keep in mind that these options change with time; you may see items not listed here, or the items may be in a different place in the kernel that you decide to build.
Inside this menu item you will find an option named Prompt for development and/or incomplete code/drivers. To see the newest (but perhaps unstable) drivers and features when perusing the rest of the kernel configuration menus, select this option.
This section has three settings that you should turn on:
Support for paging of anonymous memory Enables swap disk and file support
System V IPC Enables interprocess communication
Sysctl support Enables kernel parameter changes through /proc
If you do not build your kernel with the support listed here, many major packages and utilities will not work, including the X Window System.
In addition to these options, the General Setup menu in kernel 2.6.0 and newer versions have an option named Kernel .config support to make the build process save the current .config file in the kernel image. If you enable this option, you will also have the opportunity to enable a second option that allows you to turn on access to the embedded .config file via /proc/config.gz. These options increase your kernel size slightly, but they can come in extremely handy later on when you need to upgrade your kernel but can't remember what configuration options you selected.
You have some control over the kernel's module loader. In general, you should always activate the kernel module system with the Enable loadable module support option, as well as activating the kernel module loader option, Automatic kernel module loading, sometimes called the autoloader.
The only item in the kernel module support menu that you should be wary of is versioning support (at the moment, this is experimental). Kernels compiled with this option enabled may try to load modules built for a different kernel version, and this can cause trouble if you don't know exactly what you're doing.
The Linux kernel includes a number of optimizations and other enhancements that are specific to certain processors. You can choose your processor with the Processor family option. Be careful — a kernel built for a "primitive" CPU supports advanced processors, but a kernel tailored to an advanced CPU will likely not work on an older (or different brand of) CPU.
Other significant options in the processor category include:
High memory support This is for machines with more than 2GB of physical memory.
Symmetric multi-processing support This is for machines with more than one processor.
MTRR support This permits optimizations that may improve certain kinds of graphics performance.
There are two types of power management in PC hardware: the older APM (Advanced Power Management) and the newer ACPI (Advanced Configuration and Power Interface). You can configure a kernel with both varieties. Appropriate power management support is essential on notebooks to preserve battery life, and it is a good idea for desktops so that your machine doesn't generate too much heat and use too much electricity.
Power management features enable interesting tricks with fans, processor speeds, and more. There's a lot to explore, but you may need additional software such as apmd or acpid to take advantage of the kernel features.
You shouldn't need to change the bus options for most systems. Unless you have an extremely old or odd system, include PCI support (and if you'd like to list and diagnose devices on the PCI bus, install lspci, which is a part of the pci-utils package).
You should enable the Support for hot-pluggable devices option so that your system can take appropriate action when you attach and detach removable devices.
Newer kernels include base PCMCIA (PC Card/CardBus) drivers as configuration options in this menu — in previous systems, PCMCIA support was completely separate from the main kernel distribution. You still need the PCMCIA utilities if you intend to use PC cards, and at the moment, you can still leave out PCMCIA kernel support here and get it from these utilities, but this may change in the future.
To start a process from an executable file on the disk, the kernel needs to know how to load the executable file, how to initialize the process in memory, and where to start running the process. An executable's file format determines these characteristics. Most binaries on a modern Linux system are ELF (Executable and Linkable Format) files. You probably do not need to support the ancient "a.out" executable format (you may not even have the shared libraries to support these binaries), but it does not take too much memory to include support, and you can build it as a module.
Configuring device drivers is a long process due to the wide variety of devices that Linux supports. Unfortunately, it's during this stage that you can get bogged down with all of the options and end up building a kernel that is far too large because you included drivers for devices that you will never have. If you're in doubt about whether you are going to use any particular driver (other than a disk driver), build it as a module so that it does not unnecessarily take up kernel memory.
The following sections describe the driver configuration options inside the Device drivers menu.
You must enable Plug and Play support if you want any reasonably modern built-in hardware in your computer to work. You may also need plug-and-play support in order to use network cards, internal modems, and sound cards.
The Block devices section of the kernel configuration contains miscellaneous random-access storage devices, such as floppy disks and RAM disks. These devices normally hold filesystems that you directly attach to your current system with the mount command. The interesting drivers here include the following:
Normal floppy disk support A driver for the PC floppy disk drive.
Loopback device support A simple driver that maps a file into a block device. This driver is very useful because it allows you to mount a filesystem on a disk image.
Network block device support A driver that allows you to use a network server as a block device.
RAM disk support A driver that designates a chunk of physical memory as disk space.
Initial RAM disk (initrd) support A driver that provides a special kind of RAM disk that a boot loader gives to the kernel as the initial / partition during the very first stages of init. Many distributions use an initial RAM disk for SCSI drivers and other modules that may not be in their stock kernels.
Parallel port IDE device support A driver for certain older portable disk devices.
You should always compile ATA (IDE) support directly into your kernel unless you know exactly what you're doing. There are several kinds of IDE drivers that you can enable here:
Disk support A driver required if you want hard drives to work. Needless to say, you should compile this driver directly into the kernel.
CD-ROM support A driver for ATAPI CD-ROM and DVD-ROM drives.
Floppy support A driver for various removable-media drives with an ATAPI interface.
SCSI emulation A driver for ATAPI CD-R and CD-RW drives. Older Linux CD-burning software worked exclusively with SCSI drivers; if your CD-burning software is up to date, you do not need this driver.
Various chipsets Drivers for various specific chipsets. If your motherboard's IDE chipset is listed, you might be able to squeak out a little more performance with one of these drivers.
Even if you have no SCSI devices, you may still need SCSI support because many Linux device drivers work through emulated SCSI devices. For example, if you want to use USB mass storage, you need SCSI disk support.
These are the media drivers:
SCSI disk support Covers all fixed and removable-media disk-like storage devices, except CD-ROM drives.
SCSI tape support
SCSI CD-ROM support
SCSI generic support Allows applications talk to a SCSI device at a low level. You need SCSI generic support for a wide range of devices, including CD burners, changer devices on tape drives, SCSI scanners, and more.
A look inside the SCSI low-level drivers submenu reveals drivers for many kinds of SCSI host controllers. Some of the drivers are named after the SCSI chipset on the host controller, so you may have to look carefully at your hardware to find a match. The low-level driver list also includes support for some parallel port devices, such as Zip drives.
If your kernel and root partition are on a SCSI disk, compile SCSI support (including the disk and host controller drivers) directly into the kernel rather than as modules. This makes booting much easier, because you do not need to worry about loading SCSI modules from a disk that the kernel does not yet know how to access.
You need networking support for almost any system, even if you do not have an external network connection. Many applications use local network interface features.
Your first order of business is to pick the networking devices that you need. For most Ethernet devices, look under Ethernet (10 or 100Mbit). There are many devices to choose from. If you're not too sure what you need, don't be afraid to configure several drivers as modules. In addition, if you plan to dial up to the Internet or use certain DSL connections, you need PPP support, along with asynchronous (serial port) or PPP over Ethernet (PPPoE) support. If you're not sure about PPP options, configure them as modules.
The configuration options inside the Networking options submenu represent the trickiest part of the kernel network configuration. You need to select all of the options and protocols that you intend to use. The essential options for many packages include the following:
Unix domain sockets
Packet socket (for features such as promiscuous mode)
Not so obvious is Network packet filtering, which is required for any kind of firewall or NAT (Network Address Translation, or "IP masquerading") support. Just selecting this option is not enough because, in general, your kernel needs all of the connection tracking, NAT, and masquerade options if you want to use NAT. Therefore, you must enter the Netfilter Configuration submenu and choose more options there, such as these:
Connection tracking for NAT (be sure to include any protocols you need to track).
IP tables support for firewalling and NAT. Once you enable IP tables, you get several more options, including various match options for filtering. You don't have to worry about most of these, except for Connection state and Connection tracking, both of which you need for NAT. That's not the end of the things you need for NAT — look out for and enable Full NAT and MASQUERADE target support.
Packet filtering and REJECT target support for firewalls.
You need several configuration options to support your keyboard and mouse. There are two levels of support. The basic drivers support the PS/2 keyboard. Also, look for PS/2 Mouse.
Among the most important character devices are Virtual terminals (/dev/tty0, /dev/tty1, and so on). Unless you have a special type of server, you also need to put the console on the virtual terminal.
Here are some other things to check up on:
Serial drivers Standard PC serial ports use or emulate 8250/16550 UART chips. You almost certainly need this support if you plan to use a modem.
Unix98 PTY support Some programs now expect to see the dynamic Unix98 /dev/pts/* pseudo-terminal devices rather than old static names like /dev/ttyp*.
Enhanced real time clock support This makes /dev/rtc available to programs like hwclock. You should enable this option for any modern machine.
/dev/agpart This is for direct-rendered graphics (GLX and DRI) on AGP graphics cards.
Parallel printer support This gives you /dev/lp* devices. To get this option, you must go back to the main kernel menu and enable Parallel port support. You also need PC-style hardware for any standard PC.
There is a section for Mice in the character device configuration, but you can probably safely ignore it, because the drivers there are for very old bus mice.
There are two parts to sound configuration: API support and drivers. The current sound system is called Advanced Linux Sound Architecture (ALSA), but you should also include the emulation support for the old OSS (Open Sound System), because many programs still use the OSS interface.
The driver configuration for sound devices is very similar to that for network devices — many of the sound drivers carry the names of the sound chipset.
When configuring USB, choose an interface driver first:
UHCI and OHCI are USB 1.1 interfaces. Even if you have a USB 2.0 motherboard, you need one of these. If you don't know which one your motherboard supports, pick both (modules are okay); the kernel will sort it out.
EHCI is a USB 2.0 interface.
You also want to enable the USB device filesystem option that can maintain USB device information in /proc/bus/usb.
Configuring the kernel to support USB devices is fairly straightforward, but there are two gotchas:
The Mass storage support option requires that you also enable SCSI and SCSI disk support.
The Interface device support (HID) option requires that you enable the input drivers described earlier. To get USB mouse and keyboard support, you need to enable HID input layer support in the USB support menu. Don't use the boot protocol drivers unless you know exactly what you're doing.
You can add support for many different filesystems to your Linux kernel configuration. However, make sure that you compile your primary filesystem directly into the kernel. For example, if your root partition uses ext2, don't modularize ext2 support. Otherwise, your system will not be able to mount the root filesystem and therefore will not boot.
These are the most important filesystems:
Second extended (ext2) The Linux standard for many years.
Third extended (ext3) A journaled version of ext2; now the standard for many distributions.
Reiserfs A high-performance journaled filesystem.
DOS/FAT/NT MS-DOS- and Windows-compatible filesystems. To get MS-DOS filesystem support, you need to enable FAT. VFAT is the extended filesystem introduced with Windows 95. You need VFAT if you plan to read images from the flash memory cards in digital cameras and similar devices.
ISO9660 A standard CD-ROM filesystem. The Linux driver includes the Rock Ridge extensions. You can also add the Microsoft Joliet extensions.
UDF A newer CD-ROM and DVD filesystem.
Minix A filesystem that was the Linux standard a long time ago (it even predates Linux). It never hurts to include Minix filesystem support as a module.
Pseudo filesystems These are system interfaces, not storage mechanisms. The /proc filesystem is one of the best-known pseudo-filesystems, and one that you should always configure. You should also include the /dev/pts filesystem and the virtual memory filesystem.
Network filesystems These are used for sharing files with machines over the network.
There are also a couple important filesystem-related options:
Kernel automounter support Enables automatic filesystem mounting and unmounting. This is a popular solution for managing network filesystem access.
Partition types Allows Linux to read partitioning schemes other than the regular PC partition tables, including BSD disklabels and Solaris x86 partitions.
This wraps up the important kernel configuration options. You shouldn't really have to worry about the other options (such as the Profiling support used for kernel development); let's turn our focus to compiling the kernel.
After you save your kernel configuration, you're ready to build the kernel. To get a list of make targets, you can run this command:
Your main goals are to compile the bzImage compressed kernel image and the kernel modules. Because these two are the default targets, you only need to run the following to build everything:
The compile takes some time. As it runs along, you see messages like this:
If you see a message containing [M], it means that make is compiling a module:
CC [M] net/sctp/protocol.o
The following output appears when make builds bzImage:
Kernel: arch/i386/boot/bzImage is ready
As the preceding message indicates, the build process creates your kernel image as arch/i386/boot/bzImage. The process also creates a file named System.map that contains kernel symbols and locations. You may have to wait a little while after the "Kernel ready" message appears, because make may still need to compile some kernel modules. Don't interrupt the build; make sure that you wait until you get your prompt back before installing the kernel.
In kernel versions prior to 2.6, you had to run the following commands for a complete kernel build:
make dep make bzImage
Recent kernels are very self-contained; there are only two primary things that can go wrong during the build process:
If you get a parse error or some other sort of coherent compiler error, the compiler on your machine probably doesn't match the recommended compiler in the README file. Kernel code is very particular about the compiler, especially due to all of the assembly code involved.
If the compiler dies unexpectedly midway through the build process, your hardware may be at fault. Compiling a kernel stresses a machine much more than almost any other task. Bad memory and overclocked or overheated processors are the main culprits.
If you need to see each command in the build process to track down a problem, use this command:
Before you install and boot from your new kernel, you should put the new kernel modules in /lib/modules with this command:
Your new modules should appear in /lib/modules/version, where version is your kernel version. If you fail to install the modules before booting your kernel, the kernel module utilities will not automatically recognize the new modules, and you may end up missing a few drivers.
The module installation builds a module dependency list in /lib/modules/version/modules.dep. If this stage fails, it's likely that your module utilities are out of date. As of this writing, the module utilities are in a package named module-init-tools.
Sometimes you need to send extra parameters to the kernel at boot time in order to get devices or services working. For example, one of the most elementary kernel parameters is root=partition, which sets the initial root partition to partition.
You can enter a kernel parameter after the kernel image name. For example, at a LILO prompt where your kernel label is Linux, you can type this:
Documentation/kernel-parameters.txt contains a list of all kernel parameters. Most of them are for hardware. In addition to root=partition, here are the most important parameters:
init=path This starts path as the first process on the system in place of /sbin/init. For example, you can use init=/bin/sh to get out of a tight spot if your init does not work properly.
mem=size This specifies that the machine has size memory; the kernel should not autodetect the memory size. For example, to specify 512MB of memory, you would use mem=512M.
rootfstype=type This specifies that the root filesystem's type is type.
A number as a boot parameter indicates the init runlevel. You can use -s or S for single-user mode.