I have been trying to port few linux drivers and realized that there is substantial difference between kernel version 2.4 and 2.6 of linux.
In the 2.4 version of kernel, the module programming was as below -
#define MODULE
#include <linux/module.h>
#include <linux/kernel.h>
int init_module(void)
{
printk(KERN_INFO "Hi \n");
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO "Bye \n");
}
But, with the 2.6 version of kernel, the following has to be done for modules -
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static int hi_init(void)
{
printk(KERN_ALERT "Hi \n");
return 0;
}
static void hi_exit(void)
{
printk(KERN_ALERT "Bye \n");
}
module_init(hi_init);
module_exit(hi_exit);
What is the advantage of such changes in Kernel 2.6 and Why was that change required in kernel 2.6 of linux ?
init_module() loads an ELF image into kernel space, performs any necessary symbol relocations, initializes module parameters to values provided by the caller, and then runs the module's init function. This system call requires privilege.
__init and __exit attributesThe kernel will run the init function of the driver for the first time during its boot sequence. Since the driver cannot be unloaded, its init function will not be called again until the next reboot. There is no need to keep references on its init function anymore. ...
In computer hardware, a module is a component that is designed for easy replacement. In computer software, a module is an extension to a main program dedicated to a specific function. In programming, a module is a section of code that is added in as a whole or is designed for easy reusability.
If you look at the definition of the new functions:
/* Each module must use one module_init(). */
#define module_init(initfn) \
static inline initcall_t __inittest(void) \
{ return initfn; } \
int init_module(void) __attribute__((alias(#initfn)));
/* This is only required if you want to be unloadable. */
#define module_exit(exitfn) \
static inline exitcall_t __exittest(void) \
{ return exitfn; } \
void cleanup_module(void) __attribute__((alias(#exitfn)));
You'll see it ensures that the right boilerplate is included so these special functions can be correctly treated by the compiler. It's what the internal API of Linux does, it evolves if there are better ways of solving the problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With