Changes between Version 13 and Version 14 of Archi-1-TD10
- Timestamp:
- Nov 19, 2022, 8:59:12 PM (3 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Archi-1-TD10
v13 v14 42 42 43 43 44 1. Le MIPS propose deux modes d'exécution, rappelez quels sont ces deux modes et à quoi ils servent? ( ''Nous l'avons dit dans le descriptif de la séance''). (C10 S6+S7)44 1. Le MIPS propose deux modes d'exécution, rappelez quels sont ces deux modes et à quoi ils servent? (C10 S6+S7) 45 45 {{{#!protected ------------------------------------------------------------------------------------ 46 46 '' … … 212 212 '' 213 213 }}} 214 1. Que faire avant l'exécution de la fonction `main()` du point de vue de l'initialisation? Et au retour de la fonction `main()`? 215 {{{#!protected ------------------------------------------------------------------------------------ 216 '' 217 Cours 10 / slide 38 214 1. Que faire avant l'exécution de la fonction `main()` du point de vue de l'initialisation? Et au retour de la fonction `main()`? (C10 S24) 215 {{{#!protected ------------------------------------------------------------------------------------ 216 '' 218 217 - Comme dans la fonction `kinit()`, il faut explicitement initialiser les variables globales non initialisées dans le programme C. 219 218 - Si on sort de la fonction `main()`, l'application s'achève. Cela signifie qu'il faut appeler la fonction `exit()` qui effectue l'appel système SYSCALL_EXIT. Cette appel est réalisé au cas où l'application n'aurait pas explicitement exécuté `exit()`. Dans ce cas la valeur rendue par l'application est la valeur de retour de la fonction `main()`. 220 219 '' 221 220 }}} 222 1. Nous avons vu que le noyau est sollicité par des événements, quels sont-ils? Nous rappelons que l'instruction `syscall` initialise le registre `c0_cause`, comment le noyau fait-il pour connaître la cause de son appel? 223 {{{#!protected ------------------------------------------------------------------------------------ 224 '' 225 Cours 10 / slide 17 221 1. Nous avons vu que le noyau est sollicité par des demandes de service, quels sont-ils? Nous rappelons que l'instruction `syscall` initialise le registre `c0_cause`, comment le noyau fait-il pour connaître la cause de son appel? (C10 S25) 222 {{{#!protected ------------------------------------------------------------------------------------ 223 '' 226 224 - Il y en a 3 (si on excepte le signal `reset` qui redémarre tout le système: 227 225 1. Les appels système donc l'exécution de l'instruction `syscall`. … … 230 228 - L'instruction `syscall` initialise les 4 bits `XCODE` du registre `c0_cause` avec un code indiquant la raison de l'entrée dans le noyau. Le noyau doit analyser ce champ `XCODE`. 231 229 '' 232 }}} 233 1. `$26` et `$27` sont deux registres temporaires que le noyau se réserve pour faire des calculs sans qu'il ait besoin de les sauvegarder dans la pile. **Ce ne sont pas des registres système** comme `c0_sr` ou `c0_epc`. En effet, l'usage de ces registres (`$26` et `$27`) par l'utilisateur ne provoque pas d'exception du MIPS. Toutefois si le noyau est appelé alors il modifie ces registres et donc l'utilisateur perd leur valeur.\\Le code assembleur ci-après contient les instructions exécutées à l'entrée dans le noyau, quelle que soit la cause. Les commentaires présents dans le code ont été volontairement retirés (ils sont dans les fichiers du TP). La section `.kentry` est placée à l'adresse `0x80000000` par l'éditeur de lien. Ligne 16, la directive `.org DEP` (`.org` pour `origine`) permet de placer le pointeur de remplissage de la section courante à `DEP` octets du début de la section, ici `DEP = 0x180`. Aurait-on pu remplacer le `.org 0x180` par `.space 0x180` ? Expliquer les lignes 25 à 28.\\ \\**`kernel/hcpua.S`**230 }}} 231 1. `$26` et `$27` sont deux registres temporaires que le noyau se réserve pour faire des calculs sans qu'il ait besoin de les sauvegarder dans la pile. **Ce ne sont pas des registres système** comme `c0_sr` ou `c0_epc`. En effet, l'usage de ces registres (`$26` et `$27`) par l'utilisateur ne provoque pas d'exception du MIPS. Toutefois si le noyau est appelé alors il modifie ces registres et donc l'utilisateur perd leur valeur.\\Le code assembleur ci-après contient les instructions exécutées à l'entrée dans le noyau, quelle que soit la cause. Les commentaires présents dans le code ont été volontairement retirés (ils sont dans les fichiers du TP). La section `.kentry` est placée à l'adresse `0x80000000` par l'éditeur de lien.\\ \\**`kernel/hcpua.S`** 234 232 {{{#!c 235 233 15 .section .kentry,"ax" … … 243 241 28 bne $26, $27, not_syscall 244 242 }}} 245 {{{#!protected ------------------------------------------------------------------------------------ 246 '' 247 Cours 10 / slide 41 (mais il n'y a pas ces détails) 248 - La section `kentry` est placée à l'adresse `0x80000000` or l'entrée du noyau est `0x80000180` (l'entrée du noyau est l'adresse à laquelle le processeur ''saute'' lors de l'exécution `syscall`), il faut donc déplacer le pointeur de remplissage de la section `ktentry` de `0x180`. La directive `.space 0x180` réserve `0x180`, si on met cette directive au tout début de la section, c'est équivalent. 243 Ligne 16, la directive `.org DEP` (`.org` pour ''origine'', `DEP` pour ''déplassement'') permet de placer le pointeur de remplissage de la section courante à `DEP` octets du début de la section, ici `DEP = 0x180`. Pourquoi faire ça ? Aurait-on pu remplacer le `.org 0x180` par `.space 0x180` ? (C10 S5 et connaissance de l'assembleur) 244 {{{#!protected ------------------------------------------------------------------------------------ 245 '' 246 - La section `kentry` est placée à l'adresse `0x80000000` or l'entrée du noyau est `0x80000180` (l'entrée du noyau est l'adresse à laquelle le processeur ''saute'' lors de l'exécution `syscall`), il faut donc déplacer le pointeur de remplissage de la section `ktentry` de `0x180`. 247 - La directive `.space 0x180` réserve `0x180`, si on met cette directive au tout début de la section, c'est équivalent. 248 '' 249 }}} 250 Expliquer les lignes 25 à 28. (C10 S20+S26+S31) 251 {{{#!protected ------------------------------------------------------------------------------------ 249 252 - Commentaire du code 250 253 - Ligne 25 : `$26` **←** `c0_cause`\\⟶ donc le registre `$26`GPR réservé au kernel prend la valeur du registre de cause. … … 257 260 {{{#!c 258 261 1 #define SYSCALL_EXIT 0 259 2 #define SYSCALL_TTY_PUTC 1 260 3 #define SYSCALL_TTY_GETC 2 261 4 #define SYSCALL_TTY_PUTS 3 262 5 #define SYSCALL_TTY_GETS 4 263 6 #define SYSCALL_CLOCK 5 264 7 #define SYSCALL_NR 32 262 2 #define SYSCALL_READ 1 263 3 #define SYSCALL_WRITE 2 264 4 #define SYSCALL_CLOCK 3 265 5 #define SYSCALL_NR 32 265 266 }}} 266 267 **`kernel/ksyscalls.c`** … … 268 269 void *syscall_vector[] = { 269 270 [0 ... SYSCALL_NR - 1] = unknown_syscall, 270 [SYSCALL_EXIT] = exit, 271 [SYSCALL_TTY_PUTC] = tty_putc, 272 [SYSCALL_TTY_GETC] = tty_getc, 273 [SYSCALL_TTY_PUTS] = tty_puts, 274 [SYSCALL_TTY_GETS] = tty_gets, 275 [SYSCALL_CLOCK] = clock, 271 [SYSCALL_EXIT ] = exit, 272 [SYSCALL_READ ] = tty_read, 273 [SYSCALL_WRITE ] = tty_write, 274 [SYSCALL_CLOCK ] = clock, 276 275 }; 277 276 }}}