6

I am currently looking through the code of a "third-party" driver in an attempt to figure out/learn how it functions. I've had a look at sites such as this one, so I sort of understand how the basic premise works, but I don't understand the purpose of #ifdef MODULE here. Google isn't really much help, but I think the definition refers to a kernel module? (I am also completely new to this.)

module_init(os_driver_init);
#ifdef MODULE
module_exit(os_driver_cleanup);
#endif

My question is, what happens if I remove the #ifdef statement? Also, why/when would it be necessary to include the #ifdef statement?

janneia
  • 63
  • 7
  • 1
    Is there an alternative (lower down in the code) `module_exit(...)` line? It may be that alternative functions are called, and the `ifdef MODULE` controls this – chrisb2244 Oct 01 '14 at 07:16
  • Maybe `MODULE` is to be defined when driver is statically compiled in to kernel? http://www.fsl.cs.sunysb.edu/kernel-api/re02.html – user694733 Oct 01 '14 at 07:20
  • Can you link to this "third-party" driver code? The `#ifdef` you're showing shouldn't be there any more. – Jonathon Reinhart Oct 01 '14 at 07:38
  • @JonathonReinhart The permalink is [here](http://support.automation.siemens.com/WW/view/en/67634126) and the direct download link (that may or may not work?) is [here](http://support.automation.siemens.com/WW/llisapi.dll/csfetch/67634126/DK16xx_V2p6p0.zip?func=cslib.csFetch&nodeid=88192690). That's a compressed file, so the file I'm looking at is actually in V2.6.0\DK16xx_V2p6p0\linux-sw\host_linx\driver\linux\cp16xx_linux.c – janneia Oct 01 '14 at 22:32

1 Answers1

7

In the Linux kernel, most drivers can be either statically linked (built-in) to the kernel image itself, or built as dynamically-loaded modules (.ko files).

The MODULE macro is defined for a C file when it is being compiled as part of a module, and undefined when it is being built directly into the kernel.

The code you're showing is only defining os_driver_cleanup as a module-exit function when it is being compiled as a module. However, this construct is unnecessary in modern kernel code; include/linux/init.h defines module_exit() as a macro, whose implementation depends on #ifdef MODULE.

Basically, you should always provide an exit function, and leave off the #ifdef around module_exit(). You should also mark your exit function with __exit, which will properly control inclusion of the code for your in the modular/non-modular case.

Here's an example of proper init/exit code.

static int  __init foo_init(void)
{
    /* Register driver, etc. */
}

static void __exit foo_cleanup(void)
{
    /* Unregister driver, etc. */
}

module_init(foo_init);
module_exit(foo_cleanup);
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328