KernelNewbies:

What are the __init* and __exit* macros ?

The init* and exit* macros are widely used in the kernel. These macros are defined in include/linux/init.h :

#define __init          __attribute__ ((__section__ (".init.text")))
#define __initdata      __attribute__ ((__section__ (".init.data")))
#define __exitdata      __attribute__ ((__section__(".exit.data")))
#define __exit_call     __attribute_used__ __attribute__ ((__section__ (".exitcall.exit")))
 
#ifdef MODULE
#define __exit          __attribute__ ((__section__(".exit.text")))
#else
#define __exit          __attribute_used__ __attribute__ ((__section__(".exit.text")))
#endif

__init* macros

It tells the compiler to put the variable or the function in a special section, which is declared in vmlinux.lds. init puts the function in the ".init.text" section and initdata puts the data in the ".init.data" section.

For example, the following declaration means that the variable md_setup_ents will be put in the the init data section.

static int md_setup_ents __initdata;

But why must you use these macros ?

Let's take an example, with the following function, defined in mm/slab.c :

void __init kmem_cache_init(void)

This function initializes the slab system : it's only used once, at the boot of the kernel. So the code of this function should be freed from the memory after the first call. It's the goal of free_initmem().

__exit* macro

The exit macro tells the compiler to put the function in the ".exit.text" section. The exit_data macro tells the compiler to put the function in the ".exit.data" section.

exit.* sections make sense only for the modules : exit functions will never be called if compiled statically. That's why there is a ifdef : exit.* sections will be discarded only if modules support is disabled.

Prototype of a module

A module must use the init and exit macros. Here is a prototype of a module :

#include <linux/module.h>
#include <linux/kernel.h>

#define MODULE_AUTHOR "tyler@agat.net"
#define MODULE_DESC "Description of the module"

int __init init_function(void)
{
        /* Do something */
        if (err)
                return -ERR;
        return 0;
}

void __exit exit_function()
{
        /* Do something */
}

module_init(init_function);
module_exit(exit_function);

MODULE_LICENSE("GPL");
MODULE_AUTHOR(MODULE_AUTHOR);
MODULE_DESCRIPTION(MODULE_DESC);

KernelNewbies: FAQ/InitExitMacros (last edited 2006-05-07 12:04:11 by ARennes-356-1-153-195)