Cosa significa __init nel codice del kernel di Linux?

Nel codice sorgente del kernel di Linux ho trovato questa funzione:

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

Qui non riesco a capire cosa significa __init .

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, eg: * * static int init_variable __initdata = 0; * static const char linux_logo[] __initconst = { 0x32, 0x36, ... }; * * Don't forget to initialize data not at file scope, ie 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) 

Queste sono solo macro per localizzare alcune parti del codice linux in aree speciali nel binario dell’esecuzione finale. __init , ad esempio (o meglio l’ __attribute__ ((__section__ (".init.text"))) questa macro si espande) ordina al compilatore di contrassegnare questa funzione in un modo speciale. Alla fine il linker raccoglie tutte le funzioni con questo segno alla fine (o inizio) del file binario.

All’avvio del kernel, questo codice viene eseguito una sola volta (inizializzazione). Dopo l’esecuzione, il kernel può liberare questa memoria per riutilizzarla e vedrai il messaggio del kernel:

Liberare memoria del kernel inutilizzata: 108k liberati

Per utilizzare questa funzione, è necessario un file di script linker speciale, che indica al linker dove posizionare tutte le funzioni contrassegnate.

__init è una macro definita in ./include/linux/init.h che si espande in __attribute__ ((__section__(".init.text"))) .

Indica al compilatore di contrassegnare questa funzione in un modo speciale. Alla fine il linker raccoglie tutte le funzioni con questo segno alla fine (o inizio) del file binario. All’avvio del kernel, questo codice viene eseguito una sola volta (inizializzazione). Dopo l’esecuzione, il kernel può liberare questa memoria per riutilizzarla e vedrai il kernel

Questo dimostra una funzionalità del kernel 2.2 e successivi. Si noti la modifica delle definizioni delle funzioni init e cleanup . La macro __init fa sì che la funzione init venga scartata e la sua memoria liberata una volta che la funzione init termina per i driver incorporati, ma non per i moduli caricabili. Se pensi a quando viene invocata la funzione init , questo ha perfettamente senso.

fonte

Leggi commenti (e documenti allo stesso tempo) in linux / ini.h.

Dovresti anche sapere che gcc ha alcune estensioni create appositamente per il codice del kernel di Linux e sembra che questa macro ne usi una.