Changes between Version 73 and Version 74 of Archi-1-TP9


Ignore:
Timestamp:
Dec 4, 2020, 2:09:09 PM (4 years ago)
Author:
franck
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Archi-1-TP9

    v73 v74  
    463463
    464464
     465
     466
    465467= B. Travaux pratiques
    466468
     
    638640'''''''''''''''
    639641}}}
    640 - Le code de boot ne fait que sauter dans la fonction kinit avec l'instruction `j`,
    641     il n'y a pas de retour, ce n'est donc pas un `jal`, mais pourquoi ne pas avoir utilisé
    642     `j init` et donc pourquoi passer par un registre ?
    643 {{{#!protected ------------------------------------------------------------------------------------
    644 '''''''''''''''
    645   - On ne sait pas le code de boot est en `0xBFC00000`.
    646     L'instruction `j imm26` permet de sauter à n'importe quelle adresse d'instruction `0xB.......`
    647     (dans le memento MIPS `j imm26` : `PC <- PC[31:28] || imm26*4`
    648 '''''''''''''''
    649 }}}
    650   - Dans `kernel.ld`, la définition de la mémoire est plus complète, elle contient 3 régions :
    651     pour le code de boot `boot_region` pour le code du noyau `ktext_region` et
    652     pour les données globales du noyau `kdata_region`.
    653     Ces régions ne contiennent qu'une section de sorties (resp. `.boot`, `.ktext` et `.kdata`)
    654     remplies avec les sections d'entrées produites par le compilateur.\\
    655     Que signifie `*(.*data*)` ?
    656 {{{#!protected ------------------------------------------------------------------------------------
    657 '''''''''''''''
    658   - C'est une manière de désigner toutes les sections nommées `.*data*` avec `*` = n'importe quoi
    659     présentes dans n'importe quel fichier objets reçu par le compilateur.
    660 '''''''''''''''
    661 }}}
    662   - Quelle est la valeur de `__kdata_end` ? Pourquoi, selon vous, mettre 2 «`_`» au début des variables ?
    663 {{{#!protected ------------------------------------------------------------------------------------
    664 '''''''''''''''
    665   - `__kdata_end` est l'adresse du premier octet placé juste après la région data.
    666   - les 2 «`_`» permettent d'éviter les conflits avec les noms des symboles (fonction, variable, type, etc.)
    667     présents dans le programme.
    668 '''''''''''''''
    669 }}}
    670   -
    671 {{{#!protected ------------------------------------------------------------------------------------
    672 '''''''''''''''
    673   -
    674 '''''''''''''''
    675 }}}
    676   -
    677 {{{#!protected ------------------------------------------------------------------------------------
    678 '''''''''''''''
    679   -
    680 '''''''''''''''
    681 }}}
    682   -
    683 {{{#!protected ------------------------------------------------------------------------------------
    684 '''''''''''''''
    685   -
    686 '''''''''''''''
    687 }}}
    688   -
    689 {{{#!protected ------------------------------------------------------------------------------------
    690 '''''''''''''''
    691   -
    692 '''''''''''''''
    693 }}}
    694 
    695 
    696 
    697 
    698 == 3. Saut dans la fonction kinit() du noyau en langage C
    699 
    700    Dans ce troisième programme, nous faisons la même chose que pour le deuxième mais `kinit()` est désormais écrit en
    701    langage C. Cela change peu de choses, sauf une chose importante `kinit()` est une fonction et donc il faut absolument
    702    une pile d'exécution.
    703    \\\\
    704    **Objectifs**
    705    - Savoir comment et où déclarer la pile d'exécution du noyau.
    706    - Savoir comment afficher un caractère sur un terminal depuis un programme C.
    707  
    708  **Fichiers**
     6422. Le code de boot ne fait que sauter à l'adresse `kinit avec l'instruction `j`,
     643   il n'y a pas de retour, ce n'est donc pas un `jal`. Où est définit `kinit` ?
     644   Comment le code de boot connait cette adresse ?
     645   Pourquoi ne pas avoir utilisé `j init` et donc pourquoi passer par un registre ?
     646{{{#!protected ------------------------------------------------------------------------------------
     647'''''''''''''''
     648- `kinit` est défini dans la `kinit.S`.
     649- `hcpu.S` ne connait pas cette adresse, mais grâce au `.globl kinit`, l'éditeur de lien saura compléter `hcpu.o`, dans l'exécutable.
     650- 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`.
     651'''''''''''''''
     652}}}
     6531. Dans `kernel.ld`, que signifie `*(.*data*)` ?
     654{{{#!protected ------------------------------------------------------------------------------------
     655'''''''''''''''
     656- C'est une manière de désigner toutes les sections nommées `.*data*` avec `*` = n'importe quoi
     657  présentes dans n'importe quel fichier objets reçu par le compilateur.
     658'''''''''''''''
     659}}}
     6601. Quelle est la valeur de `__kdata_end` ? Pourquoi mettre 2 «`_`» au début des variables du `ldscript` ?
     661{{{#!protected ------------------------------------------------------------------------------------
     662'''''''''''''''
     663- `__kdata_end` est l'adresse du premier octet placé juste après la région data.
     664- les 2 «`_`» permettent d'éviter les conflits avec les noms des symboles (fonction, variable, type, etc.)
     665  présents dans le programme.
     666'''''''''''''''
     667}}}
     668
     669**Exercices**
     670
     671- Exécutez le programme sur le simulateur. Est-ce différent de l'étape 1 ?
     672{{{#!protected ------------------------------------------------------------------------------------
     673'''''''''''''''
     674* Non, c'est le même comportement.
     675'''''''''''''''
     676}}}
     677- Modifiez le code, comme pour l'étape 1, afin d'afficher un second message ?
     678{{{#!protected ------------------------------------------------------------------------------------
     679'''''''''''''''
     680* C'est très semblable, voire identique, à l'étape 1, l'idée est qu'ils ouvrent le code...
     681'''''''''''''''
     682}}}
     683
     684
     685
     686== B3. Saut dans la fonction kinit() du noyau en langage C
     687
     688
     689
     690Dans ce troisième programme, nous faisons la même chose que pour le deuxième mais `kinit()` est désormais écrit en
     691langage C. Cela change peu de choses, sauf une chose importante `kinit()` est une fonction et donc il faut absolument
     692une pile d'exécution.
     693
     694**Objectifs**
     695
     696- Savoir comment et où déclarer la pile d'exécution du noyau.
     697- Savoir comment afficher un caractère sur un terminal depuis un programme C.
     698
     699**Fichiers**
     700
    709701{{{
    7107023_init_c/
     
    715707}}}
    716708
    717 - **Questions**\\
    718   ''Les réponses sont dans le cours ou dans les fichiers sources''\\\\
    719   - Question ?
    720 {{{#!protected ------------------------------------------------------------------------------------
    721 '''''''''''''''
    722   - Réponse
    723 '''''''''''''''
    724 }}}
    725 
    726 
    727 
    728 
    729 == 4.  Accès aux registres de contrôle des terminaux `TTY`
    730 
    731 
    732 
    733 
    734    Le prototype de SoC que nous utilisons pour les TP est configurable. Il est possible par exemple de choisir le nombre
    735    terminaux texte (TTY). Par défaut, il y en a un mais, nous pouvons en avoir jusqu'à 4. Nous allons modifier le code du
    736    noyau pour s'adapter à cette variabilité. En outre, pour le moment, nous ne faisions qu'écrire sur le terminal,
    737    maintenant, nous allons aussi lire le clavier.
    738    \\\\
    739    **Objectifs**
    740    - Savoir comment compiler un programme C avec du code conditionnel.
    741    - Savoir comment décrire en C l'ensemble des registres d'un contrôleur de périphérique et y accéder.
     709**Questions**
     710
     7111. Quand faut-il initialiser la pile ? Dans quel fichier est-ce ? Quelle est la valeur du pointeur initial ?
     712{{{#!protected ------------------------------------------------------------------------------------
     713'''''''''''''''
     714- Il faut initialiser le pointeur avant d'appeler `kinit()`
     715- C'est dans le fichier `hcpu.S`
     716- '$29' ← '__kdata_end', c'est-à-dire `0x80400000`
     717'''''''''''''''
     718}}}
     719
     720**Exercices**
     721
     722- Exécutez le programme sur le simulateur. Est-ce différent de l'étape 1 ?
     723{{{#!protected ------------------------------------------------------------------------------------
     724'''''''''''''''
     725* Non, c'est le même comportement :-)
     726'''''''''''''''
     727}}}
     728- Modifiez le code de `kinit.c`, et comme pour l'étape 1, afficher un second message ?
     729{{{#!protected ------------------------------------------------------------------------------------
     730'''''''''''''''
     731* 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 qu'ils ouvrent le code
     732'''''''''''''''
     733}}}
     734
     735
     736
     737== B4.  Accès aux registres de contrôle des terminaux `TTY`
     738
     739
     740
     741Le prototype de SoC que nous utilisons pour les TP est configurable. Il est possible par exemple de choisir le nombre
     742terminaux texte (TTY). Par défaut, il y en a un mais, nous pouvons en avoir jusqu'à 4. Nous allons modifier le code du
     743noyau pour s'adapter à cette variabilité. En outre, pour le moment, nous ne faisions qu'écrire sur le terminal,
     744maintenant, nous allons aussi lire le clavier.
     745
     746**Objectifs**
     747
     748- Savoir comment compiler un programme C avec du code conditionnel.
     749- Savoir comment décrire en C l'ensemble des registres d'un contrôleur de périphérique et y accéder.
    742750 
    743  **Fichiers**
     751**Fichiers**
     752
    744753{{{
    7457544_nttys/
     
    750759}}}
    751760
    752 - **Questions**\\
    753   ''Les réponses sont dans le cours ou dans les fichiers sources''\\\\
    754   - Question ?
    755 {{{#!protected ------------------------------------------------------------------------------------
    756 '''''''''''''''
    757   - Réponse
    758 '''''''''''''''
    759 }}}
    760 
    761 
    762 
    763 
    764 == 5. Premier petit pilote pour le terminal
    765 
    766 
    767 
    768 
    769    Dans l'étape 4, nous accédons au registre de périphérique directement dans la fonction `kinit()`, ce n'est pas très
    770    simple. C'est pourquoi nous allons ajouter un niveau d'abstraction qui représente un début de pilote de périphérique
    771    (device driver). Ce pilote, même tout petit constitue une couche logicielle avec une API.
    772    \\\\
    773    **Objectifs**
    774    - Savoir comment créer un début de pilote pour le terminal `TTY`.
    775    - Savoir comment décrire une API en C
    776 
    777  **Fichiers**
     761**Questions**
     762
     7631. ?
     764{{{#!protected ------------------------------------------------------------------------------------
     765'''''''''''''''
     766-
     767'''''''''''''''
     768}}}
     769
     770**Exercices**
     771
     772- Exécutez le programme sur le simulateur. Qu'observez-vous ?
     773- Modifiez le code pour afficher un message sur le second terminal, il y a toujours une attente sur le premier terminal.
     774- Modifiez le code pour que le programme attende sur les deux terminaux. L'idée est de ne plus faire d'attente bloquante sur le registre `TTY_STATUS` de chaque terminal.
     775
     776
     777
     778
     779== B5. Premier petit pilote pour le terminal
     780
     781
     782
     783Dans l'étape 4, nous accédons au registre de périphérique directement dans la fonction `kinit()`, ce n'est pas très
     784simple. C'est pourquoi nous allons ajouter un niveau d'abstraction qui représente un début de pilote de périphérique
     785(device driver). Ce pilote, même tout petit constitue une couche logicielle avec une API.
     786
     787**Objectifs**
     788
     789- Savoir comment créer un début de pilote pour le terminal `TTY`.
     790- Savoir comment décrire une API en C
     791 
     792**Fichiers**
     793
    778794{{{
    7797955_driver/
     
    786802}}}
    787803   
    788 - **Questions**\\
    789   ''Les réponses sont dans le cours ou dans les fichiers sources''\\\\
    790   - Question ?
    791 {{{#!protected ------------------------------------------------------------------------------------
    792 '''''''''''''''
    793   - Réponse
    794 '''''''''''''''
    795 }}}
    796 
    797 - Quel est le nom de la directive assembleur permettant de déclarer une section
    798 
    799 
    800 
    801 
    802 
    803 
    804 
    805 
     804**Questions**
     805
     8061. ?
     807{{{#!protected ------------------------------------------------------------------------------------
     808'''''''''''''''
     809-
     810'''''''''''''''
     811}}}
     812
     813
     814**Exercices**
     815
     816
     817
     818
     819
     820
     821