Changes between Version 30 and Version 31 of Archi-1-TD10


Ignore:
Timestamp:
Nov 17, 2023, 10:09:56 AM (19 months ago)
Author:
franck
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Archi-1-TD10

    v30 v31  
    2222
    2323
    24 Le schéma présenté rapidement au cours 10 (slides 26 à 31) et en détail dans l'annexe du cours 10 (slides 1 à 32) représente l'exécution d'une application utilisateur très simple dont le comportement est défini par la fonction `main()`. L'exécution part du démarrage du SoC et va jusqu'à l'exécution de la fonction `exit()` qui stoppe l'avancée du programme.\\Son but est de comprendre les interactions entre le code de boot, le noyau, l'application et les bibliothèques système. Le schéma ci-dessous ne contient pas l'intégralité du code pour des raisons évidentes de lisibilité, mais ce qui reste devrait suffire.
     24Le schéma présenté rapidement au cours 10 (slides 26 à 31) et en détail dans l'annexe du cours 10 (slides 1 à 32) représente l'exécution d'une application utilisateur très simple dont le comportement est défini par la fonction `main()`.\\L'exécution part du démarrage du SoC et va jusqu'à l'exécution de la fonction `exit()` qui stoppe l'avancée du programme.\\L'objectif de ce schéma est de comprendre les interactions entre le code de boot, le noyau, l'application et les bibliothèques système. Le schéma ci-dessous ne contient pas l'intégralité du code pour des raisons évidentes de lisibilité, mais ce qui reste devrait suffire.
    2525
    2626 [[Image(htdocs:img/os_bigpicture.png,nolink,height=400)]]
     
    65651. Le MIPS propose des registres à usage général (GPR ''General Purpose Register'') pour les calculs ($0 à $31).\\
    6666 Le MIPS propose un deuxième banc de registres **à l'usage du système d'exploitation** dans le coprocesseur 0.\\
    67  Chaque registre du coprocesseur `0` (qu'on appelle ici ''registre système'') porte un nom correspondant à son usage, nous en avons vu 3 en cours (C10 S7+S10 à S14) : `c0_sr`, `c0_cause` et `c0_epc`.\\
     67 Chaque registre du coprocesseur `0` porte un nom correspondant à son usage, nous en avons vu 3 en cours (C10 S7+S10 à S14) : `c0_sr`, `c0_cause` et `c0_epc`.\\
    6868 Donner leur numéro et leur rôle en une phrase ?
    6969{{{#!protected ------------------------------------------------------------------------------------
     
    178178
    179179
    180 1. Comment imposer le placement d'adresse d'une fonction ou d'une variable en mémoire lorsqu'on produit un programme binaire exécutable, c'est-à-dire avec quel outil de la chaîne de compilation et avec quel fichier de configuration de cet outil ? (C9 S18+S22+S23 C10 annexe S6+S8)
     1801. Comment imposer le placement d'adresse d'une fonction ou d'une variable en mémoire lorsqu'on produit un programme binaire exécutable, c'est-à-dire quel outil de la chaîne de compilation réalise ce placement en mémoire et avec quel fichier de configuration ? (C9 S18+S22+S23 C10 annexe S6+S8)
    181181{{{#!protected ------------------------------------------------------------------------------------
    182182''
     
    187187''
    188188}}}
    189 1. La première fonction d'un programme utilisateur est la fonction `_start()`, c'est elle qui appelle la fonction `main()`. La fonction `_start()` est donc dans le code de l'application, et non pas dans le noyau. Cependant le noyau doit connaitre son adresse afin de pouvoir y sauter et ainsi entrer dans l'application. \\Dans le code ci-après, nous voyons comment la fonction `kinit()` appelle cette fonction `_start()`. Deux fichiers sont impliqués `kinit.c` dans lequel se trouve la fonction `void kinit(void)` et `hcpua.S` dans lequel se trouve la fonction `void app_load(void *)` en charge d'appeler la fonction `_start()`.
     1891. La première fonction d'un programme utilisateur est la fonction `_start()`, c'est elle qui appelle la fonction `main()`. La fonction `_start()` est donc dans le code de l'application, et non pas dans le noyau. Cependant le noyau doit connaître son adresse afin de pouvoir y sauter et ainsi entrer dans l'application. \\Dans le code ci-après, nous voyons comment la fonction `kinit()` appelle cette fonction `_start()`. Deux fichiers sont impliqués : `kinit.c` dans lequel se trouve la fonction `void kinit(void)` et `hcpua.S` dans lequel se trouve la fonction `void app_load(void *)` en charge d'appeler la fonction `_start()`.
    190190{{{#!c
    191191kinit.c:
     
    229229''
    230230- Il y a 4 registres affectés, dans l'ordre :
    231   - Le registre système `$14` nommé `c0_epc`, il reçoit l'adresse `_start`, c'est-à-dire l'adresse de la fonction `_start()`.
     231  - Le registre du coprocesseur 0 `$14` nommé `c0_epc`, il reçoit l'adresse `_start`, c'est-à-dire l'adresse de la fonction `_start()`.
    232232  - `$26` affecté par `0x12` ($26 c'est un registre temporaire pour le noyau, on peut l'écraser sans sauver sa valeur).
    233   - Le registre système `$12` nommé `c0_sr`, il reçoit la valeur `0x12`, donc les bits `UM`, `EXL` et `IE` prennent respectivement les valeurs `1`, `1` et `0`
     233  - Le registre du coprocesseur 0 `$12` nommé `c0_sr`, il reçoit la valeur `0x12`, donc les bits `UM`, `EXL` et `IE` prennent respectivement les valeurs `1`, `1` et `0`
    234234    - UM = 1 et IE = 0, signifie que l'on est normalement en mode `user` avec les interruptions masquées,
    235235      **mais** comme `EXL`=`1`, alors on reste en mode `kernel` avec interruptions masquées.\\
     
    244244''
    245245}}}
    246 1. Que doit-on faire dans la fonction `_start()` avant l'exécution de la fonction `main()` du point de vue de l'initialisation? Et au retour de la fonction `main()`? (C10 S24)
     2461. Que doit-on faire dans la fonction `_start()` avant l'exécution de la fonction `main()` du point de vue de l'initialisation? Et que doit-on faire dans la fonction `_start()` au retour de la fonction `main()` ? (C10 S24)
    247247{{{#!protected ------------------------------------------------------------------------------------
    248248''
     
    251251''
    252252}}}
    253 1. Nous avons vu que le noyau est sollicité par des demandes de service, quels sont-ils ? Nous rappelons que l'instruction `syscall` initialise le champs `xcode` du registre `c0_cause`, comment le noyau fait-il pour connaître la cause de son appel? (C10 S25)
     2531. Nous avons vu que le noyau est sollicité par des demandes de service, quels sont-ils ? Nous rappelons que l'instruction `syscall` initialise le champs `xcode` du registre `c0_cause`, ainsi donc comment le noyau fait-il pour connaître la cause de son appel? (C10 S25)
    254254{{{#!protected ------------------------------------------------------------------------------------
    255255''
     
    261261''
    262262}}}
    263 1. On rappelle que `$26` et `$27` sont deux registres GPR temporaires que le noyau se réserve pour faire des calculs sans qu'il ait besoin de les sauvegarder dans la pile. **Ce ne sont pas des registres système** comme `c0_sr` ou `c0_epc`. En effet, l'usage de ces registres (`$26` et `$27`) par l'utilisateur ne provoque pas d'exception du MIPS. Toutefois si le noyau est appelé alors il modifie ces registres et donc l'utilisateur perd leur valeur.\\Le code assembleur ci-après contient les instructions exécutées à l'entrée dans le noyau, quelle que soit la cause. Les commentaires présents dans le code ont été volontairement retirés (ils sont dans le cours et dans les fichiers du TP). La section `.kentry` est placée à l'adresse `0x80000000` par l'éditeur de lien.\\ \\**`kernel/hcpua.S`**
     2631. On rappelle que `$26` et `$27` sont deux registres GPR temporaires **''réservés''** pour le noyau pour faire des calculs sans qu'il ait besoin de les sauvegarder dans la pile. **Ce ne sont pas des registres du coprocesseur 0** comme `c0_sr` ou `c0_epc`. En effet, l'usage de ces registres (`$26` et `$27`) par l'utilisateur ne provoque pas d'exception du MIPS. Toutefois si le noyau est appelé alors il modifie ces registres et donc l'utilisateur perd leur valeur.\\Le code assembleur ci-après contient les instructions exécutées à l'entrée dans le noyau, quelle que soit la cause. Les commentaires présents dans le code ont été volontairement retirés (ils sont dans le cours et dans les fichiers du TP). La section `.kentry` est placée à l'adresse `0x80000000` par l'éditeur de lien.\\ \\**`kernel/hcpua.S`**
    264264{{{#!c
    265265 15 .section    .kentry,"ax"