1247 | | |
1248 | | == B5. Programme utilisateur utilisé en mode user mais sans libc |
1249 | | |
1250 | | |
1251 | | |
1252 | | **Objectifs de l'étape** |
1253 | | |
1254 | | Nous allons désormais avoir deux exécutables: le noyau et l'application. Dans cette étape, nous allons voir comment le noyau fait pour appeler l'application, alors même que celle-ci n'est pas compilée en même temps que le noyau. Nous allons passer du noyau à l'application à la fin de la fonction `kinit()`. |
1255 | | |
1256 | | Nous avons deux exécutables à compiler et donc deux `Makefile`s de compilation. Nous avons aussi un `Makefile` qui invoque récursivement les `Makefile`s de compilation. |
1257 | | |
1258 | | Nous allons donc entrer dans l'application depuis la fonction `kinit()`. Le programme utilisateur doit absolument s'exécuter en mode user et il doit passer par des appels système pour accéder aux services du noyau. Les services, ici, sont limités (l'accès au TTY, exit et clock), il n'empêche que pour gérer ces appels, il faut l'analyseur des causes d'appels à l'entrée du noyau et un gestionnaire de `syscall`. Il faut aussi le gestionnaire d'exceptions, parce que s'il y a une erreur de programmation, le noyau doit afficher quelque chose pour aider le programmeur. |
1259 | | |
1260 | | Le passage de l'application au noyau par le biais de l'instruction `syscall` impose que les numéros de services soient identiques pour le noyau et pour l'application. Ces numéros de service (comme `SYSCALL_TTY_WRITE`, `SYSCALL_EXIT` sont définis dans le fichier `syscall.h` communs au noyau et à l'application. Ce fichier est mis dans un répertoire à part nommé `common`. Il n'y a qu'un seul fichier ici, mais dans un système plus élaboré, il y en a d'autres. |
1261 | | |
1262 | | |
1263 | | **Fichiers** |
1264 | | |
1265 | | |
1266 | | {{{#!xml |
1267 | | 5_syscalls/ |
1268 | | ├── Makefile : Makefile racine qui invoque les Makefiles des sous-répertoires et qui exécute |
1269 | | ├── common ────────── répertoire des fichiers commun kernel / user |
1270 | | │ └── syscalls.h : API la fonction syscall et des codes de syscalls |
1271 | | ├── kernel ────────── Répertoire des fichiers composant le kernel |
1272 | | │ ├── kinit.c : fichier contenant la fonction de démarrage du noyau |
1273 | | │ ├── harch.h : API du code dépendant de l'architecture |
1274 | | │ ├── harch.c : code dépendant de l'architecture du SoC |
1275 | | │ ├── hcpu.h : prototype de la fonction clock() |
1276 | | │ ├── hcpua.S : code dépendant du cpu matériel en assembleur |
1277 | | │ ├── klibc.h : API de la klibc |
1278 | | │ ├── klibc.c : fonctions standards utilisées par les modules du noyau |
1279 | | │ ├── kpanic.h : déclaration du tableau de dump des registres en cas d'exception |
1280 | | │ ├── kpanic.c : fonction d'affichage des registres avant l'arrêt du programme |
1281 | | │ ├── ksyscalls.c : Vecteurs des syscalls |
1282 | | │ ├── kernel.ld : ldscript décrivant l'espace d'adressage pour l'édition de liens du kernel |
1283 | | │ └── Makefile : description des actions possibles sur le code kernel : compilation et nettoyage |
1284 | | └── user ──────────── Répertoire des fichiers composant l'application user |
1285 | | ├── crt0.c : fonctions d'interface entre kernel et user, pour le moment : crt0() |
1286 | | ├── main.c : fonction principale de l'application |
1287 | | ├── user.ld : ldscript décrivant l'espace d'adressage pour l'édition de liens du user |
1288 | | └── Makefile : description des actions possibles sur le code user : compilation et nettoyage |
1289 | | }}} |
1290 | | |
1291 | | |
1292 | | **Questions** |
1293 | | |
1294 | | |
1295 | | 1. Dans quel fichier se trouve la définition des numéros de services tels que `SYSCALL_EXIT` ? |
1296 | | {{{#!protected ------------------------------------------------------------------------------------ |
1297 | | ''''''''''''''' |
1298 | | - Ils sont dans le fichier `common/syscall.h`. |
1299 | | ''''''''''''''' |
1300 | | }}} |
1301 | | 1. Dans quel fichier se trouve le vecteur de syscall, c'est-à-dire le tableau `syscall_vector[]` contenant les pointeurs sur les fonctions qui réalisent les services correspondants aux syscall ? |
1302 | | {{{#!protected ------------------------------------------------------------------------------------ |
1303 | | ''''''''''''''' |
1304 | | - Il est dans le fichier `kernel/ksyscall.c`. |
1305 | | ''''''''''''''' |
1306 | | }}} |
1307 | | 1. Dans quel fichier se trouve le gestionnaire de syscalls ? |
1308 | | {{{#!protected ------------------------------------------------------------------------------------ |
1309 | | ''''''''''''''' |
1310 | | - Il est dans le fichier `kernel/hcpua.S`. |
1311 | | ''''''''''''''' |
1312 | | }}} |
1313 | | |
1314 | | |
1315 | | **Exercice** |
1316 | | |
1317 | | |
1318 | | - Vous allez ajouter un appel système nommé `SYSCALL_CPUID` qui rend le numéro du processeur. Nous allons lui attribuer le numéro 4 (notez que ces numéros de services n'ont rien à voir avec les numéros utilisés pour le simulateur MARS). Pour ajouter un appel système, vous devez modifier les fichiers : `common/syscalls.h`, `kernel/ksyscall.c`, `kernel/hcpua.S` et `kernel/hcpu.h`.cpuid(void)`. |
1319 | | |
1320 | | |
1321 | | |
1322 | | == B6. Ajout de la librairie C pour l'utilisateur |
| 1247 | == B4. Ajout de la librairie C pour l'utilisateur |
1379 | | |
1380 | | |
1381 | | **Exercice** |
1382 | | |
1383 | | |
| 1304 | 1. Dans quel fichier se trouve la définition des numéros de services tels que `SYSCALL_EXIT` ? |
| 1305 | {{{#!protected ------------------------------------------------------------------------------------ |
| 1306 | ''''''''''''''' |
| 1307 | - Ils sont dans le fichier `common/syscall.h`. |
| 1308 | ''''''''''''''' |
| 1309 | }}} |
| 1310 | 1. Dans quel fichier se trouve le vecteur de syscall, c'est-à-dire le tableau `syscall_vector[]` contenant les pointeurs sur les fonctions qui réalisent les services correspondants aux syscall ? |
| 1311 | {{{#!protected ------------------------------------------------------------------------------------ |
| 1312 | ''''''''''''''' |
| 1313 | - Il est dans le fichier `kernel/ksyscall.c`. |
| 1314 | ''''''''''''''' |
| 1315 | }}} |
| 1316 | 1. Dans quel fichier se trouve le gestionnaire de syscalls ? |
| 1317 | {{{#!protected ------------------------------------------------------------------------------------ |
| 1318 | ''''''''''''''' |
| 1319 | - Il est dans le fichier `kernel/hcpua.S`. |
| 1320 | ''''''''''''''' |
| 1321 | }}} |
| 1322 | |
| 1323 | |
| 1324 | **Exercice** |
| 1325 | |
| 1326 | Vous allez ajouter un appel système nommé `SYSCALL_MEMCPY` qui réalise la copie d'une zone de la mémoire. |