Hello, World!Unlike development on core subsystems of the kernelmuch of what has been discussed thus farmodule development is more like writing a new application, at least in that modules have entry points and exit points and live in their own files. It might be trite and cliché, but it would be a travesty of the highest order to have the opportunity to write a Hello, World! program and not capitalize on the occasion. Ladies and gentlemen, the kernel module Hello, World: /* * hello.c Hello, World! As a Kernel Module */ #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> /* * hello_init the init function, called when the module is loaded. * Returns zero if successfully loaded, nonzero otherwise. */ static int hello_init(void) { printk(KERN_ALERT "I bear a charmed life.\n"); return 0; } /* * hello_exit the exit function, called when the module is removed. */ static void hello_exit(void) { printk(KERN_ALERT "Out, out, brief candle!\n"); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Shakespeare"); This is as simple a kernel module as one can get. The hello_init() function is registered via module_init() as this module's entry point. It is invoked by the kernel when the module is loaded. The call to module_init() is not really a function call at all but a macro that assigns its sole parameter as the initialization function for this module. All init functions must have the form int my_init(void); Because init functions are typically not directly called by external code, you need not export the function, and it can be marked as static. Init functions return an int. If initialization (or whatever your init function does) was successful, the function returns zero. On failure, it returns nonzero. This init function merely prints a simple message and returns zero. Init functions in real world modules typically register resources, allocate data structures, and so on. Even if this file were compiled statically into the kernel image, the init function would be kept and run on kernel boot. The hello_exit() function is registered as this module's exit point via module_exit(). The kernel invokes hello_exit() when the module is removed from memory. Exit functions might clean up resources, ensure that hardware is in a consistent state, and so on before returning. After the exit function returns, the module is unloaded. Exit functions must have the form void my_exit(void); As with the init function, you probably want to mark it static. If this file were compiled into the static kernel image, the exit function would not be included and it would never be invoked (because, if it were not a module, the code could never be removed from memory). The MODULE_LICENSE() macro specifies the copyright license for this file. Loading a non-GPL module into memory results in the tainted flag being set in the kernel. This flag is also just for informational purposes, but many kernel developers give bug reports less credence when the tainted flag is set in the oops. Further, non-GPL modules cannot invoke GPL-only symbols (see the section "Exported Symbols" later in this chapter). Finally, the MODULE_AUTHOR() macro specifies this file's author. The value of this macro is entirely for informational purposes. |