Changes between Version 18 and Version 19 of AS6-TME-B1


Ignore:
Timestamp:
Feb 9, 2022, 10:39:16 AM (2 years ago)
Author:
franck
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • AS6-TME-B1

    v18 v19  
    428428
    429429compil:
    430     $(CC) -o hcpu.o $(CFLAGS) hcpu.S
    431     @$(OD) -D hcpu.o > hcpu.o.s
     430    $(CC) -o hcpu.o $(CFLAGS) hcpua.S
     431    @$(OD) -D hcpua.o > hcpua.o.s
    432432    $(LD) -o kernel.x -T kernel.ld hcpu.o
    433433    @$(OD) -D kernel.x > kernel.x.s
     
    777777'''''''''''''''
    778778}}}
    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`**
     7791. `$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`**
    780780{{{#!c
    781781 15 .section    .kentry,"ax"     
     
    799799'''''''''''''''
    800800}}}
    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`**
     8011. 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`**
    802802{{{#!c
    803803#define SYSCALL_EXIT        0       /* see exit()   in ulib/libc.c */
     
    817817};
    818818}}}
    819   **`kernel/hcpu.S`**
     819  **`kernel/hcpua.S`**
    820820{{{#!asm
    821821 45 syscall_handler:
     
    905905    $(OD) -D $@ > $@.s
    906906
    907 obj/hcpu.o : hcpu.S hcpu.h
     907obj/hcpua.o : hcpua.S hcpu.h
    908908    $(CC) -o $@ $(CFLAGS) $<
    909909    $(OD) -D $@ > $@.s
     
    913913- La `cible` finale est : `kernel.x`
    914914- 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`
    916916- Les variables automatiques servent à extraire des noms dans la définition de la dépendance (`cible : dépendances`)
    917917  - dans la première règle :
     
    920920  - dans la seconde règle :
    921921    - `$@` = `cible` = `obj/hcpu.o`
    922     - `$<` = la première des dépendances = `hcpu.S`
     922    - `$<` = la première des dépendances = `hcpua.S`
    923923'''''''''''''''
    924924}}}
     
    979979{{{
    9809802_init_c/
    981 ├── hcpu.S       : code dépendant du cpu matériel en assembleur
     981├── hcpua.S      : code dépendant du cpu matériel en assembleur
    982982├── kernel.ld    : ldscript décrivant l'espace d'adressage pour l'éditeur de lien
    983983├── kinit.c      : fichier en C contenant le code de démarrage du noyau, ici c'est la fonction kinit().
     
    10571057'''''''''''''''
    10581058- 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`
    10601060- `$29` ← `__kdata_end`, c'est-à-dire `0x80400000`
    10611061'''''''''''''''
     
    11541154'''''''''''''''
    11551155}}}
    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.
     11561. 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.
    11601160* `.globl clock` permet de faire en sorte que la fonction soit visible par les autres fichiers C.
    11611161'''''''''''''''
     
    12221222
    12231223
    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`)
    12251225
    12261226{{{#!protected
    1227 **hcpu.S**
     1227**hcpua.S**
    12281228{{{#!asm
    12291229.globl cpuid
     
    12741274│   ├── harch.c     : code dépendant de l'architecture du SoC
    12751275│   ├── hcpu.h      : prototype de la fonction clock()
    1276 │   ├── hcpu.S      : code dépendant du cpu matériel en assembleur
     1276│   ├── hcpua.S     : code dépendant du cpu matériel en assembleur
    12771277│   ├── klibc.h     : API de la klibc
    12781278│   ├── klibc.c     : fonctions standards utilisées par les modules du noyau
     
    13081308{{{#!protected ------------------------------------------------------------------------------------
    13091309'''''''''''''''
    1310 - Il est dans le fichier `kernel/hcpu.S`.
     1310- Il est dans le fichier `kernel/hcpua.S`.
    13111311'''''''''''''''
    13121312}}}
     
    13161316
    13171317
    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)`.
    13191319
    13201320
     
    13401340
    13411341{{{#!xml
    1342 6_libc/
     134204_libc/
    13431343├── Makefile        : Makefile racine qui invoque les Makefiles des sous-répertoires et qui exécute
    13441344├── common ────────── répertoire des fichiers commun kernel / user
     
    13491349│   ├── harch.c     : code dépendant de l'architecture du SoC
    13501350│   ├── hcpu.h      : prototype de la fonction clock()
    1351 │   ├── hcpu.S      : code dépendant du cpu matériel en assembleur
     1351│   ├── hcpua.S      : code dépendant du cpu matériel en assembleur
    13521352│   ├── klibc.h     : API de la klibc
    13531353│   ├── klibc.c     : fonctions standards utilisées par les modules du noyau