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:
asmlinkage long sys_mkdir(const char __user *pathname, int mode);
Ensuite /usr/include/asm*/unistd.h
, vous trouvez ceci:
#define __NR_mkdir 83
__SYSCALL(__NR_mkdir, sys_mkdir)
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 signifie open(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 à creuser fs/namei.c
, avec vfs_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ée ext4_mkdir()
, définie dans fs/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 par mm/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.