Changes between Version 90 and Version 91 of Archi-1-TP10


Ignore:
Timestamp:
Nov 25, 2021, 5:33:15 PM (4 years ago)
Author:
franck
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Archi-1-TP10

    v90 v91  
    323323Cours 10 / slide 40
    324324- La fonction `syscall()` a 5 a arguments
    325 - Elle reçoit ses 4 premiers arguments dans les registres $4 à $7 et le 5e dans la pile.
     325- Elle reçoit ses 4 premiers arguments dans les registres $4 à $7 et le 5e (le numéro de service) dans la pile.
    326326- La ligne 3 sert à dire que syscall est une étiquette utilisée dans un autre fichier. `.globl` signifie **glob**al **l**abel. Si on la retire, il y aura un problème lors de l'édition de lien. `syscall()` ne sera pas trouvé par l'éditeur de liens.
    327327- Le noyau attend le numéro de service dans `$2`. Or le numéro du service est le 5e arguments de la fonction `syscall()`. La ligne 5 permet d'aller le chercher dans la pile.
     
    3413411. Comment imposer le placement d'adresse d'une fonction ou d'une variable en mémoire?
    342342{{{#!protected ------------------------------------------------------------------------------------
    343 '''''''''''''''
     343''
     344Cours 9 / slide 24  et Cours 10 / slides 64 et 65
    344345- C'est l'éditeur de lien qui est en charge du placement en mémoire du code et des données, et c'est dans le fichier ldscript `kernel.ld` ou `user.ld` que le programmeur peut imposer ses choix.
    345346- Pour placer une fonction à une place, la méthode que vous avez vu consiste
    346347  - à créer une section grâce à la directive `.section` en assembleur ou à la directive `__attribute__((section()))` en C
    347348  - puis à positionner la section créée dans la description des `SECTIONS` du ldscript.
    348 '''''''''''''''
    349 }}}
    350 1. Dans la question **A2.5**, nous avons vu comment la fonction `kinit()` appelle la fonction `__start()` grâce à un bout de code en assembleur placé au début de la section `.text`. Nous allons voir maintenant quelles sont les conditions de cet appel. Dans le code de la question **A2.5**, `$26` est un registre de travail pour le kernel. Quels sont les autres registres modifiés? Expliquez pour chacun la valeur affectée.
    351 {{{#!protected ------------------------------------------------------------------------------------
    352 '''''''''''''''
     349''
     350}}}
     3511. Regardons comment la fonction `kinit()` appelle la fonction `__start()`, il y a deux fichiers impliqués `kinit.c` et `hcpua.S`, les commentaires ont été rétirés.
     352{{{#!c
     353kinit.c:
     354    void kinit (void)
     355    {
     356        [...]
     357        extern int _start;          // _start is the entry point of the app (defined in kernel.ld)
     358        app_load (&_start);         // function to start the user app (defined in hcpua.S)
     359    }
     360
     361hcpua.S:
     362    .globl app_load // --------------- void app_load (void * fun) called by kinit()
     363    app_load:                       // call when we exit kinit() function to go to user code
     364        mtc0   $4,      $14         // put _start address in c0_EPC
     365        li     $26,     0x12        // define next status reg. value
     366        mtc0   $26,     $12         // UM <- 1, IE <- 0, EXL <- 1
     367        la     $29,    __data_end   // define new user stack pointer
     368        eret 
     369}}}
     370 Où est définit `_start` ? À quoi sert `.globl app_load `? Quels sont les registres utilisés dans le code de `app_load `? Que savez-vous de l'usage de `$26 `? Quels sont les registres modifiés ? Expliquez pour chacun la valeur affectée. Que fait l'instruction `eret `?
     371{{{#!protected ------------------------------------------------------------------------------------
     372''
     373Il faut lire le code assembleur et expliquer ce qui s'y trouve :
    353374- Il y a 3 registres affectés, dans l'ordre :
    354375  - Le registre système `$14` nommé `c0_epc`, il reçoit l'adresse `__crt0`, c'est-à-dire l'adresse de la fonction `__start()`.