J'essaie de comprendre comment une fonction, disons mkdir
, fonctionne en regardant la source du noyau. Ceci est une tentative de comprendre les éléments internes du noyau et de naviguer entre différentes fonctions. Je sais mkdir
est défini dans sys/stat.h
. J'ai trouvé le prototype:
/* Create a new directory named PATH, with permission bits MODE. */
extern int mkdir (__const char *__path, __mode_t __mode)
__THROW __nonnull ((1));
Maintenant, j'ai besoin de voir dans quel fichier C cette fonction est implémentée. Depuis le répertoire source, j'ai essayé
ack "int mkdir"
qui a affiché
security/inode.c
103:static int mkdir(struct inode *dir, struct dentry *dentry, int mode)
tools/perf/util/util.c
4:int mkdir_p(char *path, mode_t mode)
tools/perf/util/util.h
259:int mkdir_p(char *path, mode_t mode);
Mais aucun d’entre eux ne correspond à la définition de sys/stat.h
.
Des questions
- Quel fichier a l'
mkdir
implémentation? - Avec une définition de fonction comme ci-dessus, comment puis-je savoir quel fichier est implémenté? Le noyau utilise-t-il un modèle pour définir et mettre en œuvre des méthodes?
NOTE: J'utilise le noyau 2.6.36-rc1 .
linux-kernel
source
system-calls
Navaneeth KN
la source
la source
Réponses:
Les appels système ne sont pas traités comme des appels de fonction normaux. Il faut un code spécial pour passer de l’espace utilisateur à l’espace noyau, c’est-à-dire un peu de code d’assemblage en ligne injecté dans votre programme sur le site d’appel. Le code du noyau qui "intercepte" l'appel système est également un élément de bas niveau que vous n'avez probablement pas besoin de comprendre en profondeur, du moins au début.
Dans
include/linux/syscalls.h
le répertoire source de votre noyau, vous trouvez ceci:Ensuite
/usr/include/asm*/unistd.h
, vous trouvez ceci:Ce code dit qu'il
mkdir(2)
s'agit de l'appel système n ° 83. C'est-à-dire que les appels système sont appelés par numéro, pas par adresse comme avec un appel de fonction normal dans votre propre programme ou vers une fonction dans une bibliothèque liée à votre programme. Le code de collage d'assemblage en ligne que j'ai mentionné ci-dessus l'utilise pour effectuer la transition de l'espace utilisateur vers l'espace noyau, en prenant en compte vos paramètres.Une autre preuve que les choses sont un peu bizarres ici est qu’il n’existe pas toujours de liste de paramètres stricte pour les appels système:
open(2)
par exemple, elle peut prendre 2 ou 3 paramètres. Cela signifieopen(2)
est surchargé , une caractéristique de C ++, C pas, mais l'interface syscall est C-compatible. (Ce n'est pas la même chose que la fonction varargs de C , qui permet à une seule fonction de prendre un nombre variable d'arguments.)Pour répondre à votre première question, il n’existe pas de fichier unique
mkdir()
. Linux supporte de nombreux systèmes de fichiers différents et chacun a sa propre implémentation de l'opération "mkdir". La couche d'abstraction qui permet au noyau de masquer tout ce qui se cache derrière un seul appel système s'appelle VFS . Donc, vous voulez probablement commencer à creuserfs/namei.c
, avecvfs_mkdir()
. Les implémentations réelles du code modifiant le système de fichiers de bas niveau sont ailleurs. Par exemple, l'implémentation ext4 est appeléeext4_mkdir()
, définie dansfs/ext4/namei.c
.En ce qui concerne votre deuxième question, oui, il y a des tendances à tout cela, mais pas une seule règle. Ce dont vous avez réellement besoin est une compréhension assez large du fonctionnement du noyau afin de déterminer où rechercher un appel système particulier. Tous les appels système n’impliquent pas le système VFS. Par conséquent, leurs chaînes d’appel côté noyau ne démarrent pas
fs/namei.c
.mmap(2)
, par exemple, commence parmm/mmap.c
, car il fait partie du sous-système de gestion de la mémoire ("mm") du noyau.Je vous recommande de vous procurer une copie de " Comprendre le noyau Linux " de Bovet et Cesati.
la source
Documentation
sous - répertoire de l'arbre source du noyau avec lequel je travaille....
fonction Varargs. Bien sûr, cela est implémenté au niveau de la libc. Il se peut que la valeur ABI du noyau soit transmise à 0 ou à une valeur résiduelle lorsque le troisième paramètre n'est pas utilisé.Cela ne répond probablement pas directement à votre question, mais j’ai trouvé
strace
très bon d’essayer de comprendre les appels système sous-jacents, en action, conçus pour les commandes shell les plus simples. par exempleLes appels système de la commande
mkdir mynewdir
seront sauvegardés dans trace.txt pour votre plus grand plaisir.la source
La référence croisée Linux (LXR) ¹ est un bon endroit pour lire la source du noyau Linux . Les recherches renvoient des résultats typés (prototypes de fonctions, déclarations de variables, etc.) en plus des résultats de recherche de texte libre, ce qui est plus pratique qu'un simple grep (et plus rapide également).
LXR ne développe pas les définitions du préprocesseur. Les appels système ont leur nom mutilé par le préprocesseur. Cependant, la plupart des appels système (tous?) Sont définis avec l'une des
SYSCALL_DEFINEx
familles de macros. Puisquemkdir
prend deux arguments, une recherche deSYSCALL_DEFINE2(mkdir
conduit à la déclaration dumkdir
syscall :ok,
sys_mkdirat
ça veut dire que c'est l'mkdirat
appel système, donc cliquer dessus ne conduit qu'à la déclarationinclude/linux/syscalls.h
, mais la définition est juste au dessus.Le travail principal de
mkdirat
est d'appelervfs_mkdir
(VFS est la couche de système de fichiers générique). En cliquant dessus, vous obtenez deux résultats de recherche: la déclaration dansinclude/linux/fs.h
et la définition quelques lignes plus haut. Le travail principalvfs_mkdir
est d'appeler la mise en œuvre spécifique au système de fichiers:dir->i_op->mkdir
. Pour savoir comment cela est implémenté, vous devez passer à l'implémentation du système de fichiers individuel, et il n'y a pas de règle absolue - il pourrait même s'agir d'un module situé en dehors de l'arborescence du noyau.¹ LXR est un programme d'indexation. Plusieurs sites Web fournissent une interface à LXR, avec des ensembles de versions connues légèrement différentes et des interfaces Web légèrement différentes. Ils ont tendance à aller et venir, alors si celui auquel vous êtes habitué n’est pas disponible, lancez une recherche Web sur «référence croisée Linux» pour en trouver une autre.
la source
Les appels système sont généralement intégrés à la
SYSCALL_DEFINEx()
macro. C'est pourquoi un simplegrep
ne les trouve pas:Le nom de la fonction finale après la macro est étendue finit par être
sys_mkdir
. LaSYSCALL_DEFINEx()
macro ajoute des éléments standard, tels que le code de traçage, nécessaires à chaque définition d'appel système.la source
Remarque: le fichier .h ne définit pas la fonction. Il est déclaré dans ce fichier .h et défini (implémenté) ailleurs. Cela permet au compilateur d'inclure des informations sur la signature de la fonction (prototype) afin de permettre la vérification du type des arguments et de faire correspondre les types de retour à tous les contextes d'appel de votre code.
En général, les fichiers .h (en-tête) en C sont utilisés pour déclarer des fonctions et définir des macros.
mkdir
en particulier est un appel système. Il peut y avoir un wrapper GNU libc autour de cet appel système (presque certainement, en fait). La véritable implémentation du noyau demkdir
peut être trouvée en recherchant les sources du noyau et les appels système en particulier.Notez qu'il y aura également une implémentation d'une sorte de code de création de répertoire pour chaque système de fichiers. La couche VFS (système de fichiers virtuel) fournit une API commune à laquelle la couche d'appels système peut appeler. Chaque système de fichiers doit enregistrer des fonctions pour que la couche VFS appelle. Cela permet à différents systèmes de fichiers d'implémenter leur propre sémantique pour la structure des répertoires (par exemple, s'ils sont stockés à l'aide d'une sorte de schéma de hachage pour rendre plus efficace la recherche d'entrées spécifiques). Je le mentionne parce que vous risquez de trébucher sur ces fonctions de création de répertoires spécifiques au système de fichiers si vous effectuez une recherche dans l’arborescence des sources du noyau Linux.
la source
Aucune des implémentations que vous avez trouvées ne correspond au prototype dans sys / stat.h Peut-être que la recherche d'une instruction include avec ce fichier d'en-tête aurait plus de succès?
la source
Voici quelques articles de blog décrivant diverses techniques permettant de rechercher le code source du noyau de bas niveau.
la source