__init and __exit macros
In this article, let’s explore init and exit macros. These are called as function or variables section attributes(shown in Figure 1).
__init
and__exit
macros are C macros used in the Linux kernel.- These macros are defined in
LINUX_SRC/include/linux/init.h
. You can open the init.h file, and you will find these macros. - They are compiler directives or attributes.
You can see above there are just C macros and which expand to a something called compiler directive. These are compiler directives, or you can also call it as compiler attributes (shown in Figure 1).
For example, if you take the first case __init, which expands into __section(.init.text). Here, this is called as a compiler directive, which directs the compiler to keep data or code in an output section called “init.”
When you use this __init macro with any function, then that function code will be placed in a section called “.init” in the final kernel image.
Similarly, __exit is also another C macro, which expands to __section(.exit.text) compiler directive, which directs the compiler to keep data or code in an output section called “exit.” __init, and __exit makes sense only for static modules.
Purpose of __init
Macro:
__init
is a C macro that expands into a compiler directive, directing the compiler to place code in the.init
section of the final ELF image of the Linux kernel.- The
.init
section is freed from memory by the kernel during boot after initialization functions are executed. - It is mainly used for static modules.
- Built-in drivers, which cannot be unloaded, do not need to keep references to their init functions in memory.
For example, this is the init function(in Figure 2).
If this module is a built-in module, then this function will be called only one time, that is, during the boot time. And once this function finishes, then why would you need this function. Because it’s a static function, no one is going to call it. Don’t you think it’s better to remove the memory occupied by this function code, the kernel can remove it from the memory, which will save some memory, because there are 100 thousand built-in modules.
Removing some memory for 100 modules would be huge. The kernel is going to save a lot of runtime memory. That’s why __init is a technique by using that we push that function into a init section, a separate section, which a kernel can free later.
Using __init macro is a technique, when used with a function, the kernel will free the code memory of that function after its execution. And also, remember that it is an optional one. If you omit that, then no problem. You don’t see any compilation, warnings, or errors. You can omit that.
Similarly, you can use __initdata with variables that will be dropped after the initialization.__init is for code or for function, __initdata is for variables, init variables.
Purpose of __exit
Macro:
- For built-in modules, cleanup functions are not required.
- When
__exit
is used with a cleanup function, the kernel build system excludes those functions during the build process. __exit
acts as a marker for the build system to exclude cleanup functions from the final kernel image.
Usage Example:
- Consider three static modules:
module1.c
,module2.c
, andmodule3.c
.
Let’s say module1.c’s init function is m1 init function, module2.c’s init function is m2 init function, and module3.c’s init function is m3 init function. Out of these 3 init functions, m1 init function and m2 init functions are tagged with init macros.
module1.c
andmodule2.c
have init functions tagged with__init
.- During kernel build, all three modules become part of the final kernel image.
- A new
.init
section is created in the final image, andm1_init_function
andm2_init_function
are placed in this section. - The kernel calls
m1_init_function
andm2_init_function
during boot and frees the memory occupied by the.init
section since these functions won’t be executed again. m3_init_function
is not tagged with__init
, so it remains in the.text
region and consumes memory throughout kernel runtime.- All functions marked with
__exit
are dropped by the kernel build system and are not part of the final image.
Conclusion:
- The use of
__init
and__exit
macros helps optimize memory usage in the Linux kernel. __init
is used for code/functions, while__exit
is used for cleanup functions.- These macros are optional but can significantly reduce memory consumption for certain modules.
In the following article, I am going to cover Linux Kernel module entry points registration.
Get the Full Course on Linux device Driver Here.
FastBit Embedded Brain Academy Courses
Click here: https://fastbitlab.com/course1