• Aucun résultat trouvé

Chapitre 6 : GENERATION DES PILOTES EN COUCHES D'ACCES MEMOIRE

3. Flot de génération systématique des pilotes logiciels

Le flot que nous utilisons a été utilisé initialement pour la génération des systèmes d'exploitation [Gau01]. Nous l'avons étendu pour la génération des pilotes logiciels en couches spécifiques à la mémoire.

3.1. Entrée du flot

S p é c i f i c a t i o n l o g i c i e l-m a t é r i e l ( V A D e L ) A B C

Bibliothèque logicielle : macro-m o d è l e s d ’ é l é m e n t s d e p i l o t e ( R I V E ) A n a l y s e u r d ’ a r c h i t e c t u r e S é l e c t i o n n e u r d e c o d e G é n é r a t e u r d e c o d e P u t _s h m G e t_ s h m . . . H A L _ R e g i s t e r _ P u t C P U _W r i t e C P U _ R e a d . . . H A L _ D M A _l o c k … A P I s S e r v i c e s d é p e n d a n t s d u l o g i c i e l d e l ’ a p p l i c a t i o n S e r v i c e s d é p e n d a n t s d u m a t é r i e l C o d e f i n a l e d u p i l o t e + M a k e f i l e s Architecture virtuelle annotée

L i s t e d e p a r a m è t r e s L i s t e d ’ é l é m e n t s s é l e c t i o n n é s G é n é r a t e u r d e M a k e f i l e F i c h i e r s s o u r c e s S p é c i f i c a t i o n l o g i c i e l-m a t é r i e l ( V A D e L ) A B C

Bibliothèque logicielle : macro-m o d è l e s d ’ é l é m e n t s d e p i l o t e ( R I V E ) A n a l y s e u r d ’ a r c h i t e c t u r e S é l e c t i o n n e u r d e c o d e G é n é r a t e u r d e c o d e P u t _s h m P u t _s h m G e t_ s h mG e t_ s h m . . .. . . H A L _ R e g i s t e r _ P u t C P U _W r i t e C P U _W r i t e C P U _ R e a dC P U _ R e a d . . .. . . H A L _ D M A _l o c k … A P I s S e r v i c e s d é p e n d a n t s d u l o g i c i e l d e l ’ a p p l i c a t i o n S e r v i c e s d é p e n d a n t s d u m a t é r i e l C o d e f i n a l e d u p i l o t e + M a k e f i l e s Architecture virtuelle annotée

L i s t e d e p a r a m è t r e s

L i s t e d ’ é l é m e n t s s é l e c t i o n n é s

G é n é r a t e u r d e M a k e f i l e F i c h i e r s s o u r c e s

Comme dans le cas de génération d’adaptateurs mémoire matériels, le flot de génération de pilotes logiciels (Figure 55) prend en entrée une architecture virtuelle qui décrit l’architecture logiciel-matériel abstraite de l’application (en VADeL). Cette architecture est annotée avec des paramètres de configuration spécifiques à l’application et à l’architecture (CPU, interface logiciel-matériel). Ces paramètres sont utilisés pour sélectionner et configurer les éléments spécifiques aux trois couches du pilote qui sont nécessaires au fonctionnement de l’application.

Paramètres spécifiques à l’application

Ces paramètres sont liés au logiciel de l’application (SE + code des tâches). Ils caractérisent les services de communication fournis ou requis par le pilote ainsi que le type de données manipulé par l’application. Ils servent essentiellement à sélectionner et à configurer les éléments de la deuxième couche du pilote et à fixer le type et la taille des éléments de mémorisation du pilote.

Paramètres spécifiques au matériel

Ces paramètres caractérisent la structure d’informations liées au périphérique en question et le processeur cible. Ces paramètres sont utilisés pour sélectionner les éléments du pilote qui dépendent du matériel.

3.2. Bibliothèque du flot

La génération des pilotes utilise une bibliothèque logicielle contenant des macro-modèles d’éléments de chaque couche du pilote. Ces éléments génériques sont configurés par les paramètres d’annotation pendant la génération du code du pilote. Chaque élément peut fournir/requérir un service à/de un autre élément. Nous utilisons le langage Lidel pour décrire cette relation de dépendance entre les services d’un pilote. Le code des macro-modèles de cette bibliothèque est écrit en langage RIVE, le langage cible étant du C.

1. /* CPU-Port write function */

2. Void @{CPUName }@_Write (T D, @{C_data_type}@ A){ 3. …….

4. /* Address conversion */

5. @{C_data_type}@ physical_addr = virtual2physical( @{EMBA}@, A);

6. /* Address CPU port write */

7. *( (@{C_data_type}@ *)(*CPU_ addr_port) ) = physical_addr;

8. /* Generic to CPU data type conversion and data CPU port write */

9. * @{CPU_data_port}@ = (@{C_data_type}@) D; 10. …….

11. }

1. /* CPU-Port write function */

2. Void ARM7_Write (T D, long int A){ 3. …….

4. /* Address conversion */

5. long int physical_addr = virtual2physical( 0x160000, A);

6. /* Address CPU port write */

7. *( (long int *)(*ARM7_addr_port) ) = physical_ addr;

8. /* Generic to CPU data type conversion and data CPU port write */

9. * ARM7_data_port = (long int) D; 10. …….

11. }

1. DEFINE CPUName = “ARM7” ENDDEFINE 2. DEFINE C_data_type = “long int ” ENDDEFINE 3. DEFINE EMBA = 0x160000 ENDDEFINE

4. DEFINE CPU_addr_port = “ARM7_ addr_port” ENDDEFINE 5. DEFINE CPU_data_port = “ARM7_data_port” ENDDEFINE

(a) Code macro en RIVE (b) Code C généré

(c) Paramètres de configuration

1. /* CPU-Port write function */

2. Void @{CPUName }@_Write (T D, @{C_data_type}@ A){ 3. …….

4. /* Address conversion */

5. @{C_data_type}@ physical_addr = virtual2physical( @{EMBA}@, A);

6. /* Address CPU port write */

7. *( (@{C_data_type}@ *)(*CPU_ addr_port) ) = physical_addr;

8. /* Generic to CPU data type conversion and data CPU port write */

9. * @{CPU_data_port}@ = (@{C_data_type}@) D; 10. …….

11. }

1. /* CPU-Port write function */

2. Void ARM7_Write (T D, long int A){ 3. …….

4. /* Address conversion */

5. long int physical_addr = virtual2physical( 0x160000, A);

6. /* Address CPU port write */

7. *( (long int *)(*ARM7_addr_port) ) = physical_ addr;

8. /* Generic to CPU data type conversion and data CPU port write */

9. * ARM7_data_port = (long int) D; 10. …….

11. }

1. DEFINE CPUName = “ARM7” ENDDEFINE 2. DEFINE C_data_type = “long int ” ENDDEFINE 3. DEFINE EMBA = 0x160000 ENDDEFINE

4. DEFINE CPU_addr_port = “ARM7_ addr_port” ENDDEFINE 5. DEFINE CPU_data_port = “ARM7_data_port” ENDDEFINE

(a) Code macro en RIVE (b) Code C généré

(c) Paramètres de configuration

La Figure 56 montre une partie du code macro de la fonction d'écriture spécifique au processeur, contenu dans la bibliothèque (a), les paramètres de configuration utilisés (c) et le code généré (b).

3.3. Sorties du flot

Les sorties du flot correspondent au code final (C) du pilote, après l’expansion des macro-modèles sélectionnés et au fichier de compilation (Makefile).

3.4. Etapes du flot

Le flot de génération des pilotes logiciels est composé de quatre étapes essentielles :

- Une analyse de l’architecture permet de parcourir le fichier XML de l’architecture virtuelle annotée pour extraire les paramètres de configuration. La sortie de cette étape est une liste de paramètres.

- Une étape de sélection consiste à utiliser les paramètres de la liste précédente pour choisir les éléments de bibliothèque spécifiques à l’application et à l’architecture. La sortie de cette étape est une liste de noms de fichiers de macro-modèles.

- La génération du code correspond à l’expansion des macro-éléments sélectionnés à partir de la

bibliothèque. L’expansion du code RIVE utilise aussi la liste des paramètres de configuration extraite à la première étape. La sortie de cette étape est composée de plusieurs fichiers représentant le code final produit par l’expansion de chaque macro-élément.

- La génération du Makefile produit un fichier de compilation contenant tous les noms des fichiers

sources ainsi que les règles de compilation et d’édition de liens spécifiques au processeur cible.

3.5. Génération automatique

Nous avons étendu l’environnement d’un outil de génération de système d’exploitation [Gau01] pour l’adapter à la génération des pilotes logiciels. Cet environnement est lié au langage de la spécification d'entrée, au traducteur de cette spécification en format intermédiaire Colif et au langage de représentation de dépendance entre les éléments de bibliothèque. Pour générer un nouveau type de pilote, l’ajout de son code dans la bibliothèque est loin d’être suffisant. Il est donc nécessaire de modifier l'environnement de génération pour que l'outil accepte le nouveau type de pilote.

On distingue trois modifications essentielles liées au langage de spécification VADeL, au traducteur Colif et au langage de description des relations de dépendance Lidel. Les détails d'implémentation de ces modifications sont dans l'annexe.

Extension de VADeL

L’utilisation d’un nouveau type de matériel dans le système nécessite la spécification d’un nouveau logiciel qui contrôle son accès. Cette spécification requiert la définition d’un nouveau type de port et d’un nouveau type de canal de communication dans le langage VADeL. Pour obtenir la nouvelle bibliothèque de VADeL

mise à jour, l’ajout des fichiers d'entête "headerfiles" définissant chaque nouveau port et chaque nouveau canal est nécessaire.

Extension du traducteur Colif

Le traducteur traduit chaque port et chaque canal de la spécification d’entrée (VADeL) en ports et "nets" dans le format intermédiaire Colif en se basant sur des API. Si le type de port ou le type de canal à traduire n’est pas reconnu par les API, la traduction échouera. Pour cette raison, l’ajout d’un nouveau type de port ou d’un nouveau type de canal doit être suivi systématiquement par leur définition au format Colif.

Extension des représentations Lidel

La bibliothèque de pilotes est composée d’éléments et de services. Chaque élément peut fournir des services à d’autres éléments et peut requérir d’autres services fournis par d’autres éléments. La relation de dépendance entre ces éléments est représentée par le langage Lidel. Pour cette raison, l’ajout d’un nouvel élément de pilote à la bibliothèque nécessite la définition de ces relations avec les autres éléments de la bibliothèque déjà existants. La description Lidel doit définir les services fournis et requis par l’élément ajouté, les paramètres d’appel de chaque méthode du pilote et les liens vers les sources d’implémentation.

Actuellement, les trois modifications sont effectuées à la main. Leur automatisation fait partie de nos travaux futurs.