|
Size: 2721
Comment: explain __init and __initdata more
|
← Revision 10 as of 2021-01-12 01:12:26 ⇥
Size: 2819
Comment:
|
| Deletions are marked like this. | Additions are marked like this. |
| Line 3: | Line 3: |
| The '__'init* and __exit* macros are widely used in the kernel. These macros are defined in include/linux/init.h : | The '__init*' and '__exit*' macros are widely used in the kernel. These macros are defined in include/linux/init.h : |
| Line 21: | Line 21: |
| __init puts the function in the ".init.text" section and __initdata puts the data in the ".init.data" section. | __init puts the function in the ".init.text" section and __initdata puts the data in the ".init.data" section. |
| Line 25: | Line 25: |
| static int md_setup_ents __initdata; | static int md_setup_ents __initdata; |
| Line 31: | Line 31: |
| void __init kmem_cache_init(void) | void __init kmem_cache_init(void) |
| Line 34: | Line 34: |
| The function free_initmem() will free the entire text and data init sections and so the code of your function, if it has been declared as __init. ALl kernel text (code) and data that are marked with __init or __initdata are freed and cannot be used later on. | The function free_initmem() will free the entire text and data init sections and so the code of your function, if it has been declared as '__init'. All kernel text (code) and data that are marked with '__init' or '__initdata' are freed and cannot be used later on. |
| Line 38: | Line 38: |
| 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. |
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. |
| Line 46: | Line 46: |
| A module must use the __init and __exit macros. Here is a prototype of a module : | A module must use the __init and __exit macros. Here is a prototype of a module : |
| Line 54: | Line 54: |
| int __init init_function(void) | int __init init_function(void) |
| Line 62: | Line 62: |
| void __exit exit_function() | void __exit exit_function() |
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().
- The function free_initmem() will free the entire text and data init sections and so the code of your function, if it has been declared as '__init'. All kernel text (code) and data that are marked with '__init' or '__initdata' are freed and cannot be used later on.
__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);