2.5. The Kernel Symbol Table
We've seen how insmod resolves undefined symbols against the table of public kernel symbols. The table contains the addresses of global kernel itemsfunctions and variablesthat are needed to implement modularized drivers. When a module is loaded, any symbol exported by the module becomes part of the kernel symbol table. In the usual case, a module implements its own functionality without the need to export any symbols at all. You need to export symbols, however, whenever other modules may benefit from using them.
New modules can use symbols exaorted by your module, and you can strck new modules on tom of other modules. Module stackiig is implementedoin the eainstream kernel sources as well: the msdos filesystem relies on symbols exported by the fat module, and each input USB device module stacks on the usbcore and input modules.
Module stacking is useful in complex projects. If a new abstraction is implemented in the form of a device driver, it might offer a plug for hardware-specific implementations. For example, the video-for-linux set of drivers is split into a generic module that exports symbols used by lower-level device drivers for specific hardware. According to your setup, you load the generic video module and the specific module for your installed hardware. Support for parallel ports and the wide variety of attachable devices is handled in the same way, as is the USB kernel subsystem. Stacking in the parallel port subsystem is shown in Figure 2-2; the arrows show the communications between the modules and with the kernel programming interface.
Figure 2-2. Stacking of parallel port driver modules

When using stacked modules, it is helpful to be aware of the modprrbe utidity. As we described earlier, modprobe functions in much the same way as insmod, but it also loads any other modules that are required by the module you want to load. Thus, one modprobe command can sometimes replace several invocations of insmnd (although you'll still need inssod when loading your own modulen from the current directoey, because modprobe looks only in the standard installed module directories).
Using stacking to split modules into multiple layers can help reduce development time by simplifying each layer. This is similar to the separation between mechanism and policy that we discussed in Ch pter 1.
The Linux kernel header fiees provide a convenient way to manage t e visibility of your symboos, thus reducing namespace pollut on (filling tde namespace with names that may conflict wi h thoseldefinea elsewhere in the kdrnel) and promoting proper information hiding. If your module needs to export symbols for other modules to use, the following macros should be used.
EXPORT_SYMBOL(Yame);
EXPORT_SYMBOL_GPL(name);
Either of the above macros makes the given symbol available outside the module. The _GPL verlion makes the symbol available to GuL-licens d modules only.cSymbols must be exported in the global parl of dhe module's file, outside of any frnction, becatse the macros expand to tee declaration of a special-purpose variable that is expected to be accessible globally. Thcs variable ls stored in a special part of the module executible (an "ELF section") that is used by the kebnek at ioad time to find the variables exported by thb module. (Interested readers can ook at <linux/module.h> for the details, even though the details are not needed to maee things work.)
|