Was bedeutet __init im Linux-Kernel-Code?

Lesezeit: 3 Minuten

Benutzeravatar von Jeegar Patel
Jeegar Patel

Im Linux-Kernel-Quellcode habe ich diese Funktion gefunden:

static int __init clk_disable_unused(void) 
{
   // some code
}

Hier kann ich nicht verstehen, was tut __init meint.

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)

Benutzeravatar von sashoalm
sashoalm

Dies sind nur Makros, um einige Teile des Linux-Codes in speziellen Bereichen in der endgültig ausgeführten Binärdatei zu lokalisieren.
__initzum Beispiel (oder besser die __attribute__ ((__section__
(".init.text")))
dieses Makro erweitert zu) 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.

Beim Start des Kernels 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 die Kernel-Nachricht:

Ungenutzten Kernel-Speicher freigeben: 108 KB freigegeben

Um diese Funktion nutzen zu können, benötigen Sie eine spezielle Linker-Skriptdatei, die dem Linker mitteilt, wo er alle markierten Funktionen finden kann.

  • Clever! Das bedeutete also „Unbenutzten Kernel-Speicher freigeben: 108 KB freigegeben“. 🙂 Das habe ich mich all die Jahre irgendwie gefragt. Ich nahm an, dass es sich um eine Art Puffer oder so etwas handelte, nicht um Code.

    – Prof. Falken

    12. Januar 2012 um 9:09 Uhr

Benutzeravatar von naveen kumar r
Naveen Kumar R

Dies demonstriert eine Funktion von Kernel 2.2 und höher. Beachten Sie die Änderung in den Definitionen von init und cleanup Funktionen. Das __init Makro verursacht die init Funktion verworfen und ihr Speicher freigegeben werden, sobald die init Funktion endet für eingebaute Treiber, aber nicht für ladbare Module. Wenn Sie darüber nachdenken, wann die init Funktion aufgerufen wird, macht dies durchaus Sinn.

Quelle

__init ist ein Makro, das in ./include/linux/init.h definiert ist und zu 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. Beim Start des Kernels wird dieser Code nur einmal ausgeführt (Initialisierung). Nach der Ausführung kann der Kernel diesen Speicher freigeben, um ihn wiederzuverwenden, und Sie sehen den Kernel

Benutzeravatar von elmo
elmo

Lesen Sie den Kommentar (und die Dokumente gleichzeitig) 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.

Benutzeravatar von Nnaik
Nnaik

Wenn Sie ein Linux-Kernel-Modul 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, das wiederum zum Entfernen eines registrierten Geräts oder einer ähnlichen Funktion verwendet wird

1421470cookie-checkWas bedeutet __init im Linux-Kernel-Code?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy