Reputation: 403
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
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 ftraceA 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