If you are wondering how to find a kernel for your particular application, the best way to proceed is to obtain the latest stable Linux source tree. Check to see if support for your particular processor exists, and then search the Linux kernel mailing lists for any patches or issues related to your application. Also find the mailing list that most closely matches your interest, and search that archive also.
Appendix E, "Open Source Resources," contains several good references and sources of information related to kernel source repositories, mailing lists, and more.
4.2. Linux Kernel Construction
In the next few sections, we explore the layout, organization, and construction of the Linux kernel. Armed with this knowledge, you will find it much easier to navigate this large, complex source code base. Over time, there have been significant improvements in the organization of the source tree, especially in the architecture branch, which contains support for numerous architectures and specific machines. As this book is being written, an effort is underway to collapse the ppc and ppc64 architecture branches into a single common powerpc branch. When the dust settles, there will be many improvements, including elimination of duplicate code, better organization of files, and partitioning of functionality.
4.2.1. Top-Level Source Directory
We make frequent reference to the top-level source directory throughout the book. In every case, we are referring to the highest-level directory contained in the kernel source tree. On any given machine, it might be located anywhere, but on a desktop Linux workstation, it is often found in /usr/src/linux-x.y.z, where x.y.z represents the kernel version. Throughout the book, we use the shorthand .../ to represent the top-level kernel source directory.
The top-level kernel source directory contains the following subdirectories. (We have omitted the nondirectory entries in this listing, as well as directories used for source control for clarity and brevity.)
arch crypto Documentation drivers fs include
init ipc kernel lib mm net
scripts security sound usr
Many of these subdirectories contain several additional levels of subdirectories containing source code, makefiles, and configuration files. By far the largest branch of the Linux kernel source tree is found under .../drivers. Here you can find support for Ethernet network cards, USB controllers, and the numerous hardware devices that the Linux kernel supports. As you might imagine, the .../arch subdirectory is the next largest, containing support for more than 20 unique processor architectures.
Additional files found in the top-level Linux subdirectory include the top-level makefile, a hidden configuration file ( dot-config , introduced in Section 4.3.1, "The Dot-Config") and various other informational files not involved in the build itself. Finally, two important build targets are found in the top-level kernel source tree after a successful build: System.map and the kernel proper, vmlinux. Both are described shortly.
4.2.2. Compiling the Kernel
Understanding a large body of software such as Linux can be a daunting task. It is too large to simply "step through" the code to follow what is happening. Multithreading and preemption add to the complexity of analysis. In fact, even locating the entry point (the first line of code to be executed upon entry to the kernel) can be challenging. One of the more useful ways to understand the structure of a large binary image is to examine its built components.
The output of the kernel build system produces several common files, as well as one or more architecture-specific binary modules. Common files are always built regardless of the architecture. Two of the common files are System.map and vmlinux, introduced earlier. The former is useful during kernel debug and is particularly interesting. It contains a human-readable list of the kernel symbols and their respective addresses. The latter is an architecture-specific ELF [27] Executable and Linking Format, a de-facto standard format for binary executable files.
file in executable format. It is produced by the top-level kernel makefile for every architecture. If the kernel was compiled with symbolic debug information, it will be contained in the vmlinux image. In practice, although it is an ELF executable, this file is usually never booted directly, as you will see shortly.
Listing 4-2 is a snippet of output resulting from executing make in a recent kernel tree configured for the ARM XScale architecture. The kernel source tree was configured for the ADI Engineering Coyote reference board based on the Intel IXP425 network processor using the following command:
make ARCH=arm CROSS_COMPILE=xscale_be- ixp4xx_defconfig
This command does not build the kernel; it prepares the kernel source tree for the XScale architecture including an initial default configuration for this architecture and processor. It builds a default configuration (the dot-config file) that drives the kernel build, based on the defaults found in the ixp4xx_defconfig file. We have more to say about the configuration process later, in Section 4.3, "Kernel Build System."
Listing 4-2 shows the command that builds the kernel. Only the first few and last few lines of the build output are shown for this discussion.
Listing 4-2. Kernel Build Output
$ make ARCH=arm CROSS_COMPILE=xscale_be- zImage
CHK include/linux/version.h
HOSTCC scripts/basic/fixdep
.
.
.
LD vmlinux
SYSMAP System.map
SYSMAP .tmp_System.map
OBJCOPY arch/arm/boot/Image
Kernel: arch/arm/boot/Image is ready
AS arch/arm/boot/compressed/head.o
GZIP arch/arm/boot/compressed/piggy.gz
AS arch/arm/boot/compressed/piggy.o
CC arch/arm/boot/compressed/misc.o
AS arch/arm/boot/compressed/head-xscale.o
AS arch/arm/boot/compressed/big-endian.o
LD arch/arm/boot/compressed/vmlinux
OBJCOPY arch/arm/boot/zImage
Kernel: arch/arm/boot/zImage is ready
Building modules, stage 2.
...
To begin, notice the invocation of the build. Both the desired architecture (ARCH=arm) and the toolchain (CROSS_COMPILE=xscale_be-) were specified on the command line. This forces make to use the XScale toolchain to build the kernel image and to use the arm-specific branch of the kernel source tree for architecture-dependent portions of the build. We also specify a target called zImage . This target is common to many architectures and is described in Chapter 5, "Kernel Initialization."
The next thing you might notice is that the actual commands used for each step have been hidden and replaced with a shorthand notation. The motivation behind this was to clean up the build output to draw more attention to intermediate build issues, particularly compiler warnings. In earlier kernel source trees, each compilation or link command was output to the console verbosely, which often required several lines for each step. The end result was virtually unreadable, and compiler warnings slipped by unnoticed in the noise. The new system is definitely an improvement because any anomaly in the build process is easily spotted. If you want or need to see the complete build step, you can force verbose output by defining V=1 on the make command line.
We have omitted most of the actual compilation and link steps in Listing 4-2, for clarity. (This particular build has more than 900 individual compile and link commands in the build. That would have made for a long listing, indeed.) After all the intermediate files and library archives have been built and compiled, they are put together in one large ELF build target called vmlinux. Although it is architecture specific, this vmlinux target is a common targetit is produced for all supported Linux architectures.
Читать дальше