Changes between Version 18 and Version 19 of AS6-TME-B1
- Timestamp:
- Feb 9, 2022, 10:39:16 AM (3 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
AS6-TME-B1
v18 v19 428 428 429 429 compil: 430 $(CC) -o hcpu.o $(CFLAGS) hcpu .S431 @$(OD) -D hcpu .o > hcpu.o.s430 $(CC) -o hcpu.o $(CFLAGS) hcpua.S 431 @$(OD) -D hcpua.o > hcpua.o.s 432 432 $(LD) -o kernel.x -T kernel.ld hcpu.o 433 433 @$(OD) -D kernel.x > kernel.x.s … … 777 777 ''''''''''''''' 778 778 }}} 779 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. La directive `.org` (ligne 16) permet de déplacer le pointeur de remplissage de la section courante du nombre d'octets donnés en argument, ici `0x180`. Pouvez-vous dire pourquoi ? Expliquer les lignes 25 à 28.\\ \\**`kernel/hcpu .S`**779 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. La directive `.org` (ligne 16) permet de déplacer le pointeur de remplissage de la section courante du nombre d'octets donnés en argument, ici `0x180`. Pouvez-vous dire pourquoi ? Expliquer les lignes 25 à 28.\\ \\**`kernel/hcpua.S`** 780 780 {{{#!c 781 781 15 .section .kentry,"ax" … … 799 799 ''''''''''''''' 800 800 }}} 801 1. Le gestionnaire de `syscall` est la partie du code qui gère le comportement du noyau lors de l'exécution de l'instruction `syscall`. C'est un code en assembleur présent dans le fichier `kernel/hcpu .S` que nous allons observer. Pour vous aider dans la compréhension de ce code, vous devez imaginer que l'instruction `syscall` est un peu comme un appel de fonction. Ce code utilise un tableau de pointeurs de fonctions nommé `syscall_vector` définit dans le fichier `kernel/ksyscalls.c`. Les lignes `47` à `54` sont chargées d'allouer de la place dans la pile.\\- Dessinez l'état de la pile après l'exécution de ces instructions.\\- Que fait l'instruction ligne `55` et quelle conséquence cela a-t-il?\\- Que font les lignes `57` à `62`?\\- Et enfin que font les lignes `64` à `70` ?\\Les commentaires ont été laissés, vous devez juste mettre à quoi ça sert, sans détailler ligne à ligne.\\ \\**`common/syscalls.h`**801 1. Le gestionnaire de `syscall` est la partie du code qui gère le comportement du noyau lors de l'exécution de l'instruction `syscall`. C'est un code en assembleur présent dans le fichier `kernel/hcpua.S` que nous allons observer. Pour vous aider dans la compréhension de ce code, vous devez imaginer que l'instruction `syscall` est un peu comme un appel de fonction. Ce code utilise un tableau de pointeurs de fonctions nommé `syscall_vector` définit dans le fichier `kernel/ksyscalls.c`. Les lignes `47` à `54` sont chargées d'allouer de la place dans la pile.\\- Dessinez l'état de la pile après l'exécution de ces instructions.\\- Que fait l'instruction ligne `55` et quelle conséquence cela a-t-il?\\- Que font les lignes `57` à `62`?\\- Et enfin que font les lignes `64` à `70` ?\\Les commentaires ont été laissés, vous devez juste mettre à quoi ça sert, sans détailler ligne à ligne.\\ \\**`common/syscalls.h`** 802 802 {{{#!c 803 803 #define SYSCALL_EXIT 0 /* see exit() in ulib/libc.c */ … … 817 817 }; 818 818 }}} 819 **`kernel/hcpu .S`**819 **`kernel/hcpua.S`** 820 820 {{{#!asm 821 821 45 syscall_handler: … … 905 905 $(OD) -D $@ > $@.s 906 906 907 obj/hcpu .o : hcpu.S hcpu.h907 obj/hcpua.o : hcpua.S hcpu.h 908 908 $(CC) -o $@ $(CFLAGS) $< 909 909 $(OD) -D $@ > $@.s … … 913 913 - La `cible` finale est : `kernel.x` 914 914 - Les `cibles` intermédiaires sont : `kernel.ld`, `obj/hcpu.o`, `obj/kinit.o`, `obj/klibc.o` et `obj/harch.o`. 915 - La `source` est : `hcpu .S`915 - La `source` est : `hcpua.S` 916 916 - Les variables automatiques servent à extraire des noms dans la définition de la dépendance (`cible : dépendances`) 917 917 - dans la première règle : … … 920 920 - dans la seconde règle : 921 921 - `$@` = `cible` = `obj/hcpu.o` 922 - `$<` = la première des dépendances = `hcpu .S`922 - `$<` = la première des dépendances = `hcpua.S` 923 923 ''''''''''''''' 924 924 }}} … … 979 979 {{{ 980 980 2_init_c/ 981 ├── hcpu .S: code dépendant du cpu matériel en assembleur981 ├── hcpua.S : code dépendant du cpu matériel en assembleur 982 982 ├── kernel.ld : ldscript décrivant l'espace d'adressage pour l'éditeur de lien 983 983 ├── kinit.c : fichier en C contenant le code de démarrage du noyau, ici c'est la fonction kinit(). … … 1057 1057 ''''''''''''''' 1058 1058 - Il faut initialiser le pointeur avant d'appeler `kinit()` 1059 - C'est dans le fichier `hcpu .S`1059 - C'est dans le fichier `hcpua.S` 1060 1060 - `$29` ← `__kdata_end`, c'est-à-dire `0x80400000` 1061 1061 ''''''''''''''' … … 1154 1154 ''''''''''''''' 1155 1155 }}} 1156 1. Le MIPS dispose d'un compteur de cycles internes. Ce compteur est dans un banc de registres accessibles uniquement quand le processeur fonctionne en mode `kernel`. Nous verrons ça au prochain cours, mais en attendant nous allons quand même exploiter ce compteur. Pourquoi avoir mis la fonction dans `hcpu .S` ? Rappeler, pourquoi avoir mis `.globl clock`1157 {{{#!protected ------------------------------------------------------------------------------------ 1158 ''''''''''''''' 1159 * La fonction qui lit ce registre (`$9` qui ne désigne pas un registre GPR du processeur !) est nécessairement en assembleur car elle utilise des instructions particulières et dépend du matériel, elle est donc mise dans hcpu .S.1156 1. Le MIPS dispose d'un compteur de cycles internes. Ce compteur est dans un banc de registres accessibles uniquement quand le processeur fonctionne en mode `kernel`. Nous verrons ça au prochain cours, mais en attendant nous allons quand même exploiter ce compteur. Pourquoi avoir mis la fonction dans `hcpua.S` ? Rappeler, pourquoi avoir mis `.globl clock` 1157 {{{#!protected ------------------------------------------------------------------------------------ 1158 ''''''''''''''' 1159 * La fonction qui lit ce registre (`$9` qui ne désigne pas un registre GPR du processeur !) est nécessairement en assembleur car elle utilise des instructions particulières et dépend du matériel, elle est donc mise dans hcpua.S. 1160 1160 * `.globl clock` permet de faire en sorte que la fonction soit visible par les autres fichiers C. 1161 1161 ''''''''''''''' … … 1222 1222 1223 1223 1224 * Le numéro du processeur est dans les 12 bits de poids faible du registre $15 (`c0_cpuid`) du coprocesseur système (à côté des registres `c0_epc`, `c0_sr`, etc.). 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`, `hcpu .S` et `kinit.c`)1224 * Le numéro du processeur est dans les 12 bits de poids faible du registre $15 (`c0_cpuid`) du coprocesseur système (à côté des registres `c0_epc`, `c0_sr`, etc.). 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`, `hcpua.S` et `kinit.c`) 1225 1225 1226 1226 {{{#!protected 1227 **hcpu .S**1227 **hcpua.S** 1228 1228 {{{#!asm 1229 1229 .globl cpuid … … 1274 1274 │ ├── harch.c : code dépendant de l'architecture du SoC 1275 1275 │ ├── hcpu.h : prototype de la fonction clock() 1276 │ ├── hcpu .S: code dépendant du cpu matériel en assembleur1276 │ ├── hcpua.S : code dépendant du cpu matériel en assembleur 1277 1277 │ ├── klibc.h : API de la klibc 1278 1278 │ ├── klibc.c : fonctions standards utilisées par les modules du noyau … … 1308 1308 {{{#!protected ------------------------------------------------------------------------------------ 1309 1309 ''''''''''''''' 1310 - Il est dans le fichier `kernel/hcpu .S`.1310 - Il est dans le fichier `kernel/hcpua.S`. 1311 1311 ''''''''''''''' 1312 1312 }}} … … 1316 1316 1317 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/hcpu .S` et `kernel/hcpu.h`.cpuid(void)`.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 1319 1320 1320 … … 1340 1340 1341 1341 {{{#!xml 1342 6_libc/1342 04_libc/ 1343 1343 ├── Makefile : Makefile racine qui invoque les Makefiles des sous-répertoires et qui exécute 1344 1344 ├── common ────────── répertoire des fichiers commun kernel / user … … 1349 1349 │ ├── harch.c : code dépendant de l'architecture du SoC 1350 1350 │ ├── hcpu.h : prototype de la fonction clock() 1351 │ ├── hcpu .S : code dépendant du cpu matériel en assembleur1351 │ ├── hcpua.S : code dépendant du cpu matériel en assembleur 1352 1352 │ ├── klibc.h : API de la klibc 1353 1353 │ ├── klibc.c : fonctions standards utilisées par les modules du noyau