Linux Device Driver Programming Lecture 18: __init and __exit macros

  • Post author:
  • Post category:Blog

 

__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).

Figure 1. Function section attributes
Figure 1. Function section attributes

 

  • __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.

 

Figure 2. Init and Exit functions- Linux kernel development
Figure 2. Init and Exit functions

 

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, and module3.c.
Figure 3. Init function’s modules explanation- Linux kernel development
Figure 3. Init function’s modules explanation

 

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 and module2.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, and m1_init_function and m2_init_function are placed in this section.
  • The kernel calls m1_init_function and m2_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

 

FastBitLab

The FastBit Embedded Brain Academy uses the power of internet to bring the online courses related to the field of embedded system programming, Real time operating system, Embedded Linux systems, etc at your finger tip with very low cost. Backed with strong experience of industry, we have produced lots of courses with the customer enrolment over 3000+ across 100+ countries.