Changes between Version 24 and Version 25 of SoclibCourseTp3


Ignore:
Timestamp:
Sep 26, 2009, 3:05:23 PM (16 years ago)
Author:
alain
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • SoclibCourseTp3

    v24 v25  
    2323[[Image(soclib_tp3_archi.png)]]
    2424
    25  * '''xcache''' est un processeur MIPS32 avec ses caches L1. On utilise le composant ''!VciXcacheWrapper'', qui est un contrôleur de cache à interface VCI.  Ce composant générique encapsule un composant ''!Mips32Iss'', qui modélise un coeur de processeur MIPS32.
     25 * '''xcache''' est un processeur MIPS32 avec ses caches L1. On utilise le composant ''!VciXcacheWrapper'', qui est un contrôleur de cache à interface VCI.  Ce composant générique encapsule un autre composant ''!Mips32Iss'', qui modélise un coeur de processeur MIPS32.
    2626 * '''rom''' est une mémoire non inscriptible à interface VCI contenant le code de boot. On utilise le composant ''!VciSimpleRam''.
    2727 * '''ram''' est une mémoire inscriptible à interface VCI contenant le code et les données. On utilise également un composant ''!VciSimpleRam''.
    2828 * '''tty''' est un périphérique adressable de type écran/clavier à interface VCI. On utilise le composant ''!VciMultiTty''.
    29  * '''lcd''' est le coprocesseur cible réalisant le calcul du PGCD. On utilise évidemment le composant ''!VciLcdCoprocessor''.
    30  * '''vgsb''' est le bus système déjà utilsé dans le TP2. On utilise le composant ''!VciVgsb''.
     29 * '''gcd''' est le coprocesseur cible réalisant le calcul du PGCD. On utilise évidemment le composant ''!VciGcdCoprocessor''.
     30 * '''vgsb''' est le bus système déjà utilisé dans le TP2. On utilise le composant ''!VciVgsb''.
    3131
    3232Les modèles de simulation des composants matériels instanciés dans cette architecture sont disponibles dans la bibliothèque SoCLib.
     
    3434pour chacun de ces composants sur le site WEB de !oCLib :  [https://www.soclib.fr/trac/dev/wiki/Component]
    3535
    36 Le composant ''!VciXcacheWrapper'' est un contrôleur de cache générique à interface VCI, qui peut être utilisé pour interfacer
    37 différents coeurs de processeur avec le reste du système. Le coeur du processeur est modélisé par un ISS (Instruction Set Simulateur).
    38 Le type du proceseur instancié (MIP32, ARM, SPARCV8, PPC405, NIOS, !MicroBlaze, etc.) est défini par un paramètre template
    39 du composant ''!VciXcacheWrapper''.
     36Le composant ''!VciXcacheWrapper'' peut être utilisé pour encapsuler différents processeur 32 bits. Le coeur du processeur est modélisé par un ISS (Instruction Set Simulateur).
     37Le type du proceseur instancié (MIP32, ARM, SPARCV8, PPC405, NIOS, !MicroBlaze, etc.) est défini par un paramètre template du composant ''!VciXcacheWrapper''.
     38Consultez la documentation [https://www.soclib.fr/trac/dev/wiki/Component/VciXcacheWrapper ici].
    4039
    4140Le composant ''!VciSimpleRam'' est utilisé pour modéliser des mémoires inscriptibles embarquées (SRAM), ou
    42 pour modéliser des mémoires non inscriptibles (ROM) dont le contenu est ''cablé''.
     41pour modéliser des mémoires non inscriptibles (ROM).
    4342Ce composants peut contenir un ou plusieurs segments (correspondant à des tranches disjointes
    44 de l'espace addressable). Cela signifie que ce composant analysee les bits de poids fort de l'adresse VCI
    45 pour déterminer le segment désigné. Les dimensions des tableaux qui implémentent les bancs mémoire
    46 physique sont définis par les longueurs des segments définis dans la !MappingTable.
    47 
    48 Enfin le composant ''!VciMultiTty'' est un contrôleur de terminaux alpha-numériques. Ce contrôleur peut modéliser de 1 à 256
    49 terminaux (un terminal est une paire écran / clavier). Pratiquement, chaque terminal est modélisé par l'ouverture
    50 d'une fenêtre XTERM indépendante sur l'écran de la station de travail qui exécute la simulation.
    51 Chaque terminal possède 4 registres adressables pour la lecture ou l'écriture, et on ne peut lire ou écrire qu'un seul caractère par transaction.
    52  
     43de l'espace addressable). Le composant analyse les bits de poids fort de l'adresse VCI
     44pour déterminer le segment désigné. Les bancs de mémoire physique correspondant aux différents segments
     45sont modélisés par des tableaux C++ dont la longueur est définie par les valeurs stockées dans la !MappingTable.
     46Consultez la documentation [https://www.soclib.fr/trac/dev/wiki/Component/VciSimpleRam ici].
     47
     48Enfin le composant ''!VciMultiTty'' est un contrôleur de terminaux alpha-numériques. Ce composant peut contrôler de 1 à 256 terminaux (un terminal est une paire écran / clavier). Pratiquement, chaque terminal est modélisé par l'ouverture d'une fenêtre XTERM indépendante sur l'écran de la station de travail qui exécute la simulation.
     49Chaque terminal possède 4 registres adressables pour la lecture ou l'écriture, et fonctionne en mode ''caractère'':
     50on ne peut lire ou écrire qu'un seul caractère par transaction.
     51Consultez la documentation [https://www.soclib.fr/trac/dev/wiki/Component/VciMultiTty ici]. 
     52
    5353= 3 Génération et chargement du logiciel embarqué =
    5454
    5555Il existe plusieurs façons de définir et de générer le code binaire qui sera exécuté par le (ou les) processeur(s) du
    5656MPSoC. Si on part d'une application logicielle écrite en langage C, il faut utiliser un cross-compilateur spécifique
    57 pour le processeur choisi. Le résultat est un fichier binaire au format ELF. Le code binaire correspondant doit
    58 être chargé dans les mémoires embarquées du MPSoC.  Il y a donc deux étapes bien distinctes, qui sont la génération du fichier ELF, et le chargement.
     57pour le processeur choisi. Le résultat est un fichier binaire au format ELF. Le code binaire correspondant doit ensuite
     58être chargé dans les mémoires embarquées du MPSoC.  Il y a donc deux étapes bien distinctes pour la génération et le chargement.
    5959
    6060== 3.1 Génération du code ==
     
    6262Les composants de la bibliothèque SoCLib permettent de modéliser des architectures matérielles complexes, capables d'exécuter des
    6363systèmes d'exploitation avancés (tels que LINUX, Unix NetBSD, ou MUTEK). Mais dans ce TP et les suivants, on se contentera d'un
    64 ''système d'exploitation'' minimal, constitué par un Gestionnaire d'Interruptions, Eceptions et Trappes (GIET), quelques appels systèmes
     64''système d'exploitation'' minimal, constitué par un Gestionnaire d'Interruptions, Exceptions et Trappes (GIET), quelques appels systèmes
    6565permettant aux programmes utilisateurs d'accéder aux périphériques, plus le code boot pour initialiser la machine.
    66 Tout ce code ''système'' est directement écrit en assembleur MIPS32 et vous est fourni. Les programmes utilisateurs seront écrits en langage C,
    67 et seront écrits par vous.
     66Tout ce code ''système'' est  écrit en C et en assembleur MIPS32, et il vous est fourni. Les programmes utilisateurs seront écrits en langage C, et seront écrits par vous.
    6867
    6968Les processeurs disponibles dans SoCLib, sont en majorités des processeurs RISC, capables
    7069de démarrer une instruction à chaque cycle, grâce à leur structure pipe-line.
    71 Chaque processeur est modélisé par un ISS (Instruction Set Simulator), qui doit - pour chaque instruction -
    72 lire l'instruction dans le cache, la décoder et l'exécuter. C'est évidemment le contrôleur du cache qui se charge d'aller
    73 lire le code binaire chargé dans les mémoires embarquées en cas de MISS.
    74 
    75 Ce code binaire doit donc être généré par un cross-compilateur spécifique. Dans le cas du processeur MIPS32, on utilise la chaîne de compilation GCC,
    76 pour compiler l'ensemble du logiciel embarqué (code applicatif en C, et code système en assembleur MIPS32), et générer du code MIPS32.
    77 
    78 Le résultat de cette compilation est un fichier au format ELF, contenant le code binaire exécutable par le processeur MIP32.
     70Le processeur doit, à chaque instruction lire l'instruction dans le cache, la décoder et l'exécuter. C'est évidemment le contrôleur du cache qui se charge d'aller lire le code binaire chargé dans les mémoires embarquées en cas de MISS.
     71
     72Le code binaire doit donc être généré par un cross-compilateur spécifique pour le processeur MIPS32. On utilise la chaîne de compilation GCC, pour compiler l'ensemble du logiciel embarqué (code applicatif et code système) et pour réaliser l'édition de liens entre le code applicatif écrit par vous, et le code système. Le résultat de cette compilation est un fichier au format ELF, contenant le code binaire exécutable par le processeur MIP32.
    7973
    8074== 3.2 Chargement du code ==
     
    107101
    108102Cette archive contient un très grand nombre de fichiers, car les composants instanc!és sont des objets complexes,
    109 qui font appel à beaucoup de code ''caché'' : le chargement initial  des mémoires embarquées ROM et RAM nécessite l'analyse du format de fichier binaire ELF.
     103qui font appel à beaucoup de code ''caché'' : Par exemple, le chargement initial  des mémoires embarquées ROM et RAM nécessite l'analyse du format de fichier binaire ELF.
    110104De même, l'utilisation d'un contrôleur de terminal suppose l'ouverture d'une ou plusieurs fenêtres XTERM sur la station de travail qui exécute la simulation.
    111105
     
    113107fichiers objets qui doivent être compilés pour générer le simulateur de cette architecture très simple.
    114108
    115 L'archive fournie contient en particulier les fichiers suivants correspondant aux modèles des composants instanciés :
    116  * `vci_xcache_wrapper.h` : définition du composant `VciXcacheWrapper`
    117  * `vci_xcache_wrapper.cpp` : méthodes associées
    118  * `vci_lcd_coprocessor.h` : définition du composant `VciLcdCoprocessor`
    119  * `vci_lcd_coprocessor.cpp` : méthodes associées
    120  * `vci_simple_ram.h` : définition du composant `VciSimpleRam`
    121  * `vci_simple_ram.cpp` : méthodes associées
    122  * `vci_multi_tty.h` : définition du composant `VciMultiTty`
    123  * `vci_multi_tty.cpp` : méthodes associées 
    124  * `vci_vgsb.h` : définition du composant `VciVgsb`
    125  * `vci_vgsb.cpp` : méthodes associées
    126  * `tp3_top.cpp` : top-cell de l'architecture
    127 
    128109Elle contient également un sous-répertoire ''soft'' qui est utilisé pour la génération du logiciel embarqué.
    129110
     
    132113Cette architecture nécessite la définition de 7 segments:
    133114
    134  * '''seg_tty''' est le segment associé au contrôleur de terminaux TTY. On prendra pour adresse de base la valeur 0xC0000000, et pour longueur 64 octets, ce qui permet d'adresser jusqu'à 4 terminaux indépendants (consulter la spécification fonctionnelle du composant VciMultiTty).
    135  * '''seg_lcd''' est le segment associé au coprocesseur LCD. On prendra pour adresse de base la valeur 0x90000000. La longueur de 16 octets correspond aux quatre registres adressables de ce composant.
     115 * '''seg_tty''' est le segment associé au contrôleur de terminaux TTY. On prendra pour adresse de base la valeur 0xC0000000, et pour longueur 64 octets, ce qui permet d'adresser jusqu'à 4 terminaux indépendants.
     116 * '''seg_gcd''' est le segment associé au coprocesseur GCD. On prendra pour adresse de base la valeur 0x90000000. La longueur de 16 octets correspond aux quatre registres adressables de ce composant.
    136117 * '''seg_reset''' est le segment contenant contient le code de ''boot'' exécuté à la mise sous tension. Il est évidemment assigné à la ROM. L'adresse de base 0xBFC00000 est imposée par la spécification du processeur MIPS32. On choisira une capacité de stockage de 4Koctets.
    137118 * '''seg_kernel''' est le segment contenant le code du système qui s'exécute en mode ''kernel''. Il s'agit principalement du Gestionnaire d'Interruptions, Exceptions, et Trappes (GIET) et du code des appels systèmes. Ce segment  est assigné à la RAM. L'adresse de base 0x80000000 est imposée par la spécification du processeur MIPS32 qui impose que le point d'entrée est à l'adresse 0x80000180. On choisira une capacité de stockage de 4 Koctets. 
     
    140121 * '''seg_stack''' est le segment contenant la pile d'exécution de l'application logicielle embarquée. Il est assigné à la RAM. On choisira pour adresse de base la valeur 0x00800000, et une capacité de stockage de 64 Koctets.
    141122
    142 Remarquez que les 2 segments correspondant aux périphériques (seg_tty et seg_lcd), ainsi que les deux segments correspondant au code système sont dans la zone
    143 protégée de l'espace adressable, qui n'est accessible qu'en mode ''kernel''.
    144 
    145 '''Remarque importante''' : Ces informations de segmentation sont utilisées à la fois par le matériel et par le logiciel embarqué. Elles doivent donc être définies à deux endroits :
    146  1. Dans le fichier ''tp3_top.cpp'' pour définir le contenu de la !MappingTable, qui est utilisée configurer les composants matériels.
    147  1. Dans le fichier ''soft/ldscript'' qui est utilisé par l'éditeur de liens lors de la compilation du logiciel embarqué, pou définir les adresses de base des différents segments (mémoire et périphériques). 
    148 
    149 Complêtez les fichiers ''tp3_top.cpp'' et ''soft/ldsript'' pour définir les adresses de base et les longueurs des segments.
     123Remarquez que les 2 segments correspondant aux périphériques (seg_tty et seg_lcd), ainsi que les deux segments correspondant au code système sont dans la zone protégée de l'espace adressable, qui n'est accessible qu'en mode ''kernel'' (adresses supérieures à 0x80000000).
     124
     125'''Remarque importante''' : Certaines informations sont utilisées à la fois par le matériel et par le logiciel embarqué, et doivent donc être définies à deux endroits :
     126 1. Les addresses de base et les longueurs des segments sont utilisées par le matériel : Elles doivent être définies dans le fichier ''tp3_top.cpp'' pour ëtre stockées dans la !MappingTable, qui est est utilisée dans la phase de configuration du matériel par les constructeurs des composants. Ces mêmes adresses de base des segments sont utilisées par le logiciel et doivent être définies dans le fichier ''soft/ldscript'' qui contient les directives pour l'éditeur de liens lors de la compilation du logiciel embarqué.
     127 1. Le composant matériel générique ''!VciMultiTty'' peut contrôler un nombre variable de terminaux. Ce nombre de terminaux doit être défini dans le fichier ''tp3_top.cpp'' (pour le matériel), mais doit aussi être défini dans le  fichier ''soft/ldscript'', pour informer le système d'exploitation du nombre de terminaux adressables.
     128
     129Complêtez les fichiers ''tp3_top.cpp'' et ''soft/ldsript'' pour définir les adresses de base et les longueurs des segments,
     130ainsi que le nombre de terminaux utilisés.
    150131
    151132== 4.2 Compilation du logiciel embarqué ==
     
    153134Le logiciel embarqué est défini dans plusieurs fichiers source, que vous trouverez dans le répertoire ''soft''.
    154135Certains de ces fichiers sont écrits en assembleur MIPS32, certains sont écrits en C :
    155  * le fichier '''reset.s''' est écrit en assembleur et contient le code de boot qui est exécuté à la mise sous tension, ou lors de l'activation du signal NRESET. Ce code s'exécute en mode ''kernel'' et initialise quelques registres, avant d'exécuter l'instruction ''eret''.
    156  * le fichier '''giet.s''' est écrit en assembleur et contient le code du Gestionnaire d'Interruption, Exceptions et Trappes. Ce code s'exécute en mode ''kernel'', et se termine toujours par une instruction ''eret''.
    157  * le fichier '''syscall.s''' est écrit en assembleur et contient le code des quelques appels système disponibles sur cette plate-forme minimale. Ils s'exécutent en mode ''kernel'', et permettent l'accès aux périphériques.
    158  * le fichier '''stdlib.c''' est la version C des appels système définis dans le fichier ''syscalls.s''. Ces fonction C se contentent d'encapsuler l'instruction assembleur ''syscall'' après avoir placé les valeurs des arguments dans les registres appropriés. Elles peuvent donc être appelées depuis un programme s'exécutant en mode ''user''.
    159  * le fichier '''main.c''' est écrit en C et contient n'importequelle application logicielle qui se contente des quelques appels système définis dans ''stdlib.c''.
    160  * le fichier '''Makefile''' permet de lancer la compilation du logiciel embarqué.
    161 
    162 '''Question''' : Quels sont les appels système qui permettent d'accéder à un terminal TTY ? Quels sont les arguments des fonctions C correspondantes?
     136 * le fichier '''reset.s''' est écrit en assembleur et contient le code de boot qui est exécuté à la mise sous tension, ou lors de l'activation du signal NRESET. Ce code s'exécute en mode ''kernel'' et initialise quelques registres, avant de se brancher à la pemière instruction du programme ''main''.
     137 * le fichier '''giet.s''' est écrit en assembleur et contient le code du Gestionnaire d'Interruption, Exceptions et Trappes. Le GIET est l'unique point d'entrée dans le système d'exploitation. Ce code s'exécute en mode ''kernel'', et se termine toujours par une instruction ''eret''.
     138 * le fichier '''stdio.c''' est écrit en C, et contient le code des fonctions C permettant à un programme applicatif s'exécutant en mode ''user'' d'accéder aux périphériques ''mappés'' dans le segment ''kernel'', en effectuant des appels système.
     139 * le fichier '''syscalls.s''' est écrit en C et contient le code des appels systèmes proprement ditS. Ce code s'exécute en mode kernel, et permet l'accès aux périphériques ou aux registres protégés du processeur.
     140 * le fichier '''main.c''' est écrit en C et contient le code de l'application logicielle, qui peut évidemment utiliser
     141les fonctions définies dans le fichier ''stdio.c''.
     142 * le fichier '''ldscript''' contient les directives pour l'éditeur de liens.
     143 * le fichier '''Makefile''' permet de lancer la génération du logiciel embarqué.
     144
     145'''Question''' : Quels sont les appels système qui permettent d'accéder à un terminal TTY ? Lorsqu'il y a plusieurs terminaux dans l'architecture, comment est sélectionné le terminal cible ?
     146
    163147
    164148On rappelle que l'instruction ''eret'' de sortie du GIET ou du code de boot effectue principalemnt deux actions :
    165  1. Elle modifie le registre SR (registre 12 du coprocesseur ''système'') pour que le processeur retourne dans le mode où il était lorsqu'il a été dérouté par une interruption, une exception ou un appel système.
    166  1. Elle effectue un branchement à l'adresse contenue dans le registre EPC (registre 14 du coprocesseur ''système'').
    167 
    168 '''Question''' : Quels sont les registres initialisés par le code de boot ? pouquoi ces initialisations ?
    169 
    170 Puisqu'on dispose d'un contrôleur de terminal dans l'architecture, le premier programme que vous allez exécuter se contentera d'afficher le célèbre ''hello world'' sur le terminal. Ouvrez lz fichier ''soft/main.c''.
    171 
    172 '''Question''' : Que fait ce programme ? (on rappelle que la fonction ''getc()'' est bloquante, et ne rend pas la main au programme appelant tant qu'un caractère
    173 n'a pas été saisi au clavier).
     149 1. Elle modifie le registre protégé SR (registre 12 du coprocesseur ''système'') pour que le processeur retourne dans le mode où il était lorsqu'il a été dérouté par une interruption, une exception ou un appel système.
     150 1. Elle effectue un branchement à l'adresse contenue dans le registre protégé EPC (registre 14 du coprocesseur ''système'').
     151
     152'''Question''' : Quels sont les initialisations réalisées par le code de boot ? pouquoi ces initialisations ?
     153
     154Le premier programme que vous allez exécuter se contente d'afficher le célèbre ''hello world'' sur le terminal.
     155Ouvrez le fichier ''soft/main.c''.
     156
     157'''Question''' : Que fait ce programme ? (on rappelle que la fonction ''tty_getc()'' est bloquante, et ne rend pas la main  tant qu'un caractère n'a pas été saisi au clavier).
    174158
    175159Lancez l'exécution du Makefile. Deux fichiers ''soft.bin'' et ''soft.bin.txt'' doivent  être créé dans le répertoire ''soft'' :
     
    178162== 4.3 Définition de l'architecture matérielle ==
    179163
    180 Il faut  compléter le fichier ''tp3_top.cpp'', pour définir les segments enregistrés dans la MappingTable,
    181 définir les arguments des constructeurs ainsi que les valeurs des paramètres template des différents composants matériels instanciés,
    182 et définir le cheminom permettant au ''loader'' des composants ROM et RAM d'accéder au fichier ELF.
     164Complétez le fichier ''tp3_top.cpp'': Il faut enregister les 7 segments dans la MappingTable.
     165Il faut définir les arguments de tous les constructeurs des composants instanciés, ainsi que les valeurs de
     166leurs paramètres template. Il faut définir le cheminom permettant au ''loader'' des composants ROM et RAM
     167d'accéder au fichier ''soft/bin.soft'' contenant le code binaire.
    183168
    184169'''Question''' : Parmi les 7 segments utilisés dans cette l'architecture, lesquels doivent être déclarés cachables ?
     
    188173
    189174'''Question''' quels sont les bits d'adresse qui doivent être décodés par le contrôleur du cache, pour déterminer
    190 qu'une adresse appartient à un segment non-cachable, et doit être diredtement transmise à la mémoire ?
     175qu'une adresse appartient à un segment non-cachable, et doit être directement transmise à la mémoire ?
    191176Cette information est un autre argument du constructeur de la !MappingTable.
    192177
    193 Comme dans le TP2, il faut modifier tous les fichiers des composants qui possèdent des paramètres templates pour définir
    194 les valeurs de ces paramètres avant de générer le fichier objet correspondant.
    195 Il faut donc ajouter à la fin du fichier ''vci_lcd_coprocessor.cpp'' la ligne  :
     178Enfin, comme dans le TP2, il faut modifier tous les fichiers des composants SoCLib qui possèdent des paramètres templates pour définir  les valeurs de ces paramètres avant de générer le fichier objet correspondant.
     179Dans le cas du coprocesseur GCD, il faut modifier le fichier ''vci_gcd_coprocessor.cpp'' en ajoutant  :
    196180
    197181{{{
     
    205189== 4.5 Lancement de la simulation ==
    206190
    207 Lancez la simulation en lançant la commande habituelle:
     191Lancez la simulation en lançant la commande :
    208192{{{
    209193$ ./simulator.x 2000