Changes between Version 193 and Version 194 of Archi-1-TP9


Ignore:
Timestamp:
Nov 14, 2023, 6:05:07 PM (12 months ago)
Author:
franck
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Archi-1-TP9

    v193 v194  
    2222}}}
    2323
    24 Pour les travaux pratiques, vous devez d'abord répondre à des questions qui ont pour but de vous faire lire le code et revoir les points du cours. Les réponses sont dans le cours ou dans les fichiers sources. Certaines ont déjà été traitées en TD, c'est normal. Ensuite, vous passez aux exercices pratiques.
     24Pour les travaux pratiques, vous devez d'abord répondre à des questions qui ont pour but de vous faire lire le code et revoir les points du cours. Les réponses sont dans le cours ou dans les fichiers sources. Certaines questions ont déjà été traitées en TD, c'est normal. Ensuite, vous passez aux exercices pratiques.
    2525
    2626La partie pratique  est découpée en 5 étapes. Pour chaque étape, nous donnons (1) une brève description, (2) une liste des objectifs principaux de l'étape, (3) une liste des fichiers avec un bref commentaire sur chaque fichier, (4) une liste de questions simples dont les réponses sont dans le code, le cours ou le TD et enfin (5) un exercice de codage.
     
    3333> * [htdocs:cours/Archi-1-C9-boot-2p.pdf Cours de démarrage présentant l'architecture matérielle et logicielle que vous allez manipuler] ''obligatoire''
    3434> * [htdocs:cours/Archi-1-C9-outils-annexe-2p.pdf Éléments d'information sur les outils de la chaîne de compilation] ''recommandé''
    35 > * [wiki:Howto-TP Configuration de l'environnement des TP] : ''obligatoire si vous êtes sur votre machine personelle, sinon c'est inutile''
    3635> * [htdocs:cours/doc_MIPS32.pdf Document sur l'assembleur du MIPS et la convention d'appel des fonctions] : ''recommandé''
    3736> * [wiki:Doc-MIPS-Archi-Asm-kernel Documentation sur le mode kernel du MIPS32] : ''optionnel pour cette séance''
     37> * [wiki:Howto-TP Configuration de l'environnement des TP] : ''obligatoire si vous êtes sur votre machine personelle, sinon lisez la suite''
    3838
    3939
     
    4141
    4242* **Configuration et test de l'environnement de travail sur les machines de la PPTI**
    43   * Éditez votre fichier `$HOME/.bashrc` et ajoutez au début:\\`source /Infos/lmd/2023/licence/ue/LU3IN029-2023oct/kO6/bin/SourceMe.sh`\\Ce script modifie quelques variables d'environnement telle que PATH qui permet de définir les répertoires dans lesquels le shell bash trouve ses exécutables (ici la chaîne de compilation du MIPS et le simulateur **almo1**).
     43  * Éditez votre fichier `$HOME/.bashrc` et ajoutez au début:\\`source /Infos/lmd/2023/licence/ue/LU3IN029-2023oct/kO6/bin/SourceMe.sh`\\Ce script modifie quelques variables d'environnement telle que PATH qui permet de définir les répertoires dans lesquels le shell bash trouve ses exécutables (ici, les outils de la chaîne de compilation du MIPS et le simulateur **almo1**).
    4444  * Exécutez pour cette fois le .bashrc (parce que vous venez juste de le modifier):\\`source $HOME/.bashrc`\\Vous pouvez aussi ouvrir un nouveau terminal, celui-ci exécutera le script `.bashrc` avant d'afficher le prompt.\\ \\
    4545* **Récupération des codes pour le tp1
    4646  * Ouvrez un `terminal`
    47   * Allez dans le répertoire où vous placez vos codes (cela dépend de chacun, je vais supposer ici qu'il y a un répertoire `~/kO6` à la racine du de votre compte):\\**`cd ~/kO6`**
     47  * Créer un répertoire nommé `kO6` à la racine de votre compte:\\`mkdir ~/kO6`\\Dans le texte des TP, nous supposons que c'est là que vous mettrez vos codes,\\vous pouvez choisir un autre emplacement, mais dans les textes, ce sera `~/kO6`
     48  * Allez dans le répertoire `~/kO6`:\\`cd ~/kO6`
    4849  * Copier les codes du tp1:\\`cp -rp /Infos/lmd/2023/licence/ue/LU3IN029-2023oct/kO6/tp/tp1 .`
    4950  * Exécutez la commande: **`tree -L 1 tp1`**.\\Vous devriez obtenir ceci:
     
    6162* **Pour tester que tout fonctionne**
    6263  * Allez dans le répertoire `0_test_almo1`:\\`cd tp1/0_test_almo1`
    63   * Exécuter la commande:\\`make exec`\\Vous devez voir 2 fenêtres `xterm` apparaître avec le message `Hello Word" et une petite fenêtre avec une roue tournante
    64   * Pour arrêter le simulateur, vous devez taper `CTRL-C` dans le terminal où vous avez démarrer le simulateur.
     64  * Exécuter la commande:\\`make exec`\\Vous devez voir 2 fenêtres `xterm` apparaître avec le message `Hello Word` et une petite fenêtre avec une roue tournante
     65  * **Pour arrêter le simulateur, vous devez taper `CTRL-C` dans le terminal où vous avez démarrer le simulateur**.
    6566  * Si vous regarder dans le répertoire, le compilateur et le simulateur ont créés plusieurs fichiers (les exécutables MIPS et d'autres), pour faire le ménage et revenir aux seuls fichiers source, vous devez taper:\\`make clean`
    6667
     
    8384**Fichiers**
    8485
     86* Allez dans le répertoire `1_hello_boot`: `cd ~/kO6/tp1/1_hello_boot`\\Il y a 3 fichiers.
    8587{{{
    86881_hello_boot
     
    9597
    9698
    97 1. Dans quel fichier se trouve la description de l'espace d'adressage du MIPS ? Que trouve-t-on dans ce fichier ?
     991. Dans quel fichier se trouve la description de l'espace d'adressage du MIPS ? Que trouve-t-on dans ce fichier (il faut l'ouvrir pour répondre) ?
    98100{{{#!protected ------------------------------------------------------------------------------------
    99101''
     
    105107''
    106108}}}
    107 1. Dans quel fichier se trouve le code de boot et pourquoi, selon vous, avoir nommé ce fichier ainsi ? (h pour hardware, cpu = Central Processor Unit)
     1091. Dans quel fichier se trouve le code de boot ? (h pour hardware, cpu = Central Processor Unit)
    108110{{{#!protected ------------------------------------------------------------------------------------
    109111''
     
    121123''
    122124}}}
    123 1. Que produit `gcc` quand on utilise l'option `-c` ?
     1251. Que produit `gcc` quand on utilise l'option `-c` ? (C9 S35)
    124126{{{#!protected ------------------------------------------------------------------------------------
    125127''
     
    128130''
    129131}}}
    130 1. Que fait l'éditeur de liens ? Comment est-il invoqué ? (C9 S21)
    131 {{{#!protected ------------------------------------------------------------------------------------
    132 ''
    133 - L'éditeur de liens rassemble toutes les sections produites par le compilateur, et donc présentes dans les fichiers objet `.o`, et il les place dans de nouvelles sections, elles-mêmes placées dans les régions de la mémoire, conformément au fichier ldscript (ici `kernel.ld`).
    134 - L'éditeur de liens est appelé par `gcc` si on n'a pas l'option `-c`ou directement par `ld` (ici `mipsel_unknown_ld`)
    135 ''
    136 }}}
    137 1. De quels fichiers a besoin l'éditeur de liens pour fonctionner ?
     1321. Que fait l'éditeur de liens ? Comment est-il invoqué ? (C9 S37)
     133{{{#!protected ------------------------------------------------------------------------------------
     134''
     135- L'éditeur de liens rassemble toutes les sections produites par le compilateur, et donc présentes dans les fichiers objet `.o`, et il les place dans de nouvelles sections, lesquelles sont placées dans les régions de la mémoire, conformément au fichier ldscript (ici, `kernel.ld`).
     136- L'éditeur de liens est appelé par `gcc` **si on n'a pas l'option `-c`** ou directement par `ld` (ici `mipsel_unknown_ld`)
     137''
     138}}}
     1391. De quels fichiers a besoin l'éditeur de liens pour fonctionner ? (C9 S37)
    138140{{{#!protected ------------------------------------------------------------------------------------
    139141''
     
    141143''
    142144}}}
    143 1. Dans quelle section se trouve le code de boot pour le compilateur ? ''(la réponse est dans le code assembleur)''
     1451. Dans quelle section se trouve le code de boot pour le compilateur ? ''(la réponse est dans le code assembleur, on fera un autre choix plus tard)''
    144146{{{#!protected ------------------------------------------------------------------------------------
    145147''
     
    147149''
    148150}}}
    149 1. Dans quelle section se trouve le message "hello" pour le compilateur ? Ce choix est particulier, mais ce message est en lecture seule.
    150 {{{#!protected ------------------------------------------------------------------------------------
    151 ''
    152 - Le message est aussi la section `.text`.
    153 ''
    154 }}}
    155 1. Dans quelle section se trouve le code de boot dans le code exécutable ? (la réponse est dans le fichier `kernel.ld`)
    156 {{{#!protected ------------------------------------------------------------------------------------
    157 ''
    158 - Dans le programme exécutable, le code de boot est mis dans la section `.boot`.
     1511. Dans quelle section se trouve le message `"hello ..."` pour le compilateur ? Ce choix est particulier, mais ce message est en lecture seule, alors pourquoi pas...
     152{{{#!protected ------------------------------------------------------------------------------------
     153''
     154- Le message est aussi la section `.text`. Ce n'est en général pas la place des données, mais ce n'est pas interdit, si les données sont en lecture seule.
     155''
     156}}}
     1571. Dans quelle section se trouve le code de boot dans le code exécutable produit par l'éditeur de liens ? (la réponse est dans le fichier `kernel.ld`)
     158{{{#!protected ------------------------------------------------------------------------------------
     159''
     160- Dans le programme exécutable, le code de boot est mis dans une section nommée `.boot`.
    159161''
    160162}}}
     
    170172- Le fichier `kernel.ld` déclare une variable `__tty_regs_map` initialisée avec l'adresse de
    171173  où sont placés les registres de contrôles du `TTY`. Le premier registre à l'adresse `__tty_regs_map`
    172   est l'adresse du registre de sortie `TTY_WRITE`.
     174  est l'adresse du registre de sortie `TTY_WRITE`. Il faut connaitre l'organisation des registres
     175  dans le contrôleur de TTY
    173176''
    174177}}}
    1751781. Le code de boot se contente d'afficher un message, comment sait-on que le message est fini
    176    et que le programme doit s'arrêter ? (ou quel est le caractère de fin de chaîne ?)
     179   et que le programme doit s'arrêter ? (ou quel est le caractère de fin de chaîne en C ?)
    177180{{{#!protected ------------------------------------------------------------------------------------
    178181''
     
    180183''
    181184}}}
    182 1. Pourquoi terminer le programme par un `dead: j dead` ? Notez qu'on ne peut pas encore faire un ''`syscall exit`'' parce qu'il n'y a pas de gestionnaire de syscall et surtout parce `syscall` est une instruction appeler par une application utilisateur, et qu'il n'y en a pas encore.
     1851. Pourquoi terminer le programme par un `dead: j dead` ? Notez qu'on ne peut pas encore faire un ''`syscall exit`'' parce qu'il n'y a pas de gestionnaire de syscall et surtout parce `syscall` est une instruction appelée par une application utilisateur, et qu'on n'est pas dans une application utilisateur.
    183186{{{#!protected ------------------------------------------------------------------------------------
    184187''
     
    196199''
    197200}}}
    198 1. Comment définir une macro-instruction C uniquement si elle n'est pas déjà définie ? Écrivez un exemple. Si vous ne savez pas regardez l'usage de `#ifndef` (C9 annexe S9)
     2011. Comment définir une macro-instruction C uniquement si elle n'est pas déjà définie ? Écrivez un exemple. Si vous ne savez pas regardez l'usage de `#ifndef` (C9 annexe S10)
    199202{{{#!protected ------------------------------------------------------------------------------------
    200203''
     
    235238}}}
    236239- Exécutez le programme en lançant le simulateur avec `make debug`.\\Cela exécute le programme pour une courte durée et cela produit deux fichiers `trace0.s` et `label0.s`.\\`trace0.s` contient la trace des instructions assembleur exécutées par le processeur. \\Ouvrez `trace.0.s` et repérez ce qui est cité ici 
    237  - On voit la séquence des instructions exécutées
    238  - La première colonne nous informe que les adresses lues sont dans l'espace Kernel
    239  - La seconde colonne sont les numéros de cycles
    240  - La troisième sont les adresses 
    241  - La quatrième le code binaire des instructions
    242  - Le reste de la ligne contient l'instruction désassemblée
    243  - Lorsque les adresses ont un nom, c'est à dire qu'une étiquette leur a été attribuée, celle-ci est indiquée.
    244 
    245  `label0.s` contient la séquence des appels de fonctions de l'exécutions. C'est en fait un extrait de la trace.\\Ouvrez le fichier `label0.s` et interprétez ce que vous voyez.
     240 - On voit la séquence chronologique des instructions exécutées
     241 - La première colonne nous informe que les adresses lues sont dans l'espace Kernel (ici, K)
     242 - La seconde colonne sont les numéros de cycles (ce n'est pas +1 à chaque instruction parce qu'il y a des caches et que cela prend du temps d'aller chercher les instructions dans la mémoire).
     243 - La troisième sont les adresses. Notez que la première instruction lue est bien en `0xbfc00000`
     244 - La quatrième le code binaire des instructions (sur 4 octets bien sûr)
     245 - Le reste de la ligne contient l'instruction désassemblée (décodée)
     246 - Lorsque les adresses ont un nom, c'est-à-dire qu'une étiquette leur a été attribuée, celle-ci est indiquée.
     247
     248 `label0.s` contient la séquence des appels de fonctions de l'exécutions. C'est en fait un extrait de la trace.\\Ouvrez les fichiers `trace0.s` et `label0.s` et interprétez ce que vous voyez.\\A quoi correspond les messages `READ` et `WRITE` dans le fichier `trace0.s`?
    246249{{{#!protected ------------------------------------------------------------------------------------
    247250''
     
    260263''
    261264}}}
    262 - Modifiez le code de `hcpua.S` afin d'afficher le message "Au revoir\n" après le message "Hello".\\
    263   Vous devez avoir deux messages, et pas seulement étendre le premier.
     265- Modifiez le code de `hcpua.S` afin d'afficher le message "Au revoir\n" après le message "Hello...".\\
     266  Vous devez avoir un message en plus, et pas seulement étendre le premier.
    264267{{{#!protected ------------------------------------------------------------------------------------
    265268''
     
    274277
    275278
    276 Dans le deuxième programme, nous restons en assembleur, mais nous avons deux fichiers source : (1) le fichier contenant
    277 le code de boot et (2) le fichier contenant le code du noyau. Ici, le code du noyau c'est juste une ''fonction'' `kinit()`. Ce n'est pas vraiment une fonction car on n'utilise pas la pile.
     279Rendez-vous dans le répertoire `tp1/2_init_asm`.\\Dans ce deuxième programme, nous restons en assembleur, mais nous avons deux fichiers source :
     2801. le fichier contenant le code de boot et
     2812. le fichier contenant le code du noyau. Ici, le code du noyau c'est juste une ''fonction'' `kinit()`.\\Ce n'est pas vraiment une fonction car on n'utilise pas la pile.
     282
    278283
    279284**Objectifs**
     
    294299**Questions**
    295300
    296 1. Regarder dans le fichier `hcpua.S`, dans quelle section est désormais le code de boot ?
     3011. Regarder dans le fichier `hcpua.S`, dans quelle section est désormais le code de boot ? (on a changé par rapport à l'exercice précédent)
    297302{{{#!protected ------------------------------------------------------------------------------------
    298303''
     
    300305''
    301306}}}
    302 2. Le code de boot ne fait que sauter à l'adresse `kinit` avec l'instruction `jr`,
    303    il n'y a pas de retour, ce n'est donc pas un `jal`. Où est défini `kinit` ?
     3072. Le code de boot ne fait que sauter à l'adresse `kinit` avec l'instruction **`jr`**,
     308   il n'y a pas de retour, ce n'est donc pas un **`jal`**. Où est défini l'étiquette `kinit` ?
    304309   Comment le code de boot connait-il cette adresse ?
    305310   Pourquoi ne pas avoir utilisé `j init` et donc pourquoi passer par un registre ?
     
    307312''
    308313- `kinit` est défini dans la `kinit.S`.
    309 - `hcpua.S` ne connait pas cette adresse, mais grâce au `.globl kinit`, l'éditeur de lien saura compléter `hcpua.o`, dans l'exécutable.
    310 - Le code de boot est en `0xBFC00000`, `kinit` est en `0x80000000`, ces deux adresses ne partagent pas les 4 bits de poids fort, c'est trop loin pour un simple `j`.
    311 ''
    312 }}}
    313 1. Dans `kernel.ld`, que signifie `*(.*data*)` ?
     314- `hcpua.S` ne connait pas cette adresse, mais grâce au `.globl kinit`, l'éditeur de lien saura compléter `hcpua.o` quand il fabriquera l'exécutable.
     315- Le code de boot est en `0xBFC00000`, `kinit` est en `0x80000000`, ces deux adresses ne partagent pas les 4 bits de poids fort, c'est trop loin pour un simple **`j`**.
     316''
     317}}}
     3181. Dans `kernel.ld`, que signifie `*(.*data*)` ? (C9 S38+S39)
    314319{{{#!protected ------------------------------------------------------------------------------------
    315320''
     
    348353
    349354
    350 Dans ce troisième programme, nous faisons la même chose que pour le deuxième mais `kinit()` est désormais écrit en
    351 langage C. Cela change peu de choses, sauf une chose importante `kinit()` est une fonction et donc il faut absolument
    352 une pile d'exécution.
     355Rendez-vous dans le répertoire `tp1/3_init_c`.\\Dans ce troisième programme, nous faisons la même chose que pour le deuxième mais `kinit()` est désormais écrit en langage C. Cela change peu de choses, sauf une chose importante `kinit()` est une fonction et donc il faut absolument
     356une pile d'exécution avant d'y entrer. Il faut donc initialiser **`$29`**.
    353357
    354358**Objectifs**
    355359
    356 - Savoir comment et où déclarer la pile d'exécution du noyau.
    357 - Savoir comment afficher un caractère sur un terminal depuis un programme C.
     360- Savoir comment et où déclarer la pile d'exécution du noyau au démarrage (cela changera plus tard).
     361- Savoir comment afficher un caractère sur un terminal **depuis un programme C**.
    358362
    359363**Fichiers**
     
    392396''
    393397}}}
    394 - Ouvrez les fichiers `kinit.o.s` et `kernel.x.s`, le premier fichier est le désassemblage de `kinit.o` et le second est le désassemblage de `kernel.x`. Dans ces fichiers, vous avez plusieurs sections. Les sections `.MIPS.abiflags`, `.reginfo` et `.pdr` ne nous sont pas utiles (elles servent au chargeur d'application, elles contiennent des informations sur le contenu du fichier et cela ne nous intéresse pas).\\Notez l'adresse de `kinit` dans les deux fichiers, sont-ce les mêmes ? Sont-elles dans les mêmes sections ? Expliquez pourquoi.
     398- Ouvrez les fichiers `kinit.o.s` et `kernel.x.s`, le premier fichier est le désassemblage de `kinit.o` et le second est le désassemblage de `kernel.x`. Dans ces fichiers, vous avez plusieurs sections. Les sections `.MIPS.abiflags`, `.reginfo` et `.pdr` ne nous sont pas utiles (elles servent au chargeur d'application, elles contiennent des informations sur le contenu du fichier et cela ne nous intéresse pas).\\Notez l'adresse de `kinit` dans les deux fichiers, sont-ce les mêmes ? Sont-elles dans les mêmes sections ? Expliquez pourquoi (c'est simple si vous avez compris le rôle de l'éditeur de liens).
    395399{{{#!protected ------------------------------------------------------------------------------------
    396400''
     
    405409{{{#!protected ------------------------------------------------------------------------------------
    406410''
    407 * Hormis, qu'il s'agit de code C, il n'y a pas de différence de principe, c'est toujours du copier-coller, l'important c'est d'ouvrir le code.
     411* Hormis, qu'il s'agit de code C, il n'y a pas de différence de principe, c'est toujours du copier-coller, l'important c'est d'ouvrir le code et de jouer avec.
    408412''
    409413}}}
     
    415419
    416420
    417 Le prototype de SoC que nous utilisons pour les TP est configurable. Il est possible par exemple de choisir le nombre de terminaux texte (TTY). Par défaut, il y en a un mais, nous pouvons en avoir jusqu'à 4. Nous allons modifier le code du noyau pour s'adapter à cette variabilité. En outre, pour le moment, nous ne faisions qu'écrire sur le terminal, maintenant, nous allons aussi lire le clavier.
     421Rendez-vous dans le répertoire `tp1/4_nttys`.\\Le prototype de SoC que nous utilisons pour les TP est configurable. Il est possible par exemple de choisir le nombre de terminaux texte (TTY). Par défaut, il y en a un, mais nous pouvons en avoir jusqu'à 4. Nous allons modifier le code du noyau pour s'adapter à cette variabilité. En outre, pour le moment, nous ne faisions qu'écrire sur le terminal, maintenant, nous allons aussi lire le clavier.
    418422
    419423**Objectifs**
     
    434438**Questions**
    435439
    436 1. Dans le fichier `kinit.c`, il est question d'un loopback, à quoi cela sert-il ?
     4401. Dans le fichier `kinit.c`, dans la boucle `while` de la fonction `kinit()`, il est question d'un loopback, à quoi cela sert-il ? (Vous devez lire le code et les commentaires de cette fonction pour comprendre).
    437441{{{#!protected ------------------------------------------------------------------------------------
    438442''
     
    441445''
    442446}}}
    443 1. Dans le fichier `kinit.c`, on trouve `__tty_regs_map[ tty%NTTYS ].write = *s`, expliquez le modulo.
    444 {{{#!protected ------------------------------------------------------------------------------------
    445 ''
    446 * C'est une sécurité, un peu inutile ici, qui permet de ne pas écrire en dehors de la zone des registres du contrôleur de tty
     4471. Dans le fichier `kinit.c`, on trouve `__tty_regs_map[ tty%NTTYS ].write = *s`, expliquez le modulo. Pour répondre à cette question, vous devez avoir compris comment sont rangés les registres de commande dans le contrôleur de TTY (C9 S10), et comprendre que le programmeur pourrait mettre n'importe quoi dans la variable `tty` et qu'on ne veut pas de bug !
     448{{{#!protected ------------------------------------------------------------------------------------
     449''
     450* C'est une sécurité, un peu inutile ici, qui permet de ne pas écrire en dehors de la zone des registres du contrôleur de tty.
    447451''
    448452}}}
     
    450454{{{#!protected ------------------------------------------------------------------------------------
    451455''
    452 - Deux fenêtres sont apparues avec un message uniquement dans la fenêtre `proc0_term0`.
    453 - Non. Quand on tape dans la fenêtre `proc0_term0`, les touches tapées s'affichent alors que rien ne se passe dans la fenêtre `proc0_term1`.
     456- Deux fenêtres sont apparues avec un message uniquement dans la fenêtre `xterm0`.
     457- Non. Quand on tape dans la fenêtre `xterm0`, les touches tapées s'affichent alors que rien ne se passe dans la fenêtre `xterm1`.
    454458''
    455459}}}
     
    457461**Exercices**
    458462
    459 - Modifiez le code pour afficher un message sur le second terminal, il y a toujours une attente sur le premier terminal.
     463- Modifiez le code pour afficher un message sur le terminal `xterm1`, il y a toujours une attente sur le premier terminal.
    460464{{{#!protected ------------------------------------------------------------------------------------
    461465''
     
    463467''
    464468}}}
    465 - Modifiez le code pour que le programme affiche les touches tapées au clavier sur les deux terminaux. C'est-à-dire, ce que vous tapez sur le terminal `proc0_term0` s'affiche sur ce même terminal, et pareil pour `proc0_term1`. L'idée est de ne plus faire d'attente bloquante sur le registre `TTY_STATUS` de chaque terminal. Pour que cela soit plus amusant, changez la casse (minuscule ←→ majuscule) sur le terminal `proc1_term1` (si vous tapez `bonjour 123`, il affiche `BONJOUR 123` et inversement.
     469- Modifiez le code pour que le programme affiche les touches tapées au clavier sur les deux terminaux. C'est-à-dire, ce que vous tapez sur le terminal `xterm0` s'affiche sur ce même terminal, et pareil pour `xterm1`. L'idée est de ne plus faire d'attente bloquante sur le registre `TTY_STATUS` de chaque terminal. Pour que cela soit plus amusant, changez la casse (minuscule ←→ majuscule) sur le terminal `proc1_term1` (si vous tapez `bonjour 123`, il affiche `BONJOUR 123` et inversement).
    466470{{{#!protected ------------------------------------------------------------------------------------
    467471''
     
    508512
    509513
    510 Dans l'étape précédente, nous accédons aux registres de périphérique directement dans la fonction `kinit()`, ce n'est pas très simple. C'est pourquoi nous allons ajouter un niveau d'abstraction qui représente un début de pilote de périphérique (device driver). Ce pilote, même tout petit constitue une couche logicielle avec une API.
     514Rendez-vous dans le répertoire `tp1/5_driver`.\\Dans l'étape précédente, nous accédons aux registres de périphérique directement dans la fonction `kinit()`, ce n'est pas très simple. C'est pourquoi nous allons ajouter un niveau d'abstraction qui représente un ''début'' de pilote de périphérique (device driver). Ce pilote, même tout petit constitue une couche logicielle avec une API.
    511515
    512516**Objectifs**