Niveau :
Résumé : syscall
Qu'est-ce qu'un appel système ?
Prenons le code suivant :
fopen("/tmp/toto", "r");
Ceci est simplement un appel de fonction, fonction écrite dans la libc et donc disponible à tout bon programme écrit en C (notez que le manuel de fopen est dans la section 3)
Prenons ensuite le code suivant :
open("/tmp/toto", O_RDONLY);
Ceci vous semble aussi être un appel de fonction comme les autres. Hé bien vous avez presque raison. En fait cette fonction est dans la libc, mais celle-ci ne fait que rediriger l'appel vers une fonction du noyau. C'est un appel système (syscall), notez cette fois que le manuel de open est dans la section 2.
Quels sont-ils ?
Il existe un grand nombre d'appels système. Tous sont numérotés, et ce numéro ne peut pas changer, en effet, le changer reviendrait à casser tous les binaires fonctionnant sous linux. Par contre, il arrive de temps en temps qu'un appel système soit ajouté, mais ce genre de chose est toujours étudié en profondeur, car cela signifie qu'il devra être maintenu à vie par les développeurs du noyau. C'est ce qu'on appelle l'API stable du noyau.
Parmi les appels système, on trouve de tout, enfin tout ce qui est du ressort du noyau. Vous pourrez en trouver la liste dans les sources. Toutes les fonctions concernant le système de fichiers, le réseau, les droits, les utilisateurs ou les processus se retrouvent ici.
Comment ça marche ?
L'implémentation d'un appel système dépend complètement du processeur. En effet, il faut une instruction qui offre quelques garanties au noyau pour permettre son bon fonctionnement.
Ces garanties sont des privilèges particuliers accordés au code au code appelé. Par exemple, le code appelé peut avoir des droits d'accès au matériel et il ne peut pas être modifié par le code appelant.
Intéressons-nous à des processeurs assez répandus, les x86. L'instruction qui nous intéresse est l'interruption (int). Linux a choisi l'interruption 80 pour mettre en place ses appels système. Mais tout ceci est caché par la libc qui fait elle-même l'appel. Mais l'instruction int est infiniment lente et Intel a décidé de fournir une autre instruction du même style, en plus rapide (sysenter). Il fallait donc une méthode pour que linux utilise cette nouvelle instruction sans pour autant casser les logiciels existants.
Linus a choisi de permettre les appels système sans avoir à se se poser la question de la méthode à utiliser. Depuis linux 2.5, tous les processus disposent d'une page spéciale créée par le noyau contenant le code pour faire l'appel système. Et c'est lui qui choisi la meilleure méthode disponible. On appelle cette page la VDSO (Virtual Dynamically-linked Shared Object). C'est elle que vous voyez lorsque vous faites un ldd sur un exécutable et qu'il contient l'une de ces lignes :
linux-gate.so.1 => (0xffffe000)
linux-vdso.so.1 => (0x00007fffa6dfe000)
PS : int 80 reste disponible sur toutes les version de linux
PPS : fopen fait appel à open en interne
PPPS : pour mémoire dos avait choisi l'interruption 21 pour ses propres fonctions
Comments