Im Quellcode des Linux-Kernels habe ich diese Funktion gefunden:
static int __init clk_disable_unused(void)
{
// some code
}
Hier kann ich nicht verstehen, was die __init
bedeutet.
Im Quellcode des Linux-Kernels habe ich diese Funktion gefunden:
static int __init clk_disable_unused(void)
{
// some code
}
Hier kann ich nicht verstehen, was die __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 spezielle Bereiche in der endgültigen Binärdatei zu platzieren. __init
zum Beispiel (oder besser die __attribute__ ((__section__ (".init.text")))
Dieses Makro expandiert 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 er ausgeführt wurde, kann der Kernel diesen Speicher wieder freigeben, um ihn wieder zu verwenden, und Sie sehen die Kernel Meldung:
Freigeben von unbenutztem Kernel-Speicher: 108k freigegeben
Um diese Funktion zu nutzen, benötigen Sie eine spezielle Linker-Skriptdatei, die dem Linker mitteilt, wo alle markierten Funktionen zu finden sind.
Dies demonstriert eine Funktion von Kernel 2.2 und höher. Beachten Sie die Änderung in den Definitionen der init
y cleanup
Funktionen. Die Website __init
Makro bewirkt, dass die init
Funktion verworfen und ihr Speicher freigegeben werden, sobald die init
Funktion wird für eingebaute Treiber beendet, nicht aber für ladbare Module. Wenn Sie darüber nachdenken, wann die init
Funktion aufgerufen wird, ist dies durchaus sinnvoll.
__init ist ein in ./include/linux/init.h definiertes Makro, das sich zu __attribute__ ((__section__(".init.text")))
.
Er weist den Compiler an, diese Funktion in besonderer Weise zu kennzeichnen. Am Ende sammelt der Linker alle Funktionen mit dieser Markierung am Ende (oder Anfang) der Binärdatei. Wenn der Kernel startet, wird dieser Code nur einmal ausgeführt (Initialisierung). Danach kann der Kernel diesen Speicher wieder freigeben, um ihn wieder zu verwenden, und Sie werden sehen, dass der Kernel
Kommentar (und Dokumente gleichzeitig) lesen in linux/init.h .
Sie sollten auch wissen, dass gcc hat einige Erweiterungen speziell für Linux-Kernel-Code gemacht und es sieht aus wie dieses Makro verwendet eine von ihnen.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.