5.4 Installing the Kernel

Ultimately, the kernel we generated and its modules will have to be copied to your target to be used. I will cover the actual copying of the kernel and its modules in Chapter 6 and Chapter 9. Meanwhile, we will discuss how to manage multiple kernel images and their corresponding module installations. The configuration of the target's boot layout and its root filesystem depend on the techniques we discuss below.

5.4.1 Managing Multiple Kernel Images

In addition to using separate directories for different kernel versions, you will find it useful to have access to multiple kernel images to test on your target. Since these images may be built using the same sources, we need to copy them out of the kernel source and into a directory where they can be properly identified. In our setup, the repository for these images is the ${PRJROOT}/images directory.

For each kernel configuration, we will need to copy four files: the uncompressed kernel image, the compressed kernel image, the kernel symbol map, and the configuration file. The last three are found within the kernel sources' root directory and are called vmlinux, System.map, and .config, respectively. The compressed kernel image file is found in the arch/YOUR_ARCH/boot directory, where YOUR_ARCH is the name of your target's architecture, and is called zImage or bzImage, depending on the Makefile target you used earlier. For our ARM-based target, the compressed kernel image is arch/arm/boot/zImage.

Some architectures, such as the PPC, have many boot directories. In those cases, the kernel image to use is not necessarily the one located at arch/YOUR_ARCH/boot/zImage. In the case of the TQM board mentioned above, for example, the compressed kernel image that should be used is arch/ppc/images/vmlinux.gz. Have a look at the arch/YOUR_ARCH/Makefile for a full description of all the Makefile boot image targets for your architecture. In the case of the PPC, the type of boot image generated depends on the processor model for which the kernel is compiled.

To identify the four files needed, we use a naming scheme similar to that of the kernel's version. In the case of the kernel generated using 2.4.18-rmk5 sources, for instance, we copy the files as follows:

$ cp arch/arm/boot/zImage ${PRJROOT}/images/zImage-2.4.18-rmk5
$ cp System.map ${PRJROOT}/images/System.map-2.4.18-rmk5
$ cp vmlinux ${PRJROOT}/images/vmlinux-2.4.18-rmk5
$ cp .config ${PRJROOT}/images/2.4.18-rmk5.config

You could also include the configuration name in the filenames. So in the case of the kernel without serial support, for instance, we could name the four kernel files zImage-2.4.18-rmk5-no-serial, System.map-2.4.18-rmk5-no-serial, vmlinux-2.4.18-rmk5-no-serial, and 2.4.18-rmk5-no-serial.config.

5.4.2 Installing Kernel Modules

The kernel Makefile includes the modules_install target for installing the kernel modules. By default, the modules are installed in the /lib/modules directory. Since we are in a cross-development environment, however, we need to instruct the Makefile to install the modules in another directory.

As the kernel modules need to be used with the corresponding kernel image, we will install the modules in a directory with a name similar to that of the kernel image. So in the case of the 2.4.18-rmk5 kernel we are using, we install the modules in the ${PRJROOT}/images/modules-2.4.18-rmk5 directory. The content of this directory will later be copied to the target's root filesystem for use with the corresponding kernel on the target. To install the modules in that directory, we use:

$ make ARCH=arm CROSS_COMPILE=arm-linux- \
> INSTALL_MOD_PATH=${PRJROOT}/images/modules-2.4.18-rmk5 \
> modules_install

The INSTALL_MOD_PATH variable is prepended to the /lib/modules path, so the modules are therefore installed in the ${PRJROOT}/images/modules-2.4.18-rmk5/lib/modules directory.

Once it is done copying the modules, the kernel tries to build the module dependencies needed for the module utilities during runtime. Since depmod, the utility that builds the module dependencies, is not designed to deal with cross-compiled modules, it will fail.

To build the module dependencies for your modules, you will need to use another module dependency builder provided with the BusyBox package. We will discuss BusyBox at length in Chapter 6. For now, download a copy of the BusyBox archive from http://www.busybox.net/ into your ${PRJROOT}/sysapps directory and extract it there.[5] From the BusyBox directory, copy the scripts/depmod.pl Perl script into the ${PREFIX}/bin directory.

[5] Download BusyBox Version 0.60.5 or later.

We can now build the module dependencies for the target:

$ depmod.pl \
> -k ./vmlinux -F ./System.map \
> -b ${PRJROOT}/images/modules-2.4.18-rmk5/lib/modules > \
> ${PRJROOT}/images/modules-2.4.18-rmk5/lib/modules/2.4.18-rmk5/modules.dep

The -k option is used to specify the uncompressed kernel image, the -F option is used to specify the system map, and the -b option is used to specify the base directory containing the modules for which we need to build dependencies. Because the tool's output goes to the standard output, we redirect it to the actual dependency file, which is always called modules.dep.