Im Linux-Kernel-Quellcode habe ich diese Funktion gefunden:
static int __init clk_disable_unused(void)
{
// some code
}
Hier kann ich nicht verstehen, was __init
bedeutet.
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
*
* Usage:
* For functions:
*
* You should add __init immediately before the function name, like:
*
* static void __init initme(int x, int y)
* {
* extern int z; z = x * y;
* }
*
* If the function has a prototype somewhere, you can also add
* __init between closing brace of the prototype and semicolon:
*
* extern int initialize_foobar_device(int, int, int) __init;
*
* For initialized data:
* You should insert __initdata between the variable name and equal
* sign followed by value, e.g.:
*
* static int init_variable __initdata = 0;
* static const char linux_logo[] __initconst = { 0x32, 0x36, ... };
*
* Don't forget to initialize data not at file scope, i.e. within a function,
* as gcc otherwise puts the data into the bss section and not into the init
* section.
*
* Also note, that this data cannot be "const".
*/
/* These are for everybody (although not all archs will actually
discard it in modules) */
#define __init __section(.init.text) __cold notrace
#define __initdata __section(.init.data)
#define __initconst __section(.init.rodata)
#define __exitdata __section(.exit.data)
#define __exit_call __used __section(.exitcall.exit)
Dies sind nur Makros, um einige Teile des Linux-Codes in speziellen Bereichen der endgültigen ausführenden Binärdatei zu lokalisieren.
__init
Beispielsweise (oder besser, __attribute__ ((__section__
(".init.text")))
wenn dieses Makro erweitert wird) wird der Compiler angewiesen, diese Funktion auf besondere Weise zu markieren. Am Ende sammelt der Linker alle Funktionen mit dieser Markierung am Ende (oder Anfang) der Binärdatei.
Wenn der Kernel gestartet wird, wird dieser Code nur einmal ausgeführt (Initialisierung). Nach der Ausführung kann der Kernel diesen Speicher freigeben, um ihn wiederzuverwenden. Die Kernel-Meldung wird angezeigt:
Nicht verwendeten Kernelspeicher freigeben: 108.000 freigegeben
Um diese Funktion nutzen zu können, benötigen Sie eine spezielle Linker-Skriptdatei, die dem Linker mitteilt, wo sich alle markierten Funktionen befinden.
Dies zeigt eine Funktion von Kernel 2.2 und höher. Beachten Sie die Änderung in den Definitionen der
init
undcleanup
Funktionen. Das__init
Makro bewirkt, dass dieinit
Funktion verworfen und ihr Speicher freigegeben wird, sobald dieinit
Funktion für integrierte Treiber, jedoch nicht für ladbare Module beendet ist. Wenn Sie darüber nachdenken, wann dieinit
Funktion aufgerufen wird, ist dies absolut sinnvoll.Quelle
quelle
__init ist ein in ./include/linux/init.h definiertes Makro, das auf erweitert wird
__attribute__ ((__section__(".init.text")))
.Es weist den Compiler an, diese Funktion auf besondere Weise zu markieren. Am Ende sammelt der Linker alle Funktionen mit dieser Markierung am Ende (oder Anfang) der Binärdatei. Wenn der Kernel gestartet wird, wird dieser Code nur einmal ausgeführt (Initialisierung). Nachdem es ausgeführt wurde, kann der Kernel diesen Speicher freigeben, um ihn wiederzuverwenden, und Sie sehen den Kernel
quelle
Lesen Kommentar (und Dokumente zur gleichen Zeit) in linux / init.h .
Sie sollten auch wissen, dass gcc einige Erweiterungen hat, die speziell für Linux-Kernel-Code erstellt wurden, und es sieht so aus, als ob dieses Makro eine davon verwendet.
quelle
Wenn Sie ein Linux-Kernelmodul kompilieren und in den Kernel einfügen, ist die erste auszuführende Funktion __init. Diese Funktion wird im Wesentlichen verwendet, um die Initialisierung durchzuführen, bevor Sie die Hauptoperationen wie das Registrieren eines Gerätetreibers usw. ausführen. Es gibt eine andere Funktion mit dem gegenteiligen Effekt __exit, das aufgerufen wird, wenn Sie das Kernelmodul entfernen, mit dem erneut ein registriertes Gerät oder eine ähnliche Funktion entfernt wird
quelle