Changes between Version 128 and Version 129 of Archi-1-TP10
- Timestamp:
- Nov 19, 2023, 3:01:03 PM (12 months ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Archi-1-TP10
v128 v129 36 36 37 37 38 38 39 **Récupération du code du TP** 39 40 … … 132 133 '' 133 134 }}} 134 1. Dans quel fichier se trouvent les codes dépendant du MIPS ?135 1. Dans quel fichier se trouvent les codes dépendant du MIPS (donc écrits en assembleur) ? 135 136 {{{#!protected ------------------------------------------------------------------------------------ 136 137 '' … … 143 144 144 145 145 * Le numéro du processeur est dans les 12 bits de poids faible du registre du **coprocesseur0 $15** (`c0_cpuid`) (à côté des registres `c0_epc`, `c0_sr`, etc. ce n'est pas le registre GPR $15). Ajoutez la fonction `int cpuid(void)` qui lit le registre `c0_cpuid` et qui rend un entier contenant juste les 12 bits de poids faible.\\Vous pouvez vous inspirez fortement de la fonction `int clock(void)`. Comme il n'y a qu'un seul processeur dans cette architecture, `cpuid` rend toujours `0`.\\Ecrivez un programme de test (vous devrez modifier les fichiers `hcpu.h` pour y mettre le prototype de la fonction, `hcpua.S` pour y mettre le code et `kinit.c` pour appeler la fonction)146 * Dans un SoC, on peut avoir plusieurs processeurs. Le noyau a besoin de savoir sur quelle instance de processeur il s'exécute. Le numéro du processeur est dans les 12 bits de poids faible du registre du **coprocesseur-0 $15** (`c0_cpuid`) (à côté des registres `c0_epc`, `c0_sr`, etc. ce n'est pas le registre GPR $15). Ajoutez la fonction `int cpuid(void)` qui lit le registre `c0_cpuid` et qui rend un entier contenant juste les 12 bits de poids faible.\\Vous pouvez vous inspirez fortement de la fonction `int clock(void)`. Comme il n'y a qu'un seul processeur dans cette architecture, `cpuid` rend toujours `0`.\\Ecrivez un programme de test (vous devrez modifier les fichiers `hcpu.h` pour y mettre le prototype de la fonction, `hcpua.S` pour y mettre le code et `kinit.c` pour appeler la fonction) 146 147 147 148 {{{#!protected … … 180 181 181 182 **Fichiers** 183 182 184 183 185 {{{#!xml … … 205 207 206 208 207 1. Combien de fichiers de type ldscript avons-nous ?208 {{{#!protected ------------------------------------------------------------------------------------ 209 '' 210 - Il en faut deux , un pour le kernel `kernel/kernel.ld` et un pour l'application `user/user.ld`209 1. Combien de fichiers de type ldscript avons-nous en tout ? 210 {{{#!protected ------------------------------------------------------------------------------------ 211 '' 212 - Il en faut deux désormais, un pour le kernel `kernel/kernel.ld` et un pour l'application `user/user.ld` 211 213 '' 212 214 }}} … … 243 245 244 246 245 - Vous n'allez pas faire grand-chose pour cette étape parce qu'il est impossible de revenir dans le noyau après l'entrée dans l'application. Affichez juste un second message depuis la fonction `main()`247 - Vous n'allez pas faire grand-chose pour cette étape parce qu'il est impossible de revenir dans le noyau après l'entrée dans l'application... tant qu'il n'y a pas le gestionnaire de syscalls dans le noyau. En conséquence, affichez juste un second message depuis la fonction `main()`. 246 248 247 249 … … 253 255 **Objectifs de l'étape** 254 256 255 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. 257 258 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 analyser la cause 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. 256 259 257 260 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_PUTS`, `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. … … 291 294 292 295 293 1. Dans quel fichier se trouve la définition des numéros de services tels que `SYSCALL_EXIT` ? (''Ces numéros sont communs au noyau et à l'application'')296 1. Dans quel fichier se trouve la définition des numéros de services tels que `SYSCALL_EXIT` ?\\(''Ces numéros sont communs au noyau et à l'application, alors ils ont été mis dans un répertoire commun aux deux exécutables.'') 294 297 {{{#!protected ------------------------------------------------------------------------------------ 295 298 '' … … 297 300 '' 298 301 }}} 299 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 ? 302 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 ? C'est un tableau indexé par les numéros de syscall qui permet de connaitre la fonction à exécuter pour chaque numéro de service. 300 303 {{{#!protected ------------------------------------------------------------------------------------ 301 304 '' … … 303 306 '' 304 307 }}} 305 1. Dans quel fichier se trouve le gestionnaire de syscalls ? (''c'est de l'assembleur'') 308 1. Dans quel fichier se trouve le gestionnaire de syscalls ? (''c'est de l'assembleur'') et pourquoi est-ce de l'assembleur ? 306 309 {{{#!protected ------------------------------------------------------------------------------------ 307 310 '' 308 311 - Il est dans le fichier `kernel/hcpua.S`. 312 - Le code du gestionnaire est totalement spécifique au MIPS, on ne peut pas l'écrire en C. 309 313 '' 310 314 }}} … … 314 318 315 319 316 - Vous allez ajouter un appel système nommé `SYSCALL_CPUID` qui rend le numéro du processeur. Nous allons lui attribuer le numéro 6 (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)`. 320 - 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 : 321 - `kernel/hcpua.S` : pour ajouter `cpuid(void)` déjà écrite à l'étape précédente; 322 - `kernel/hcpu.h` : pour le prototype de la fonction `cpuid() (afin que gcc la connaisse pour la compilation de `kernel/ksyscall.c`; 323 - `common/syscalls.h` : pour ajouter le numéro de syscall `SYSCALL_CPUID`; 324 - `kernel/ksyscall.c` : pour ajouter la fonction `cpuid()` dans le vecteur de syscall. 325 - Modifiez aussi la fonction `main()` pour utiliser votre nouvel appel système. Vous pouvez utiliser le mode debug pour voir dans la trace d'exécution l'appel à 317 326 318 327 … … 325 334 326 335 327 L'application utilisateur n'est pas censée utiliser directement les appels système. Elle utilise une librairie de fonctions standards (la `libc` POSIX, mais pas seulement) et ce sont ces fonctions qui réalisent les appels système. Toutes les fonctions de la `libc` n'utilisent pas les appels système. Par exemple, les fonctions `int rand(void)` ou `int strlen(char *)` (rendent, respectivement, un nombre pseudo aléatoire et la longueur d'une chaîne de caractères) n'ont pas besoin du noyau. Les librairies font partie du système d'exploitation mais elles ne sont pas dans le noyau.336 L'application utilisateur n'est pas censée utiliser directement les appels système. Elle utilise une librairie de fonctions standards (la `libc` POSIX, mais pas uniquement) et ce sont ces fonctions qui réalisent les appels système. Toutes les fonctions de la `libc` n'utilisent pas les appels système. Par exemple, les fonctions `int rand(void)` ou `int strlen(char *)` (rendent, respectivement, un nombre pseudo aléatoire et la longueur d'une chaîne de caractères) n'ont pas besoin du noyau. Les librairies font partie du système d'exploitation mais elles ne sont pas dans le noyau. 328 337 329 338 ''Le terme « librairie » vient de l'anglais « library » qui signifie bibliothèque. On utilise souvent le mot librairie même si le sens en français n'est pas le même que celui en anglais. Disons que, dans notre contexte, les deux mots sont synonymes.'' 330 339 331 Normalement, les librairies système sont des « vraies » librairies au sens `gcc` du terme. C'est-à-dire des archives de fichiers objet (`.o`). Ici, nous allons simplifier et ne pas créer une ''vraie'' librairie, mais seulement un fichier objet `libc.o` contenant toutes les fonctions. Ce fichier objets doit être lié avec le code de l'application. 332 333 L'exécutable de l'application utilisateur est donc composé de deux parties : d'un côté, le code de l'application et, de l'autre, le code de la librairie `libc` (+ `crt0`). Nous allons répartir le code dans deux répertoires `uapp` pour les fichiers de l'application et `ulib` pour les fichiers qui ne sont pas l'application, c'est-à-dire la `libc`, le fichier `crt0.c` mais aussi le fichier ldscript `user.ld`. 340 Normalement, les librairies système sont des « vraies » librairies au sens `gcc` du terme. C'est-à-dire des archives de fichiers objet (`.o`). Ici, nous allons simplifier et ne pas créer une ''vraie'' librairie, mais seulement un fichier objet `libc.o` contenant toutes les fonctions. Ce fichier objet doit être lié avec le code de l'application. 341 342 L'exécutable de l'application utilisateur est donc composé de deux parties : d'un côté, le code de l'application et, de l'autre, le code de la librairie `libc` (+ `crt0`). Nous allons répartir le code dans deux répertoires: 343 - `uapp` pour les fichiers de l'application utilisateur 344 - `ulib` pour les fichiers qui ne sont pas l'application, c'est-à-dire la `libc`, le fichier `crt0.c` mais aussi le fichier ldscript `user.ld`. 334 345 335 346