Книга: Embedded Linux Primer: A Practical, Real-World Approach

8.1.4. Module Build Infrastructure

8.1.4. Module Build Infrastructure

A device driver must be compiled against the kernel on which it will execute. Although it is possible to load and execute kernel modules built against a different kernel version, it is risky to do so unless you are certain that the module does not rely on any features of your new kernel. The easiest way to do this is to build the module within the kernel's own source tree. This ensures that as the developer changes the kernel configuration, his custom driver is automatically rebuilt with the correct kernel configuration. It is certainly possible to build your drivers outside of the kernel source tree. However, in this case, you are responsible for making sure that your device driver build configuration stays in sync with the kernel you want to run your driver on. This typically includes compiler switches, location of kernel header files, and kernel configuration options.

For the example driver introduced in Listing 8-1, the following changes were made to the stock Linux kernel source tree to enable building this example driver. We explain each step in detail.

1. Starting from the top-level Linux source directory, create a directory under .../drivers/char called examples.

2. Add a menu item to the kernel configuration to enable building examples and to specify built-in or loadable kernel module.

3. Add the new examples subdirectory to the .../drivers/char/Makefile conditional on the menu item created in step 2.

4. Create a makefile for the new examples directory, and add the hello1.o module object to be compiled conditional on the menu item created in step 2.

5. Finally, create the driver hello1.c source file from Listing 8.1.

Adding the examples directory under the .../drivers/char subdirectory is self-explanatory. After this directory is created, two files are created in this directory: the module source file itself from Listing 8-1 and the makefile for the examples directory. The makefile for examples is quite trivial. It will contain this single line:

obj-$(CONFIG_EXAMPLES) += hello1.o

Adding the menu item to the kernel configuration utility is a little more involved. Listing 8-2 contains a patch that, when applied to the .../drivers/char/Kconfig file from a recent Linux release, adds the configuration menu item to enable our examples configuration option. For those readers not familiar with the diff / patch format, each line in Listing 8-1 preceded by a single plus (+) character is inserted in the file between the indicated lines (those without the leading + character).

Listing 8-2. Kconfig Patch for Examples

diff -u ~/base/linux-2.6.14/drivers/char/Kconfig ./drivers/char/Kconfig
--- ~/base/linux-2.6.14/drivers/char/Kconfig
+++ ./drivers/char/Kconfig
@@ -4,6 +4,12 @@
menu "Character devices"
+config EXAMPLES
+       tristate "Enable Examples"
+       default M
+       ---help---
+       Enable compilation option for driver examples
  config VT
         bool "Virtual terminal" if EMBEDDED
         select INPUT

When applied to Kconfig in the .../drivers/char subdirectory of a recent Linux kernel, this patch results in a new kernel configuration option called CONFIG_EXAMPLES. As a reminder from our discussion on building the Linux kernel in Chapter 4, "The Linux KernelA Different Perspective," the configuration utility is invoked as follows (this example assumes the ARM architecture):

$ make ARCH=ARM CROSS_COMPILE=xscale_be- gconfig

After the configuration utility is invoked using a command similar to the previous one, our new Enable Examples configuration option appears under the Character devices menu, as indicated in the patch. Because it is defined as type tristate, the kernel developer can choose from three choices:

(N) No. Do not compile examples.

(Y) Yes. Compile examples and link with final kernel image.

(M) Module. Compile examples as dynamically loadable module.

Figure 8-1 shows the resulting gconfig screen with the new configuration option added. The dash (-) in the check box selects (M)odule, as indicated in the M column on the right. A check mark in the check box selects (Y)es, indicating that the driver module should be compiled as part of the kernel proper. An empty check box indicates that the option is not selected.

Figure 8-1. Kernel configuration with Examples module

Now that we have added the configuration option to enable compiling our examples device driver module, we need to modify the makefile in .../drivers/char to instruct the build system to descend into our new examples subdirectory if the configuration option CONFIG_EXAMPLES is present in our configuration. Listing 8-3 contains the patch for this against the makefile in a recent Linux release.

Listing 8-3. Makefile Patch for Examples

diff -u ~/base/linux-2.6.14/drivers/char/Makefile ./drivers/char/Makefile
--- ~/base/linux-2.6.14/drivers/char/Makefile
+++ ./drivers/char/Makefile
@@ -88,6 +88,7 @@
 obj-$(CONFIG_DRM) += drm/
 obj-$(CONFIG_PCMCIA) += pcmcia/
 obj-$(CONFIG_IPMI_HANDLER) += ipmi/
+obj-$(CONFIG_EXAMPLES) += examples/
obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o

The patch in Listing 8-3 adds the single line (preceded by the + character) to the makefile found in .../drivers/char. The additional lines of context are there so that the patch utility can determine where to insert the new line. Our new examples directory was added to the end of the list of directories already being searched in this makefile, which seemed like a logical place to put it. Other than for consistency and readability, the location is irrelevant.

Having completed the steps in this section, the infrastructure is now in place to build the example device driver. The beauty of this approach is that the driver is built automatically whenever a kernel build is invoked. As long as the configuration option defined in Listing 8-3 is selected (either M or Y), the driver module is included in the build.

Building for an arbitrary ARM system, the command line for building modules might look like this:

$ make ARCH=arm CROSS_COMPILE=xscale_be- modules

Listing 8-4 shows the build output after a typical editing session on the module (all other modules have already been built in this kernel source tree.)

Listing 8-4. Module Build Output

$ make ARCH=arm CROSS_COMPILE=xscale_be- modules
  CHK     include/linux/version.h
make[1]: 'arch/arm/kernel/asm-offsets.s' is up to date.
make[1]: 'include/asm-arm/mach-types.h' is up to date.
  CC [M]  drivers/char/examples/hello1.o
  Building modules, stage 2.
  LD [M]  drivers/char/examples/hello1.ko

Оглавление книги

Генерация: 0.034. Запросов К БД/Cache: 0 / 0
Вверх Вниз