kakeh
kakeh

Reputation: 403

What happens with functions using macro *__init* as prefix?

From the info I've read about module initialization in a Linux OS, I came to know that the function calls that are having a prefix like __init will be placed in a single ELF location.

For example we usually write:

int __init module_start()
{
....
}

So that that particular ELF location can be overridden or deleted later after initialization is over if so? If we want to use initialization again or if I want to reinitialize any module what is the approach followed, knowing the fact that initialization routines are been deleted?

Upvotes: 1

Views: 308

Answers (1)

mr.spuratic
mr.spuratic

Reputation: 10117

__init is a Linux kernel macro, it is somewhat similar to the normal gcc __attribute__(constructor), with the additional feature that it's also interpreted as a hint that the code can be freed once it has run (modules only, platform dependent). In a "normal" gcc/glibc C program, libc takes care of calling any init (and fini) functions, in the kernel you need to use module_init() (and module_exit()) explicitly.

From include/linux/init.h:

/* These macros are used to mark some functions or 
 * initialized data (doesn't apply to uninitialized data)
 * as `initialization' functions. The kernel can take this
 * as hint that the function is used only during the initialization
 * phase and free up used memory resources after
[...]

#define __init          __section(.init.text) __cold notrace

There are similar macros to mark exit functions, and data. These are the compiler/linker instructions:

  • __section() to place the code in the .init.text section (to jettison)
  • __cold instructs the compiler (via __attribute__() to not optimise calling path since the function is rarely called (once!)
  • notrace to prevent possible problems with ftrace

A simple way to re-invoke module initialisation is to unload and reload the module (sometimes useful for getting a device unwedged).

If there are parts of the initialisation routines which might be useful at runtime, these may be placed in functions not marked __init, and invoked from the real initialisation function. You may mark multiple functions with __init, exactly one must also be used in module_init(), and such function should not be called by your code otherwise. The main point is that the module initialisation code is as much about setting up the kernel API as it is about initialising any hardware or non-hardware driver capabilities (which I'm guessing is the problem you have).

See also:

Upvotes: 2

Related Questions