This demonstrates a feature of kernel 2.2 and later. Notice the change in the definitions of the init and cleanup functions. The __init macro causes the init function to be discarded and its memory freed once the init function finishes for built-in drivers, but not loadable modules. If you think about when the init function is invoked, this makes perfect sense.
There is also an __initdata which works similarly to __init but for init variables rather than functions.
The __exit macro causes the omission of the function when the module is built into the kernel, and like __exit, has no effect for loadable modules. Again, if you consider when the cleanup function runs, this makes complete sense; built-in drivers don't need a cleanup function, while loadable modules do.
These macros are defined in linux/init.h and serve to free up kernel memory. When you boot your kernel and see something like Freeing unused kernel memory: 236k freed, this is precisely what the kernel is freeing.
Example 2-5. hello-3.c
/* hello-3.c - Illustrating the __init, __initdata and __exit macros. |
By the way, you may see the directive "__initfunction()" in drivers written for Linux 2.2 kernels:
__initfunction(int init_module(void)) |
This macro served the same purpose as __init, but is now very deprecated in favor of __init. I only mention it because you might see it modern kernels. As of 2.4.18, there are 38 references to __initfunction(), and of 2.4.20, there are 37 references. However, don't use it in your own code.
2.5. Hello World (part 4): Licensing and Module Documentation
If you're running kernel 2.4 or later, you might have noticed something like this when you loaded the previous example modules:
# insmod hello-3.o |
In kernel 2.4 and later, a mechanism was devised to identify code licensed under the GPL (and friends) so people can be warned that the code is non open-source. This is accomplished by the MODULE_LICENSE() macro which is demonstrated in the next piece of code. By setting the license to GPL, you can keep the warning from being printed. This license mechanism is defined and documented in linux/module.h.
Similarly, MODULE_DESCRIPTION() is used to describe what the module does, MODULE_AUTHOR() declares the module's author, and MODULE_SUPPORTED_DEVICE() declares what types of devices the module supports.
These macros are all defined in linux/module.h and aren't used by the kernel itself. They're simply for documentation and can be viewed by a tool like objdump. As an exercise to the reader, try grepping through linux/drivers to see how module authors use these macros to document their modules.
Example 2-6. hello-4.c
/* hello-4.c - Demonstrates module documentation. |