Changes between Version 29 and Version 30 of AS6-TME-B5


Ignore:
Timestamp:
Feb 21, 2022, 6:51:53 PM (3 years ago)
Author:
franck
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • AS6-TME-B5

    v29 v30  
    286286{{{#!protected ------------------------------------------------------------------
    287287'''
    288  * Soit c'est lui qui demande par l'appel explicite à `thread_yield()`, soit c'est une interruption d'horloge
     288 * Soit c'est lui qui demande par l'appel explicite à `thread_yield()`, soit c'est une interruption d'horloge, soit c'est `thread_exit()`
    289289'''
    290290}}}
     
    292292{{{#!protected ------------------------------------------------------------------
    293293'''
    294  *
     294 * Quand un thread rend le processeur, il le reprendra plus tard et reviendra précisément dans la fonction où il l'avait perdu (sauf si c'est une sortie définitive avec `thread_exit()` bien sûr).
     295 * Quand on entre dans une fonction C, on sait que l'on peut modifier les registres temporaires car ils ne contiennent rien pour la fonction appelante. S'ils contiennent quelque-chose d'important la fonction appelante doit sauver leur valeur avant d'entrer dans la fonction appelée.
     296 * Par contre, la fonction appelante suppose que les registres persistants conservent leur valeur, c.-à-d. qu'ils ne sont pas modifiés par la fonction appelée.
     297 * C'est vrai pour toutes les fonctions, c'est donc vrai aussi pour la fonction `thread_save()`. Elle peut modifier les registres temporaires mais pas les registres persistants.
     298 * C'est donc seul les registres persistants qu'elle sauve et qui seront restaurés par la fonction `thread_load()` qui sortira de `thread_save()` sans modification des registres persistants.
    295299'''
    296300}}}
     
    319323{{{#!protected ------------------------------------------------------------------
    320324'''
    321  *
    322 '''
    323 }}}
    324  a. Dites ce que sont les arguments `2` et `3` de `thread_kernel()` et pourquoi, ici, on les met à `0`.
    325 {{{#!protected ------------------------------------------------------------------
    326 '''
    327  *
     325 * C'est le fichier `kernel.ld` qui définit la position de `__bss_origin` et `__bss_end` dans la section `.kdata`. Ce sont des adresses qui dépendent des variables globales.
     326 * C'est aussi le fichier `kernel.ld` qui définit les adresses `__main_thread` et `_start`. Par convention, `__main_thread` est au tout début de la section `.data` de l'utilisateur et `_start` est au tout début de la section `.text` de l'utilisateur. Cette convention est nécessaire pour que le kernel sache comment lancer le premier thread de l'application.
     327'''
     328}}}
     329 a. Dites ce que sont les arguments `2` et `3` de `thread_create_kernel()` et pourquoi, ici, on les met à `0`.
     330{{{#!protected ------------------------------------------------------------------
     331'''
     332 * `thread_create_kernel()` est la fonction qui crée le thread
     333   * Le premier argument est un pointeur vers la structure `thread_t` à remplir.
     334   * Le quatrième argument est l'adresse de la fonction `_start` de démarrage du thread `main()`.
     335   * Le deuxième, c'est normalement l'adresse de la fonction de principale du thread `main()`, ça devrait être l'adresse de la fonction `main()`. Le problème c'est qu'on ne peut pas connaître l'adresse de la fonction `main()`, elle est quelque part dans la section `.text`. Le fait ne pas savoir où est `main()` n'est pas important, car on appelle `_start()` qui appelle `main()`.
     336   * Le troisième argument, c'est normalement l'argument de la fonction principale du thread, mais par pour le thread `main()` qui doit prendre en principe les arguments de la ligne de commande du shell (ici rien). Là encore, ce n'est pas important, la fonction `start()` saura trouver les arguments.
     337   * Comme on n'a pas besoin de arguments 2 et 3, on met 0.
    328338'''
    329339}}}
     
    331341{{{#!protected ------------------------------------------------------------------
    332342'''
    333  *
     343 * Quend on sort de `thread_load()`, on entre dans la fonction `_start()` (après un passage par `thread_bootstrap()` et `thread_launch()`). Or on ne sort jamais de `_start()`, on sort de l'application avec `exit()`.
     344 * On n'exécute rien après `thread_load()` mais si ça devait se produire alors c'est un kernel panic !
    334345'''
    335346}}}
     
    337348{{{#!protected ------------------------------------------------------------------
    338349'''
    339  *
     350 * `kinit()` utilise une pile temporaire en haut du segment `.kdata`. Dès qu'on entre dans une application, on utilise la pile de l'application et on ne revient plus jamais sur la pile de `kinit()`.
     351 * Dans le cas général, il y a toujours une application et un thread en cours, et le processeur utilise la pile courrante.
     352 * Dans la version actuelle du code, il n'y a qu'une pile par thread, utilisée à la fois par les fonctions utilisateur et par le kernel lors des syscall ou des ISR, mais bientôt, nous aurons 2 piles par thread, une pour le code utilisateur et une pour le code noyau.
    340353'''
    341354}}}
     
    343356{{{#!protected ------------------------------------------------------------------
    344357'''
    345  *
     358 * Non, ça ne sert à rien, le contexte restauré ne contient rien dans ces registres
    346359'''
    347360}}}