Team LiB
Previous Section Next Section

Building Modules

In 2.6, building modules is easier than ever, thanks to the new "kbuild" build system. The first decision in building modules is deciding where the module source is to live. You can add the module source to the kernel source proper, either as a patch or by eventually merging your code into the official tree. Alternatively, you can maintain and build your module source outside the source tree.

At Home in the Source Tree

Ideally, your module is an official part of Linux and thus lives in the kernel source tree. Getting your work into the kernel proper may require more maintenance at first, but it is usually the preferred solution.

The first step is deciding where in the kernel source tree your module is to live. Drivers are stored in subdirectories of the drivers/ directory in the root of the kernel source tree. Inside, they are further organized by class, type, and eventually specific driver. Character devices live in drivers/char/, whereas block devices live in drivers/block/ and USB devices live in drivers/usb/. The rules are not hard and fast because many USB devices are character devices. But the organization is fairly understandable and accurate.

Assume you have a character device and want to store it in drivers/char/. Inside this directory are numerous C source files and a handful of other directories. Drivers with only one or two source files might simply stick their source in this directory. Drivers with multiple source files and other accompanying junk might create a new subdirectory. There is no hard and fast rule.

Presume that you want to create your own subdirectory. In this fantasy, your driver is for a fishing pole with a computer interface, the Fish Master XL 2000 Titanium, so you need to create a fishing subdirectory inside drivers/char/.

Now you need to add a line to the Makefile in drivers/char/. So you edit drivers/char/Makefile and add

obj-m += fishing/

This causes the build system to descend into the fishing/ subdirectory whenever it compiles modules. More likely, your driver's compilation is contingent on a specific configuration option; for example, perhaps CONFIG_FISHING_POLE (see the section "Managing Configuration Options" later in this chapter for how to add a new con-figuration option). In that case, you would instead add the line

obj-$(CONFIG_FISHING_POLE) += fishing/

Finally, inside drivers/char/fishing/, you add a new Makefile with the following line:

obj-m += fishing.o

The build system will now descend into fishing/ and build the module fishing.ko from fishing.c. Yes, you write an extension of .o but the module is compiled as .ko.

Again, more likely, your fishing pole driver's compilation is conditional on a configuration option. So you probably want to do the following:

obj-$(CONFIG_FISHING_POLE) += fishing.o

One day, your fishing pole driver may get so complicatedautodetection of fishing line test is just the latest "must have"that it grows to occupy more than one source file. No problem, anglers! You simply make your Makefile read

obj-$(CONFIG_FISHING_POLE) += fishing.o
fishing-objs := fishing-main.o fishing-line.o

Now, fishing-main.c and fishing-line.c will be compiled and linked into fishing.ko.

Finally, you may need to pass to gcc additional compile flags during the build process solely for your file. To do so, simply add a line such as the following to your Makefile:

EXTRA_CFLAGS += -DTITANIUM_POLE

If you opted to place your source file(s) in drivers/char/ and not create a new subdirectory, you would merely place the preceding lines (that you placed in your Makefile in drivers/char/fishing/) into drivers/char/Makefile.

To compile, run the kernel build process as usual. If your module's build was conditioned on a configuration option, as it was with CONFIG_FISHING_POLE, make sure that the option is enabled before beginning.

Living Externally

If you prefer to maintain and build your module outside the kernel source tree, to live the life of an outsider, simply create a Makefile in your own source directory like the single line

obj-m := fishing.o

This compiles fishing.c into fishing.ko. If your source spans multiple files, then two lines will suffice:

obj-m := fishing.o
fishing-objs := fishing-main.o fishing-line.o

This compiles fishing-main.c and fishing-line.c into fishing.ko.

The main difference in living externally is the build process. Because your module lives outside the kernel tree, you need to instruct make on how to find the kernel source files and base Makefile. This is also easy:

make -C /kernel/source/location SUBDIRS=$PWD modules

where /kernel/source/location is the location of your configured kernel source tree. Recall that you should not store your working copy of the kernel source tree in /usr/src/linux but somewhere else, easily accessible, in your home directory.

    Team LiB
    Previous Section Next Section