Que signifie __init dans le code du noyau Linux?


91

Dans le code source du noyau Linux, j'ai trouvé cette fonction:

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

Ici, je ne peux pas comprendre ce que __initsignifie.

Réponses:


76

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)

55

Ce ne sont que des macros pour localiser certaines parties du code linux dans des zones spéciales du binaire final en cours d'exécution. __init, par exemple (ou mieux la __attribute__ ((__section__ (".init.text")))macro se développe) indique au compilateur de marquer cette fonction d'une manière spéciale. À la fin, l'éditeur de liens rassemble toutes les fonctions avec cette marque à la fin (ou au début) du fichier binaire.

Au démarrage du noyau, ce code ne s'exécute qu'une seule fois (initialisation). Après son exécution, le noyau peut libérer cette mémoire pour la réutiliser et vous verrez le message du noyau:

Libération de la mémoire du noyau inutilisée: 108 Ko libérés

Pour utiliser cette fonctionnalité, vous avez besoin d'un fichier de script de l'éditeur de liens spécial, qui indique à l'éditeur de liens où localiser toutes les fonctions marquées.


11
Intelligent! C'est donc ce que signifiait "Libérer la mémoire du noyau inutilisée: 108k libérés". :-) Je me suis en quelque sorte demandé toutes ces années. J'ai supposé que c'était une sorte de tampons ou quelque chose, pas du code.
Prof.Falken

6

Cela démontre une fonctionnalité du noyau 2.2 et supérieur. Notez le changement dans les définitions des fonctions initet cleanup. La __initmacro entraîne la suppression de la initfonction et la libération de sa mémoire une fois la initfonction terminée pour les pilotes intégrés, mais pas les modules chargeables. Si vous pensez au moment où la initfonction est appelée, cela est parfaitement logique.

la source


5

__init est une macro définie dans ./include/linux/init.h qui se développe en __attribute__ ((__section__(".init.text"))).

Il demande au compilateur de marquer cette fonction d'une manière spéciale. À la fin, l'éditeur de liens rassemble toutes les fonctions avec cette marque à la fin (ou au début) du fichier binaire. Au démarrage du noyau, ce code ne s'exécute qu'une seule fois (initialisation). Après son exécution, le noyau peut libérer cette mémoire pour la réutiliser et vous verrez le noyau


3

Lire un commentaire (et docs en même temps) dans linux / init.h .

Vous devez également savoir que gcc a des extensions spécialement conçues pour le code du noyau Linux et il semble que cette macro utilise l'une d'entre elles.


1

Lorsque vous compilez et insérez un module de noyau Linux dans le noyau, la première fonction à être exécutée est __init.Cette fonction est essentiellement utilisée pour effectuer l'initialisation avant d'effectuer les opérations principales comme l'enregistrement d'un pilote de périphérique, etc.Il existe une autre fonction avec l'effet inverse __exit qui est appelé lorsque vous supprimez le module du noyau qui est à nouveau utilisé pour supprimer un périphérique enregistré ou une fonction similaire

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.