Avant de nous plonger dans la définition d'un appel du système Linux et d'examiner les détails de son exécution, il est préférable de commencer par définir les différentes couches logicielles d'un système Linux typique.
Le noyau Linux est un programme spécialisé qui bottise et fonctionne au niveau le plus bas disponible sur votre matériel. Il a la tâche d'orchestrer tout ce qui s'exécute sur l'ordinateur, y compris la gestion des événements de clavier, de disque et de réseau pour fournir des tranches de temps pour exécuter plusieurs programmes en parallèle.
Lorsque le noyau exécute un programme de niveau utilisateur, il virtualise l'espace mémoire afin que les programmes pensent qu'ils sont le seul processus en cours de mémoire. Cette bulle protectrice d'isolement matériel et logiciel augmente la sécurité et la fiabilité. Une application non privilégiée ne peut pas accéder à la mémoire appartenant à d'autres programmes, et si ce programme se bloque, le noyau se termine afin qu'il ne puisse pas nuire au reste du système.
Breecher la barrière avec les appels du système Linux
Cette couche d'isolement entre les applications non privilégiées fournit une excellente limite pour protéger d'autres applications et utilisateurs sur le système. Cependant, sans un moyen d'interfacer avec les autres éléments de l'ordinateur et du monde extérieur, les programmes ne pourraient pas accomplir beaucoup de rien.
Pour faciliter l'interaction, le noyau désigne une porte logicielle qui permet au programme d'exécution de demander que le noyau agisse en son nom. Cette interface est connue comme un appel système.
Puisque Linux suit la philosophie UNIX de «Tout est un fichier», de nombreuses fonctions peuvent être exécutées en ouvrant et en lisant ou en écrivant dans un fichier, qui pourrait être un appareil. Sur Windows, par exemple, vous pouvez utiliser une fonction appelée cryptgenrandom pour accéder aux octets aléatoires. Mais sur Linux, cela peut être fait en ouvrant simplement le «fichier» / dev / urandom et la lecture d'octets à partir de celui-ci en utilisant les appels du système d'entrée / sortie de fichier standard. Cette différence cruciale permet une interface d'appel système plus simple.
Emballage mince de la plaquette
Dans la plupart des applications, les appels système ne sont pas directement effectués sur le noyau. Pratiquement tous les programmes sont liés à la bibliothèque standard C, qui fournit un wrapper mince mais important autour des appels système Linux. La bibliothèque s'assure que les arguments de fonction sont copiés dans les registres du processeur corrects, puis publie l'appel système Linux correspondant. Lorsque les données sont reçues de l'appel, l'emballage interprète les résultats et les renvoie au programme de manière cohérente.
Dans les coulisses
Chaque fonction d'un programme qui interagit avec le système est finalement traduit par un appel système. Pour voir cela en action, commençons par un exemple de base.
void main ()C'est probablement le programme C le plus trivial que vous verrez jamais. Il gagne simplement le contrôle via le point d'entrée principal puis sort. Il ne renvoie même pas une valeur car le main est défini comme vide. Enregistrez le fichier en tant que CTEST.C et compilons-le:
gcc ctest.c -o ctestUne fois qu'il est compilé, nous pouvons voir la taille du fichier comme 8664 octets. Il peut varier légèrement sur votre système, mais il devrait être d'environ 8k. C'est beaucoup de code juste pour entrer et sortir! La raison pour laquelle il est 8K est que l'exécution de la LIBC est incluse. Même si nous supprimons les symboles, c'est toujours un peu plus de 6k.
Dans un exemple encore plus simple, nous pouvons faire sortir l'appel du système Linux plutôt que de dépendre de l'exécution C pour ce faire pour nous.
void _start ()Ici, nous nous déplaçons 1 dans le registre EAX, effacez le registre EBX (qui contiendrait autrement la valeur de retour) puis appelez l'interruption d'appel du système Linux 0x80 (ou 128 en décimal). Cette interruption déclenche le noyau pour traiter notre appel.
Si nous compilons notre nouvel exemple, appelé asmtest.C, et éliminer les symboles et exclure la bibliothèque standard:
gcc -s -Nostdlib asmtest.c -o asmtestNous produirons un binaire moins de 1k (sur mon système, il donne 984 octets). La plupart de ce code sont des en-têtes exécutables. Nous appelons maintenant l'appel système Direct Linux.
À toutes fins pratiques
Dans presque tous les cas, vous n'aurez jamais à passer des appels système directs dans vos programmes C. Si vous utilisez le langage d'assemblage, cependant, le besoin peut survenir. Cependant, dans l'optimisation, il serait préférable de permettre aux fonctions de la bibliothèque C de passer les appels du système et d'avoir uniquement votre code critique intégré dans les directives d'assemblage.
Si vous souhaitez voir une liste de tous les appels système disponibles pour Linux, vous pouvez vérifier ces pages de référence: Liste complète des appels système sur Linuxhint.com, Filippo.IO / Linux-Syscall-Table / et ou Syscalls.kernel.com