Introduction aux appels système
Les appels système fournissent une interface aux services mis à disposition par un système d'exploitation. Un appel système est une méthode permettant à un programme informatique de demander un service au noyau du système d'exploitation sur lequel il s'exécute.
Ces appels sont généralement disponibles sous forme de fonctions écrites en C et C++, bien que certaines tâches de bas niveau (par exemple, les tâches où le matériel doit être accessible directement) puissent être écrites à l'aide d'instructions en langage assembleur.
Les systèmes exécutent des milliers d'appels système par seconde. Cependant, la plupart des programmeurs ne voient jamais ce niveau de détail.
API et appels système
En règle générale, les développeurs d'applications conçoivent des programmes selon une interface de programmation d'application (API). L'API spécifie un ensemble de fonctions disponibles pour un programmeur d'application, y compris les paramètres transmis à chaque fonction et les valeurs de retour auxquelles le programmeur peut s'attendre.
| API | Systèmes | Bibliothèque |
|---|---|---|
| API Windows | Systèmes Windows | Windows API |
| API POSIX | UNIX, Linux, macOS | libc (pour C) |
| API Java | Machine virtuelle Java (JVM) | Bibliothèques Java |
Un programmeur accède à une API via une bibliothèque de code fournie par le système d'exploitation. Dans le cas d'UNIX et de Linux pour les programmes écrits en langage C, la bibliothèque s'appelle libc.
Relation entre API et appels système
Dans les coulisses, les fonctions qui composent une API invoquent généralement les appels système réels au nom du programmeur d'application. Par exemple :
- La fonction Windows CreateProcess() (utilisée pour créer un nouveau processus) invoque en fait l'appel système NTCreateProcess() dans le noyau Windows.
- La fonction POSIX fork() invoque l'appel système correspondant dans le noyau Linux/UNIX.
Programme applicatif
│
▼
[ API ] ← Interface de programmation (ex: CreateProcess, fork)
│
▼
[ Bibliothèque ] ← Libc, bibliothèques systèmes
│
▼
[ Interface d'appel système ] ← Gère les numéros d'appels
│
▼
[ Noyau ] ← Exécute l'appel système réel
Figure : Hiérarchie entre application, API et noyau
L'environnement d'exécution (RTE)
L'environnement d'exécution (RTE) est la suite complète de logiciels nécessaire pour exécuter des applications écrites dans un langage de programmation donné, y compris ses compilateurs ou interpréteurs ainsi que d'autres logiciels, tels que des bibliothèques et des chargeurs (loaders).
Le RTE fournit une interface d'appel système qui sert de lien vers les appels système mis à disposition par le système d'exploitation. L'interface d'appel système intercepte les appels de fonction dans l'API et invoque les appels système nécessaires dans le système d'exploitation.
Numéros d'appels système
Typiquement, un numéro est associé à chaque appel système, et l'interface d'appel système maintient une table indexée selon ces numéros. L'interface d'appel système invoque ensuite l'appel système prévu dans le noyau du système d'exploitation et renvoie l'état de l'appel système.
; Les appels système sont identifiés par des numéros
; /usr/include/asm/unistd_64.h
#define __NR_read 0 ; Numéro pour read
#define __NR_write 1 ; Numéro pour write
#define __NR_open 2 ; Numéro pour open
#define __NR_close 3 ; Numéro pour close
#define __NR_fork 57 ; Numéro pour fork
#define __NR_execve 59 ; Numéro pour execve
#define __NR_exit 60 ; Numéro pour exit
#define __NR_getpid 39 ; Numéro pour getpidL'appelant n'a besoin de rien savoir de la façon dont l'appel système est implémenté ou de ce qu'il fait pendant l'exécution. Au lieu de cela, l'appelant n'a qu'à obéir à l'API et à comprendre ce que le système d'exploitation fera à la suite de l'exécution de cet appel système.
Passage des paramètres aux appels système
Les appels système se produisent de différentes manières, selon l'ordinateur utilisé. Souvent, plus d'informations sont nécessaires que simplement l'identité de l'appel système souhaité.

Figure : Trois méthodes générales pour passer des paramètres au système d'exploitation
Les trois méthodes principales
Passage par registres
L'approche la plus simple consiste à passer les paramètres dans des registres du processeur.
Avantage : Rapide et simple.
Inconvénient : Limité par le nombre de registres disponibles.
Passage par bloc mémoire
Les paramètres sont stockés dans un bloc ou une table en mémoire, et l'adresse du bloc est passée dans un registre.
Avantage : Pas de limitation sur le nombre de paramètres.
Inconvénient : Nécessite un accès mémoire supplémentaire.
Passage par pile
Les paramètres sont placés ou poussés sur une pile par le programme et retirés de la pile par le système d'exploitation.
Avantage : Flexible et sans limitation de taille.
Inconvénient : Gestion de pile plus complexe.
Cas particulier de Linux
Linux utilise une combinaison de ces approches :
- S'il y a cinq paramètres ou moins, des registres sont utilisés.
- S'il y a plus de cinq paramètres, la méthode des blocs est utilisée.
Certains systèmes d'exploitation préfèrent la méthode du bloc ou de la pile car ces approches ne limitent pas le nombre ou la longueur des paramètres transmis.
Exemple concret sous Linux x86-64
// En C, l'appel système write
ssize_t write(int fd, const void *buf, size_t count);; En assembleur x86-64, les paramètres sont passés dans des registres
; rax = numéro de l'appel système (1 pour write)
; rdi = premier paramètre (fd - descripteur de fichier)
; rsi = deuxième paramètre (buf - pointeur vers le tampon)
; rdx = troisième paramètre (count - nombre d'octets)
mov rax, 1 ; numéro de l'appel système write
mov rdi, 1 ; fd = 1 (stdout)
mov rsi, msg ; buf = adresse du message
mov rdx, 14 ; count = 14 octets
syscall ; déclenche l'appel systèmeProcessus complet d'un appel système
- Programme applicatif appelle une fonction de l'API (ex:
read()). - La bibliothèque (libc) prépare les paramètres et place le numéro de l'appel système.
- L'interface d'appel système exécute une instruction spéciale (
syscallouint 0x80). - Le processeur passe en mode noyau.
- Le gestionnaire d'appels système dans le noyau examine le numéro et aiguille vers la fonction correspondante.
- La fonction noyau exécute le service demandé.
- Le résultat est retourné au programme utilisateur via les registres.
- Le processeur repasse en mode utilisateur.
- L'application reçoit la valeur de retour de l'appel.
Les six catégories d'appels système
Les appels système peuvent être regroupés en six catégories principales :
| Catégorie | Description | Exemples |
|---|---|---|
| Contrôle de processus | Gestion des processus (création, terminaison, attente) | fork(), exit(), wait(), exec() |
| Gestion de fichiers | Manipulation de fichiers et répertoires | open(), read(), write(), close() |
| Gestion de périphériques | Contrôle des périphériques matériels | ioctl(), read(), write() sur /dev/* |
| Maintenance des informations | Obtention d'informations système | time(), getpid(), uname() |
| Communications | Communication entre processus | pipe(), shmget(), socket() |
| Protection | Gestion des permissions et sécurité | chmod(), chown(), umask() |
Traçage d'appels système
Sous Linux, on peut utiliser la commande strace pour tracer les appels système effectués par un programme.
Considérons le programme C suivant :
#include <stdio.h>
#include <unistd.h>
int main() {
printf("Bonjour, monde!\n");
int pid = getpid();
printf("Mon PID est %d\n", pid);
FILE* f = fopen("test.txt", "w");
if (f) {
fprintf(f, "Test d'écriture\n");
fclose(f);
}
return 0;
}Questions :
- Quels appels système seront probablement invoqués par ce programme ?
- Pour chaque appel identifié, à quelle catégorie appartient-il ?
- Comment les paramètres sont-ils transmis pour l'appel
write()? - Quel est le rôle de la bibliothèque libc dans ce programme ?
- Appels système invoqués :
write()- pour afficher "Bonjour, monde!" (car printf utilise write)getpid()- pour obtenir le PID du processuswrite()- pour afficher "Mon PID est..."open()- pour créer/ouvrir le fichier test.txtwrite()- pour écrire "Test d'écriture" dans le fichierclose()- pour fermer le fichierexit()- pour terminer le processus
- Catégories :
write()- Gestion de fichiers / Gestion de périphériques (selon le descripteur)getpid()- Maintenance des informationsopen()- Gestion de fichiersclose()- Gestion de fichiersexit()- Contrôle de processus
- Passage de paramètres pour write :
write(fd, buf, count)utilise trois paramètres :- fd (descripteur de fichier) - passé dans le registre rdi
- buf (pointeur vers les données) - passé dans le registre rsi
- count (nombre d'octets) - passé dans le registre rdx
Comme il y a 3 paramètres (moins de 5), ils sont passés par registres sous Linux.
- Rôle de libc :
La bibliothèque libc joue plusieurs rôles essentiels :
- Elle fournit une API plus simple (printf, fopen, etc.) que les appels système bruts.
- Elle gère le passage des paramètres et le placement des numéros d'appels.
- Elle effectue la transition vers le noyau via l'instruction syscall.
- Elle interprète les valeurs de retour et gère les erreurs (errno).
- Elle maintient des buffers (ex: pour printf) pour optimiser les appels système.
- Les appels système sont l'interface entre les programmes utilisateur et le noyau.
- Les programmeurs utilisent généralement des API (Windows, POSIX, Java) plutôt que des appels système directs.
- La bibliothèque libc fait le lien entre les fonctions API et les appels système sous Linux/Unix.
- Chaque appel système possède un numéro unique utilisé par le noyau pour l'identifier.
- Les paramètres peuvent être passés par registres, bloc mémoire ou pile.
- Linux utilise les registres pour ≤ 5 paramètres, la méthode des blocs pour plus de paramètres.
- Les appels système se divisent en six catégories : contrôle de processus, gestion de fichiers, gestion de périphériques, maintenance des informations, communications et protection.
- L'environnement d'exécution (RTE) fournit l'infrastructure nécessaire pour exécuter les programmes.
- Le programmeur n'a pas besoin de connaître l'implémentation des appels système, seulement l'API.
Discussion (0)
Soyez le premier à laisser un commentaire !
Laisser un commentaire
Votre commentaire sera visible après modération.