5.2 Configuring the Kernel

Configuration is the initial step in the build of a kernel for your target. There are many ways to configure the kernel, and there are many options from which to choose .

Regardless of the configuration method you use or the actual configuration options you choose, the kernel will generate a .config file at the end of the configuration and will generate a number of symbolic links and file headers that will be used by the rest of the build.

We will limit our discussion to the aspects of kernel configuration that differ in embedded systems. You can consult the various references I mentioned earlier if you are not familiar with kernel configuration.

5.2.1 Configuration Options

It is during configuration that you will be able to select the options you want to see included in the kernel. Depending on your target, the option menus available will change, as will their content. Some options, however, will be available no matter which embedded architecture you choose. The following is the list of main menu options available to all embedded Linux architectures:

  • Code maturity level options

  • Loadable module support

  • General setup

  • Memory technology devices

  • Block devices

  • Networking options

  • ATA/IDE/MFM/RLL support

  • SCSI support

  • Network device support

  • Input core support

  • Character devices

  • Filesystems

  • Console drivers

  • Sound

  • Kernel hacking

I will not give the details of each option, since the kernel configuration menu provides help capabilities you can refer to as you perform the configuration. Notice, however, that we discussed many of these options in Chapter 3.

One of the most important option menus is the one in which you choose the exact instance of the processor architecture that best fits your target. The name of this menu, however, varies according to your architecture. Table 5-2 provides the system and processor selection option menu name, along with the correct kernel architecture name for each. When issuing make commands, we need to set the ARCH variable to the architecture name recognized by the kernel Makefiles.

Table 5-2. System and processor selection option and kernel architecture name according to processor architecture

Processor architecture

System and processor selection option

Kernel architecture name

x86

Processor type and features

i386

ARM

System type

arm

PPC

Platform support

ppc

MIPS

Machine selection/CPU selection

mips or mips64[2]

SH

Processor type and features

sh

M68k

Platform-dependent support

m68k

[2] Depending on the CPU.

Some options are available only for certain architectures. Table 5-3 lists these options and indicates their availability for each architecture, as displayed by the kernel's configuration menus.

Table 5-3. Hardware support options for each architecture

Option

x86

ARM

PPC

MIPS

SH

M68k

Parallel port support

X

X

 

X

   

IEEE 1394 support

X

X

X

 

X

 

IrDA support

X

X

X

X

   

USB support

X

X

X

X

   

Bluetooth support

X

X

X

     

Some architectures have their own specific configuration option menus. The following is a list of such menus for the ARM architecture:

  • Acorn-specific block devices

  • Synchronous serial interfaces

  • Multimedia capabilities port drivers

Here is the list of menus specific to the PPC:

  • MPC8xx CPM options

  • MPC8260 communication options

The fact that an option is available in your architecture's configuration menu does not automatically mean that this feature is supported for your target. Indeed, the configuration menus may allow you to enable many kernel features that have never been tested for your target. There is no VGA console, for instance, on ARM systems. The configuration menu of the kernel, however, will allow you to enable support for the VGA console. In this case, the actual kernel build will fail if you enable support for this option. In other cases, the selected feature, or even the entire kernel, will not be functional. To avoid these types of problems, make sure the options you choose are supported for your target. Most of the time, as in the case of the VGA console, it is a matter of common sense. When the choice doesn't seem as evident, visiting the appropriate project web site, such as the ones provided in Chapter 3, will help you determine whether the feature is supported for your target.

In some cases, the fact that an option is not displayed in your architecture's configuration menu doesn't mean that this feature can't actually be used on your target. Many of the features listed in Table 5-3, such as Bluetooth, are mostly architecture independent, and should run on any architecture without a problem. They aren't listed in the configuration menus of certain architectures, because they've either not been tested on those architectures, or the maintainers of those ports or the maintainers of the feature haven't been asked to add the feature in the architecture's main config.in file.[3] Again, the resources listed in Chapter 3 are a good start for finding out about which unlisted features are possibly supported on your target.

[3] config.in files control the options displayed in the configuration menus.

5.2.2 Configuration Methods

The kernel supports four main configuration methods:

make config

Provides a command-line interface where you are asked about each option one by one. If a .config configuration file is already present, it uses that file to set the default values of the options it asks you to set.

make oldconfig

Feeds config with a an existing .config configuration file, and prompts you to configure only those options you had not previously configured. This contrasts with make config, which asks you about all options, even those you may have previously configured.

make menuconfig

Displays a curses-based terminal configuration menu. If a .config file is present, it uses it to set default values, as with make config.

make xconfig

Displays a Tk-based X Window configuration menu. If a .config file is present, it uses it to set default values, as with make config and make menuconfig.

Any of these can be used to configure the kernel. They all generate a .config file in the root directory of the kernel sources. (This is the file that contains the full detail of the options you choose.)

Few developers actually use the make config command to configure the kernel. Instead, most use make menuconfig. You can also use make xconfig. Keep in mind, however, that make xconfig may have some broken menus in some architectures; as is the case for the PowerPC, for instance.

To view the kernel configuration menu, type the appropriate command at the command line with the proper parameters. For our ARM-based user interface modules, we use the following command line:

$ make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig

We then proceed to choose the configuration options appropriate to our target. Many features and drivers are available as modules and we can choose here whether to have them built in the kernel or whether to build them as modules. Once we are done configuring the kernel, we use the Escape key or select the Exit item to quit the configuration menu. We are then prompted by the configuration utility to confirm that we want to save the configuration. By choosing Yes, we save the kernel's configuration and create a .config file. In addition to creating the .config file, a few header files and symbolic links are created. If we choose No, the configuration is not saved and any existing configuration is left unmodified.

Apart from the main configuration options, some architectures, such as the PPC and the ARM, can be configured using custom tailored configurations for the various boards implemented using the architecture. In those cases, the defaults provided with the kernel will be used to generate the .config file. For example, here is how I configure the kernel for the TQM860L PowerPC board I have:

$ make ARCH=ppc CROSS_COMPILE=powerpc-linux- TQM860L_config
$ make ARCH=ppc CROSS_COMPILE=powerpc-linux- oldconfig

5.2.3 Managing Multiple Configurations

It is often desirable to test different configurations using the same kernel sources. By changing the kernel's configuration, however, we destroy the previous configuration, because all the configuration files are overwritten by the kernel's configuration utilities. To save a configuration for future use, we need to save the .config files created by the kernel's configuration. These files can later be reused to restore a previous kernel configuration.

The easiest way to back up and retrieve configurations is to use the kernel's own configuration procedures. The menus displayed by both the menuconfig and xconfig Makefile targets allow you to save and restore configurations. In each case, you need to provide an appropriate filename.

You can also save the .config files by hand. In that case, you need to copy the configuration file created by the kernel configuration utilities to an alternative location for future use. To use a saved configuration, you will need to copy the previously saved .config file back into the kernel's root directory and then use the make command with the oldconfig Makefile target to configure the kernel using the newly copied .config. As with the menuconfig Makefile target, the oldconfig Makefile target creates a few headers files and symbolic links.

Whether you copy the files manually or use the menus provided by the various utilities, store the configurations in an intuitive location and use a meaningful naming scheme for saving your configurations. Using our project layout, I suggest that you store all your configurations in the ${PRJROOT}/kernel directory so that the configuration files may live independently from the actual kernel sources while still remaining with the other kernel-related material. To identify each configuration file, prepend each filename with the kernel version it relates to and a small descriptive comment or a date or both. Leave the .config extension as-is, nevertheless, to identify the file as a kernel configuration file.

In the case of the 2.4.18 kernel we are using, for instance, I tried a configuration where I disabled serial port support. I called the corresponding configuration file 2.4.18-no-serial.config. I also maintain the latest known "best" configuration as 2.4.18.config. Feel free to adopt the naming convention that is most intuitive for you, but you may want to avoid generic names such as 2.4.18-test1.config.

5.2.4 Using the EXTRAVERSION Variable

If you are using multiple variants of the same kernel version, you will find the EXTRAVERSION variable to be quite useful in identifying each instance. The EXTRAVERSION variable is appended to the kernel's version number to provide the kernel being built with its final name. The rmk5 patch we applied on our plain 2.4.18, for example, sets EXTRAVERSION to -rmk5 and the resulting version for that kernel is 2.4.18-rmk5.

The final version number is also used to name the directory where the modules built for the kernel are stored. Hence, modules built for two kernels based on the same initial version but with different EXTRAVERSIONs will be stored in two different directories, whereas modules built for two kernels based on the same initial version but that have no EXTRAVERSION will be stored in the same directory.

You can also use this variable to identify variants based on the same kernel version. To do so, edit the Makefile in the main kernel directory and set EXTRAVERSION to your desired value. You will find it useful to rename the directory containing this modified source code using this same value. If, for example, the EXTRAVERSION of a 2.4.18 kernel is set to -motor-diff, the parent directory should be named 2.4.18-motor-diff. The naming of the backup .config files should also reflect the use of EXTRAVERSION. The configuration file for the kernel with disabled serial support should therefore be called 2.4.18-motor-diff-no-serial.config in this case.