Changes between Version 88 and Version 89 of SoclibCourseTp4
- Timestamp:
- Dec 15, 2011, 8:04:47 PM (13 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
SoclibCourseTp4
v88 v89 18 18 19 19 Il existe deux types de périphériques: 20 * Un ''périphérique caractère'' (tel qu'un contrôleur TTY) supporte des requêtes de lecture ou d'écriture d'un seul caractère. Ce type de périphérique se comportecomme une cible sur le bus, puisqu'il ne peut que recevoir des commandes provenant d'un processeur, et qu'il n'a pas la possibilité de lire ou d'écrire lui-même en mémoire. Le contrôleur de périphérique utilise une interruption pour signaler au système d'exploitation qu'un événement (tel qu'un caractère frappé au clavier) s'est produit du côté du périphérique.21 22 * Un ''périphériquesbloc'', tel qu'un contrôleur de disque, doit tranférer de grosses quantités de données entre la mémoire et le disque. Les transferts se font par blocs (un bloc contenant généralement 512 octets), et ces périphériques ont généralement une capacité DMA : Ils sont à la fois maître et cible sur le bus, cat ils reçoivent des commandes définissant le transfert à effectuer, mais peuvent ensuite directement lire ou écrire en mémoire. Le contrôleur de périphérique utilise une interruption pour signaler au système d'exploitation la fin du transfert.20 * Un périphérique ''orienté caractère'' (tel qu'un contrôleur TTY) supporte des requêtes de lecture ou d'écriture d'un petit nombre de caractères. Ce type de périphérique se comporte généralement comme une cible sur le bus, puisqu'il ne peut que recevoir des commandes provenant d'un processeur, et qu'il n'a pas la possibilité de lire ou d'écrire lui-même en mémoire. Le contrôleur de périphérique utilise une interruption pour signaler au système d'exploitation qu'un événement (tel qu'un caractère frappé au clavier) s'est produit du côté du périphérique. 21 22 * Un périphérique orienté ''bloc'', tel qu'un contrôleur de disque, doit tranférer de grosses quantités de données entre la mémoire et le disque. Les transferts se font par blocs (un bloc contenant généralement 512 octets), et ces périphériques ont généralement une capacité DMA : Ils sont à la fois maître et cible sur le bus, cat ils reçoivent des commandes définissant le transfert à effectuer, mais peuvent ensuite directement lire ou écrire en mémoire. Le contrôleur de périphérique utilise une interruption pour signaler au système d'exploitation la fin du transfert. 23 23 24 24 == 2.1 composants matériels == … … 26 26 Lorsque le nombre de périphériques augmente, le nombre de lignes d'interruption augmente également, 27 27 et il faut un mécanisme permettant de concentrer plusieurs dizaines de requêtes d'interruption vers un seul signal 28 connecté au processeur. C'est en interrogeant le composant matériel ICU que le système d'exploitation (en pratique le gestionnaire d'interruption) peut obtenir le numéro de la ligne d'interruption activéla plus prioritaire.28 connecté au processeur. C'est en interrogeant le composant matériel ICU (Interrupt Controler Unit) que le système d'exploitation (en pratique le gestionnaire d'interruption) peut obtenir le numéro de la ligne d'interruption active la plus prioritaire. 29 29 30 30 Le composant '''vci_icu''' est un contrôleur d'interruptions vectorisées. C'est une cible VCI dont vous trouverez la spécification fonctionnelle [https://www.soclib.fr/trac/dev/wiki/Component/VciIcu ici]. Prenez le temps de la lire. … … 65 65 66 66 Dans le TP3, le programme utilisateur utilise l'appel système '''tty_getc()''' pour lire un caracère. 67 Cet appel système bloquantcontient une boucle de scrutation dans laquelle, à chaque tour de boucle,68 oneffectue une transaction sur le bus pour lire la valeur du registre STATUS du terminal TTY concerné.67 Cet appel système contient une boucle de scrutation dans laquelle, à chaque tour de boucle, 68 le processeur effectue une transaction sur le bus pour lire la valeur du registre STATUS du terminal TTY concerné. 69 69 On ne sort de cette boucle que lorsqu'un caractère a effectivement été saisi au clavier. 70 70 … … 74 74 qui est à la fois protégé (non accessible par les programmes utilisateur) et non cachable. 75 75 76 Plutôt que d'effectuer une scrutation sur le registre STATUS du contrôleur TTY, l'appel système '''tty_get_irq()''' 77 teste la variable '''_tty_get_full''' rangée en mémoire. Si la valeur de cette variable indique qu'il n'y a pas de caractère 78 disponible, le système d'exploitation peut (en principe) attribuer le processeur à un autre programme utilisateur. C'est la routine d'interruption (ISR) associée au terminal TTY qui se charge d'écrire le code ASCII du caractère dans le tampon '''_tty_get_buf''', et de forcer à 1 la variable de synchronsation '''_tty_get_full''' pour signaler que le tampon est plein. Cette variable de synchronisation est remise à 0 par l'appel système ''tty_getc_irq()'' lorsque le caractère est transféré du tampon système '''tty_get_buf''' vers le tampon mémoire défini par l'utilisateur. 76 Plutôt que d'accéder directement au registre STATUS du contrôleur TTY, l'appel système '''tty_get_irq()''' 77 teste la variable '''_tty_get_full''' rangée en mémoire. C'est la routine d'interruption (ISR) associée au terminal TTY qui se charge d'écrire le code ASCII du caractère dans le tampon '''_tty_get_buf''', et de forcer à 1 la variable de synchronsation '''_tty_get_full''' pour signaler que le tampon est plein. Cette variable de synchronisation est remise à 0 par l'appel système ''tty_getc_irq()'' lorsque le caractère est transféré du tampon système '''tty_get_buf''' vers le tampon mémoire défini par l'utilisateur. 79 78 80 79 Dans une architecture monoprocesseur, le processeur peut exécuter plusieurs tâches (plusieurs programmes utilisateurs) en pseudo-paralléliseme, par multiplexage temporel. Chaque tâche possède alors son propre terminal écran/clavier, mais ces 81 différents terminaux sont tous contrôlés par le même contrôleur TTY : Chaque terminal ason propre jeu de 4 registres,80 différents terminaux sont tous contrôlés par le même contrôleur TTY : Chaque terminal possède son propre jeu de 4 registres, 82 81 pour communiquer avec l'OS. 83 82 … … 100 99 L'appel système '''ioc_completed()''', qui appelle lui-même la fonction système '''_ioc_completed()''' permet au programme utilisateur de se mettre en attente sur la fin d'un transfert. C'est donc une fonction bloquante qui ne rend la main au programme utilisateur que lorsque le transfert est effectivement terminé. 101 100 102 '''Question''' : Que se passe-t-il si un programme utilisateur A effectue un appel système '''_ioc_read()''' alors que le contrôleur de disque est déjà en train d'exécuter un transfert à la demande d'un autre programme utilisateur B? 101 '''Question''' : Le contrôleur de disque utilisé ici ne peut effectuer qu'un seul transfert de données à la fois. 102 Que se passe-t-il si un programme utilisateur A effectue un appel système '''_ioc_read()''' alors que le contrôleur de disque est déjà en train d'exécuter un transfert à la demande d'un autre programme utilisateur B? 103 104 '''Question''': Si deux programmes utilisateurs s'exécutant en parallèle sur deux processeurs différents demandent simultanément à utiliser le contrôleur de disque, comment le GIET peut-il garantir que le périphérique ne sera alloué qu'à un seul des deux demandeurs? 105 103 106 104 107 = 3 Modélisation de l'architecture matérielle = … … 115 118 116 119 '''Question''' : Complétez le fichier '''tp4_top.cpp''' pour définir les arguments des constructeurs des composants ICU, TIMER, IOC, FBF, DMA et BUS. Pour le composant IOC on fera en sorte que le cheminom désignant le fichier 117 externe puisse être redéfini par un paramètre sur la ligne de commande au lancement du simulateur. Pour le composant 118 FBF, on choisira une taille d'écran de 128 lignes de 128 pixels. 120 externe puisse être redéfini par un paramètre sur la ligne de commande au lancement du simulateur. Pour le composant FBF, on choisira une taille d'écran de 128 lignes de 128 pixels. 119 121 120 122 '''Question''' : Complétez la net-list dans le fichier '''tp4_top.cpp''' pour connecter les 4 lignes d'interruption utilisées dans cette architecture mono-processeur, et pour connecter sur le bus les 3 initiateurs et les 3 cibles. … … 174 176 175 177 '''Question''' : Ecrivez un nouveau programme main_1 dans un fichier '''main_1.c'''. Vous utiliserez les appels système '''ioc_read()''' et '''ioc_completed()''' pour charger une image dans un tampon mémoire de 128*128 octets tab[128][128], déclaré dans la fonction main(). Dans quel segment sera rangéé ce tableau tab[128][128]? 176 Utilisez l'appel système '''fbf_ write()''' pour afficher cette image sur l'écran graphique.178 Utilisez l'appel système '''fbf_sync_write()''' pour afficher cette image sur l'écran graphique. 177 179 N'oubliez pas de tester systématiquement la valeur du code de retour chaque fois que vous utilisez un appel système. 178 180 Modifiez le Makefile pour utiliser main_1.c au lieu de main_0.c, compilez le logiciel embarqué, et exécutez-le sur le simulateur. … … 193 195 composant !VciTimer peut contenir jusque 256 timers indépendants, on utilisera un seul composant !VciTimer. 194 196 195 * Le GIET ne pouvant supporter que 8 processeurs, on vérifiera que le paramètre NPROCS est inférieur ou égal à 8.196 197 * Il faut définir des tableaux de pointeurs indexés par l'index du processeurs (proc_id) pour les composants répliqués PROC[i], TTY[i] et ICU[i] ainsi que pour les signaux connectés à ces composants.197 * Le GIET ne pouvant supporter que 8 processeurs, on vérifiera dans le code de la top-cell que le paramètre NPROCS est inférieur ou égal à 8. 198 199 * Pour les composants répliqués PROC[i], TTY[i] et ICU[i] ainsi que pour les signaux connectés à ces composants, il faut définir des tableaux de pointeurs indexés par l'index du processeurs (proc_id). 198 200 199 201 * Pour les tableaux de signaux, il est recommandé d'utiliser le constructeur générique de tableaux '''alloc_elems<type>(name, size)'''. Ce constructeur est défini dans le fichier '''alloc_elems.h''', qu'il ne faut pas oublier d'inclure dans la top-cell. … … 205 207 * Pour l'index des cibles (TGTID), on utilisera les valeurs (0) à (6) pour les composants matériels non répliqués (ROM, RAM GCD, TIMER, IOC, DMA, FBF). On utilisera les valeurs (7) à ( 7 + NPROCS -1) pour les composants TTY[i]. On utilisera les valeurs (7 + NPROCS) à (7 + 2*NPROCS -1) pour les composants ICU[i]. 206 208 207 * il faut définir NPROCS segments pour les composants ICU[i]. L'adresse de base du segment associé au composant ICU[i] est définie comme : seg_icu_base + 0x00100000 * proc_id (cette contrainte est imposée par le GIET).208 209 * Il faut définir NPROCS segments pour les NPROCS TTY[i]. L'adresse de base du segment associé au composant ICU[i] est définie comme : seg_tty_base + 0x00100000 * proc_id (cette contrainte est imposée par le GIET).209 * il faut définir NPROCS segments pour les composants ICU[i]. L'adresse de base du segment associé au composant ICU[i] est définie comme : seg_icu_base + icu_segment_increment * proc_id. La valeur de cette variable devra donc être définie dans le fichier '''tp4_top_multi.cpp pour le matériel, et dans le fichier '''ldscript''' pour le logiciel. On prendra par exemple la valeur 0x00100000. 210 211 * Il faut définir NPROCS segments pour les NPROCS TTY[i]. L'adresse de base du segment associé au composant ICU[i] est définie comme : seg_tty_base + tty_segment_increment * proc_id. On prendra également la valeur 0x00100000. 210 212 211 213 * Pour la net-list, il faut utiliser des boucles indexées par l'index du processeur pour connecter les composants répliqués et signaux répliqués. … … 221 223 Un vrai système d'exploitation tel que LINUX (ou MutekH) permet de créer dynamiquement de nouvelles tâches (i.e. de nouveaux programmes utilisateurs) alors que la machine est déjà démarrée (mécanisme ''pthread_create()'' pour les threads POSIX, ou mécanisme fork/exec pour les processus UNIX). Le GIET n'est pas un vrai système d'exploitation, car il ne supporte pas la création ou la destruction dynamique de tâches : Les tâches doivent être créées une fois pour toute au démarrage de la machine, c'est à dire dans le code de boot. 222 224 223 Bien que le GIET supporte le fonctionnement multi-tâches (un seul processeur exécute plusieurs tâches en pseudo-parallélisme par multiplexage temporel), on va utiliser ici un mécanisme plus simple où chaque processeur n'exécute qu'une seule tâche, qui lui est assignéedans le code de boot.225 On va utiliser ici un mécanisme simple où chaque processeur n'exécute qu'une seule tâche, qui lui est assignée une fois pour toutes dans le code de boot. 224 226 225 227 Le mécanisme est le suivant :