Thursday, June 19, 2014

Modules




Introduction-


  • Despite being "monolithic," in the sense of the whole kernel running in a single protection domain, the Linux kernel is modular, allowing the dynamic insertion and removal of code from the kernel at run-time. 
  • Related subroutines, data, and entry and exit points are grouped together in a single binary image, a loadable kernel object, called a module
  • Support for modules allows systems to have only a minimal base kernel image, with optional features and drivers supplied via module. 
  • Modules also provide easy removal and reloading of kernel code, facilitate debugging, and allow for the loading of new drivers on demand in response to the hotplugging of new devices.



Our first 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("jin");

  • 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, we need not export the function, and it can be marked as static.
  • Init functions return an int. If initialization (or whatever our 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 invokeshello_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, we 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.

No comments:

Post a Comment