2017-08-07 13 views
2

Je vois le code suivant dans certains noyaux OS. Mais je ne comprends pas la façon dont __section est utilisé, et je ne sais pas ce que signifie ce code.Que signifie __section() dans la source du noyau Linux

#define KEEP_PAGER(sym) \ 
    extern const unsigned long ____keep_pager_##sym; \ 
    const unsigned long ____keep_pager_##sym \ 
     __section("__keep_meta_vars_pager") = (unsigned long)&sym 
+0

Avez-vous essayé * de le rechercher * dans le code, pour voir s'il est déclaré ou défini quelque part? –

+2

Merci, comprenez. Il est défini dans un autre #define. Je me promenais pourquoi il n'est pas enfermé avec attribut. Et je trouve enfin #define suivante: '#define __section (x) \t __attribute __ ((section (x)))' –

Répondre

3

Son noyau linux spécifique C macro definition entoure un GCC extension, en spécifiant un atttribute to use for an object. Il est une façon d'écrire plus court la section définition d'attribut

Historiquement le noyau Linux a été written specifically for building with the GCC compiler, et fait largement appel à des extensions de bas niveau pour effectuer des opérations matérielles spécifiques et OPTIMISATIONS.

L'attribut section est utilisé spécifiquement pour déterminer l'emplacement de stockage de l'objet étiqueté avec elle. ELF binary format organise le fichier objet en sections nommées, et en utilisant l'attribut comme ceci permet au programmeur de spécifier plus précisément où les informations pour l'objet étiqueté seront placées dans l'objet cible

Au fil des ans, il y a eu du travail pour augmenter la compatibilité de ces extensions de compilateur entre différents compilateurs, ainsi que rendre Linux compilable avec des compilateurs alternatifs (si vous regardez the linux header file where the macro is defined vous verrez qu'il est plein de directives conditionnelles pour diverses fonctionnalités du compilateur). Les macros comme celle-ci peuvent être un moyen utile d'avoir une API interne portable pour les fonctionnalités de bas niveau à travers différentes implémentations de compilateurs. Le code C du pilote du noyau et du noyau est atypiquement concerné par les spécificités directes de l'implémentation matérielle physique, et doit être explicite sur la sortie binaire du compilateur d'une manière que le code C au niveau de l'application le fera rarement. Un exemple de la raison pour laquelle le noyau Linux utilise des sections nommées est le init handling - les fonctions et les données qui sont utilisées uniquement pendant le démarrage sont regroupées dans une section de mémoire qui peut être facilement libérée une fois le démarrage terminé - vous connaissez peut-être le message de démarrage suivant la 'libération de la mémoire noyau non utilisée: ...' vers la fin de la séquence de démarrage Linux

+1

oui, c'est en effet un attribut de macro emballage, je vais développer cette explication – cms

+0

Ce serait pourquoi inventer votre propre langage macro maison-brewn est une mauvaise idée. Cette macro est simplement naïve, car certains autres compilateurs peuvent utiliser des choses comme '# pragma' pour les sections de mémoire, auquel cas cette macro ne fonctionnera pas. Linux ne travaillera jamais sur un autre compilateur que GCC de toute façon, il y a juste trop de confiance dans les fonctionnalités spécifiques au compilateur. – Lundin

0

Il est difficile de dire ce que __section est exactement sans sa définition, mais il pourrait attribut « section » une variable. Il est utilisé pour faire du compilateur place variable dans une section différente de "bss" ou "données". Voir GCC documentation pour plus de détails.