Changes between Version 4 and Version 5 of Archi-1-TP10


Ignore:
Timestamp:
Dec 20, 2020, 6:20:24 PM (4 years ago)
Author:
franck
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Archi-1-TP10

    v4 v5  
    1 ||[wiki:description_dernieres_seances retour au descriptif des séances "système"]||
     1{{{#!protected
     2**[https://www-soc.lip6.fr/trac/archi-l3s5/wiki/AS5-TME10-tmp?action=edit EDIT]**
     3}}}
    24[[PageOutline]]
    3 = Application simple en mode utilisateur
    4 
    5 Les applications de l'utilisateur s'exécute en mode user. Dans la séance précédente, nous avons vu que les registres de commande des contrôleurs de périphérique sont placés dans l'espace d'adressage du processeur. Et bien, les adresses de ces registres ont été choisies dans la partie de l'espace d'adressage interdite en mode user. Ainsi, une application n'a pas un accès directe aux contrôleur de périphériques, elle doit utiliser des appels système (avec l'instructions syscall) pour demander au noyau du système d'exploitation Dans cette séance, nous allons découper le code en 4 couches : (1) le code de boot (utilisé seulement au démarrage), (2) le noyau du système d'exploitation (contenant, entre autres, la fonction d'initialisation init() et le code des appels systèmes syscall), (3) la bibliothèque de fonctions standards (libc) et Dans cette séance, afin d'exécuter une application, nous allons sortir du mode kernel, utilisé par le MIPS au démarrage, pour passer en mode user. Quand le MIPS est en mode user, le code s'exécute dans un environnement restreint dans lequel il n'a pas droit à certaines instructions et il n'a pas accès à tout l'espace d'adressage. En particulier, il n'a pas accès aux adresses où ont été placés les registres de commandes des contrôleurs de périphériques. C'est dans ce mode que s'exécute les applications de l'utilisateur. Pour interagir avec les périphériques, une application doit utiliser les appels systèmes, et donc elle doit utiliser l'instruction syscall qui provoque le passage du processeur en mode kernel et l'exécution d'un code du noyau du système d'exploitation. Ce mode permet, entre autres, de garantir le bon usage des périphériques.
    6 
     5
     6
     7Cette page décrit la séance complète : TD et TP. Elle commence par des exercices à faire sur papier et puis elle continue et se termine par des questions sur le code et quelques exercices de codage simples à écrire et à tester sur le prototype.
     8La partie pratique  est découpée en 4 étapes. Pour chaque étape, nous donnons (1) une brève description, (2) une liste des objectifs principaux de l'étape, (3) une liste des fichiers avec un bref commentaire sur chaque fichier, (4) une liste de questions simples dont les réponses sont dans le code, le cours ou le TD et enfin (5) un exercice de codage.
     9
     10**IMPORTANT\\Avant de faire cette séance, vous devez avoir lu les documents suivants** :
     11* [wiki:AS5-TME9 Séance de TME sur le démarrage du prototype] : ''obligatoire''
     12* [htdocs:cours/AS5-10-2p.pdf Cours sur l'exécution d'une application en mode user] : ''obligatoire''
     13* [htdocs:cours/doc_MIPS32.pdf Document sur l'assembleur du MIPS et la convention d'appel des fonctions] : ''recommandé''
     14* [wiki:Doc-MIPS-Archi-Asm-kernel Documentation sur le mode kernel du MIPS32] : ''obligatoire''
     15
     16
     17
     18**Récupération du code du TP**
     19
     20
     21
     22* Téléchargez **[htdocs:files/tp2.tgz l'archive code du tp2]** et placez là dans le répertoire `$HOME/AS5` 
     23* Assurez-vous que vous avez déjà sourcé le fichier `Source-me.sh` (sinon lisez [https://www-soc.lip6.fr/trac/archi-l3s5/wiki/Howto-TP Configuration de l'environnement des TP → Étape 3])
     24* Ouvrez un `terminal`, allez dans le répertoire `AS5` (**`cd ~/AS5`**) et décompressez l'archive du tp1 avec **`tar xvzf tp2.tgz`**\\''Cette étape est peut-être inutile si vous avez déjà fait la décompression de l'archive au moment de son téléchargement.''
     25* Dans le `terminal`, exécutez la commande  **`cd ; tree -L 2 AS5`**. Vous devriez obtenir ceci (tp1 et tp2):
     26{{{#!bash
     27AS5
     28├── bin
     29│   ├── almo1.x
     30│   ├── gcc
     31│   ├── Source-me.sh
     32│   ├── test
     33│   └── tracelog
     34├── tp1
     35│   ├── 1_hello_boot
     36│   ├── 2_init_asm
     37│   ├── 3_init_c
     38│   ├── 4_nttys
     39│   ├── 5_driver
     40│   └── Makefile
     41└── tp2
     42    ├── 1_klibc
     43    ├── 2_appk
     44    ├── 3_syscalls
     45    ├── 4_libc
     46    └── Makefile
     47}}}
     48
     49
     50**Objectif de la séance**
     51
     52
     53Cette séance illustre le [htdocs:cours/AS5-10-2p.pdf cours2].
     54Les applications de l'utilisateur s'exécutent en mode user. Dans la séance précédente, nous avons vu que les registres de commande des contrôleurs de périphériques sont placés dans l'espace d'adressage du processeur. Les adresses de ces registres ont été placées dans la partie de l'espace d'adressage interdite en mode user. Ainsi, une application n'a pas un accès direct aux périphériques, elle doit utiliser des appels système (avec l'instruction syscall) pour demander au noyau du système d'exploitation. C'est ce que nous allons voir.
     55Le code est désormais découpé en 4 couches logicielles :
     561. `1_klibc` le code de boot (utilisé seulement au démarrage);
     572. `2_appk`  le noyau du système d'exploitation, ici pour l'essentiel, la fonction d'initialisation `kinit()` et le gestionnaire des appels systèmes;
     583. `3_syscalls` la bibliothèque de fonctions standards (libc);
     594. `4_libc` l'application.
     60
     61
     62
     63
     64----
     65
     66= A. Travaux dirigés
     67
     68
     69
     70== A1. Les modes d'exécution du MIPS
     71
     72
     73Dans cette section, nous allons nous intéresser à ce que propose le processeur MIPS concernant les modes d'exécution. Ce sont des questions portant sur l'usage des modes en général et le comportement du MIPS vis-à-vis de ces modes. Dans la section A3, nous verrons le code de gestion des changements de mode;
     74Le MIPS propose deux modes d'exécution.
     75
     76
     77**Questions**
     78
     79
     801. Le MIPS propose deux modes d'exécution, rappelez quels sont ces deux modes et à quoi ils servent? (''Nous l'avons dit dans le descriptif de la séance'').
     81{{{#!protected ------------------------------------------------------------------------------------
     82'''''''''''''''
     83- Il y a le mode kernel et le mode user.
     84- Le mode kernel est utilisé par le noyau alors que le mode user est utilisé par l'application.
     85'''''''''''''''
     86}}}
     871. Commencez par rappeler ce qu'est l'espace d'adressage du MIPS, puis dîtes ce que veut dire qu'une adresse X mappée en mémoire, et enfin dîtes si une adresse X mappée en mémoire est toujours accessible (en lecture ou en écriture) quelque soit le mode d'exécution du MIPS.
     88{{{#!protected ------------------------------------------------------------------------------------
     89'''''''''''''''
     90- L'espace d'adressage du MIPS, c'est l'ensemble des adresses que peut produire le MIPS
     91- On dit qu'une adresse est mappée en mémoire, s'il y a bien une case mémoire pour cette adresse.
     92- Non X n'est pas toujours accessible, si X est < `0x80000000` elle est bien accessible quelque-soit le mode d'exécution du MIPS, mais si X >= `0x80000000` alors X n'est accessible que si le MIPS est en mode kernel.
     93'''''''''''''''
     94}}}
     951. Le MIPS propose des registres à usage général (GPR ''General Purpose Register'') pour les calculs ($0 à $31). Le MIPS propose un deuxième banc de registres à l'usage du système d'exploitation, ce sont les registres système. Comment sont-ils numérotés? Chaque registre porte un nom correspondant à son usage, quels sont ceux que vous connaissez, donner leur nom, leur numéro et leur rôle? Peut-on faire des calculs avec des registres? Quelles sont les instructions qui permettent de les manipuler?
     96{{{#!protected ------------------------------------------------------------------------------------
     97'''''''''''''''
     98- Les registres système sont numérotés de $0 à $31, comme les registres GPR, ce qui peut induire une certaine confusion
     99- Nous avons vu 6
     100   || `cr_sr`     || `$12` || contient essentiellement le mode d'exécution du MIPS et le bit d'autorisation des interruptions
     101   || `cr_cause`  || `$13` || contient la cause d'appel du noyau
     102   || `cr_epc`    || `$14` || contient l'adresse de l'instruction ayant provoqué l'appel du noyau ou l'adresse de l'instruction suivante
     103   || `cr_bar`    || `$8 ` || contient l'adresse mal formée si la cause est une exception due à un accès non aligné (p.ex. lw a une adresse non multiple de 4)
     104   || `cr_count`  || `$9 ` || contient le nombre de cycles depuis le démarrage du MIPS
     105   || `cr_procid` || `$15` || contient le numéro du processeur (utile pour les architectures multicores)
     106- non, il n'est pas possible de faire des calculs sur ces registres.
     107- On peut juste les lire et les écrire en utilisant les instructions `mtc0` et `mfc0`
     108'''''''''''''''
     109}}}
     1101. Le registre status est composé de plusieurs champs de bits qui ont chacun une fonction spécifique. Décrivez le contenu du registre status et le rôle des bits de l'octet 0(seulement ceux vu en cours).
     111{{{#!protected ------------------------------------------------------------------------------------
     112'''''''''''''''
     113 || 0|| IE  ||Interrupt Enable||0 → interruptions masquées\\1 → interruptions autorisées
     114 || 1|| EXL ||EXception Level ||1 → MIPS en mode exception\\à l'entrée dans le kernel, le MIPS est en mode kernel, interruptions masquées
     115 || 2|| ERL ||ERror Level     ||0 → interruptions masquées\\1 → interruptions autorisées
     116 || 4|| UM  ||User Mode       ||0 → interruptions masquées\\1 → interruptions autorisées
     117'''''''''''''''
     118}}}
     1191. Le registre cause est contient la cause d'appel du kernel. Dites à quel endroit est stockée cette cause et donnez la signification des codes 0, 4 et 8
     120{{{#!protected ------------------------------------------------------------------------------------
     121'''''''''''''''
     122- Le champ `XCODE` qui contient le code de la cause d'entrée dans le noyau est codé sur 4 bits entre les bits 2 et 5.
     123- Les valeurs les plus importantes sont:
     124
     125  || 0000,,b,, || interruption || un contrôleur de périphérique à lever un signal IRQ
     126  || 0100,,b,, || ADEL         || lecture non-alignée (p. ex. `lw` a une adresse impaire)
     127  || 1000,,b,, || syscall      || exécution de l'instruction `syscall`
     128'''''''''''''''
     129}}}
     1301. Le registre `EPC` est un registre 32 bits qui contient une adresse. Vous devriez l'avoir décrit dans la question 2, mais expliquez pourquoi ce doit être l'adresse de l'instruction qui provoque une exception qui doit être stocké dans `EPC`?
     131{{{#!protected ------------------------------------------------------------------------------------
     132'''''''''''''''
     133- Une exception, c'est une erreur du programme, telle qu'une division par 0, une lecture non alignée ou une instruction illégale. Il est important que le gestionnaire d'exception sache quelle est l'instruction fautive. C'est pour cette raison que EPC contient l'adresse de l'instruction fautive. Le gestionnaire pourra lire l'instruction et éventuellement corriger le problème.
     134- A titre indicatif, ce n'est pas question, mais pour les syscall, c'est aussi l'adresse de l'instruction syscall, or pour le retour du syscall, on souhaite aller à l'instruction suivante. Il faut donc incrémenter la valeur de `EPC` de 4 (les instructions font 4 octets) pour connaître l'adresse de retour.
     135'''''''''''''''
     136}}}
     1371. Nous avons vu trois instructions ne sont pas utilisable lorsque le MIPS est en mode kernel, lesquelles? Que font-elles? Est-ce que `syscall` peut-être utilisée en mode user?
     138{{{#!protected ------------------------------------------------------------------------------------
     139'''''''''''''''
     140- Les trois instructions sont
     141
     142  || `mtc0 $GPR, $C0` || `M`ove `T`o `C`oprocessor `0`   || `$GPR` → COPRO_0(`$C0`)
     143  || `mfc0 $GPR, $C0` || `M`ove `F`rom `C`oprocessor `0` || `$GPR` ←  COPRO_0(`$C0`)
     144  || `eret`           || `E`xpection `RET`urn            || `PC`  ←  `EPC` ; `c0_sr.EXL`  ←  `0`
     145- Bien sûr que `syscall` peut être utilisé en mode user, puisque c'est comme ça qu'on entre dans le kernel.
     146'''''''''''''''
     147}}}
     1481. Quelle est l'adresse d'entrée dans le noyau?
     149{{{#!protected ------------------------------------------------------------------------------------
     150'''''''''''''''
     151- C'est `0x80000180`i. Il n'y a qu'un adresse pour toutes les causes syscall, exception et interruption.
     152- En fait, on peut considérer que `0xBFC00000` permet aussi d'entrer dans le noyau après un reset.
     153'''''''''''''''
     154}}}
     1551. Que se passe-t-il quand le MIPS entre dans le noyau, après l'exécution de l'instruction `syscall`?
     156{{{#!protected ------------------------------------------------------------------------------------
     157'''''''''''''''
     158- L'instruction `syscall` induit beaucoup d'opérations élémentaires:
     159  - `EPC` ← `PC` (adresse de syscall)
     160  - `c0_SR.EXL` ← `1`  (ainsi les bits `c0_SR.UM` et `c0_SR.IE` ne sont plus utilisés)
     161  - `c0_cause.XCODE` ← `8`
     162  - `PC` ← `0x80000180`
     163'''''''''''''''
     164}}}
     1651. Quelle instruction utilise-t-on pour sortir du noyau et entrer dans l'application ? Dîtes précisément ce que fait cette instruction dans le MIPS?
     166{{{#!protected ------------------------------------------------------------------------------------
     167'''''''''''''''
     168- C'est l'instruction `eret` qui permet de sortir du noyau.
     169  - `PC` ← `EPC`
     170  - `c0_SR.EXL` ← `0` (ainsi les bits `c0_SR.UM` et `c0_SR.IE` sont à nouveau utilisés)
     171'''''''''''''''
     172}}}
     173
     174
     175
     176== A2. Langage C pour la programmation système
     177
     178
     179La programmation en C, vous connaissez, mais quand on programme pour le noyau, c'est un peu différent.
     180Il y a des éléments de syntaxe ou des besoins spécifiques.
     181
     182
     183**Questions**
     184
     185
     1861. définition de section pour le placement des fonctions ou des variables?
     187{{{#!protected ------------------------------------------------------------------------------------
     188'''''''''''''''
     189-
     190'''''''''''''''
     191}}}
     1921. effacement des variables globales?
     193{{{#!protected ------------------------------------------------------------------------------------
     194'''''''''''''''
     195-
     196'''''''''''''''
     197}}}
     1981. accès aux registres de périphériques?
     199{{{#!protected ------------------------------------------------------------------------------------
     200'''''''''''''''
     201-
     202'''''''''''''''
     203}}}
     2041. ldscript?
     205{{{#!protected ------------------------------------------------------------------------------------
     206'''''''''''''''
     207-
     208'''''''''''''''
     209}}}
     2101. inclusion de code assembleur en C?
     211{{{#!protected ------------------------------------------------------------------------------------
     212'''''''''''''''
     213-
     214'''''''''''''''
     215}}}
     2161. appel de code assembleur depuis le code C?
     217{{{#!protected ------------------------------------------------------------------------------------
     218'''''''''''''''
     219-
     220'''''''''''''''
     221}}}
     222
     223
     224== A3. Passage entre les modes kernel et user
     225
     226
     227Le noyau et l'application sont deux exécutables compilés indépendamment mais pas qui ne sont pas  indépendants. Vous savez déjà que l'application appelle les services du noyau avec l'instruction syscall, mais comment ça se passe vraiment depuis le code C et comment le noyau gère-t-il cet appel? En outre, il y a l'autre sens, comment le noyau lance-t-il l'application?
     228
     229
     230**Questions**
     231
     232
     2331. Comment imposer le placement d'adresse d'une fonction ou d'une variable en mémoire?
     234{{{#!protected ------------------------------------------------------------------------------------
     235'''''''''''''''
     236-
     237'''''''''''''''
     238}}}
     2391. Convention utilisée pour que le noyau puisse lancer l'application?
     240{{{#!protected ------------------------------------------------------------------------------------
     241'''''''''''''''
     242-
     243'''''''''''''''
     244}}}
     2451. Que faire avant et après l'exécution de la fonction `main()`?
     246{{{#!protected ------------------------------------------------------------------------------------
     247'''''''''''''''
     248-
     249'''''''''''''''
     250}}}
     2511. Quels sont les évènements traités par le noyau?
     252{{{#!protected ------------------------------------------------------------------------------------
     253'''''''''''''''
     254-
     255'''''''''''''''
     256}}}
     2571. le registre se réserve l'usage de deux registres, pourquoi et lesquels?
     258{{{#!protected ------------------------------------------------------------------------------------
     259'''''''''''''''
     260-
     261'''''''''''''''
     262}}}
     2631. Comment le noyau traite les causes d'invocation?
     264{{{#!protected ------------------------------------------------------------------------------------
     265'''''''''''''''
     266-
     267'''''''''''''''
     268}}}
     2691. comment fonctionne le gestionnaire de syscall?
     270{{{#!protected ------------------------------------------------------------------------------------
     271'''''''''''''''
     272-
     273'''''''''''''''
     274}}}
     2751. comment fonctionne le gestionnaire d'appel système?
     276{{{#!protected ------------------------------------------------------------------------------------
     277'''''''''''''''
     278-
     279'''''''''''''''
     280}}}
     2811. quels sont les fichiers communs?
     282{{{#!protected ------------------------------------------------------------------------------------
     283'''''''''''''''
     284-
     285'''''''''''''''
     286}}}
     287
     288
     289== A4. Génération du code exécutable
     290
     291
     292Pour simuler le logiciel, il faut produire deux exécutables. Nous utilisons, ici, un Makefile hiérarchique et des règles explicites.
     293Cela sort du cadre de l'architecture, mais vous avez besoin de ce savoir-faire pour comprendre le code, alors allons-y.
     294
     295
     296**Questions**
     297
     298
     2991. Rappelez là quoi sert un Makefile?
     300{{{#!protected ------------------------------------------------------------------------------------
     301'''''''''''''''
     302-
     303'''''''''''''''
     304}}}
     3051. Comment appeler un makefile depuis une autre Makefile?
     306{{{#!protected ------------------------------------------------------------------------------------
     307'''''''''''''''
     308-
     309'''''''''''''''
     310}}}
     3111. comment décrire une règle explicite?
     312{{{#!protected ------------------------------------------------------------------------------------
     313'''''''''''''''
     314-
     315'''''''''''''''
     316}}}
     3171. comment utiliser les variables automatiques du C?
     318{{{#!protected ------------------------------------------------------------------------------------
     319'''''''''''''''
     320-
     321'''''''''''''''
     322}}}
     323
     324
     325
     326== A5. Libc
     327
     328
     329Cette partie ne concerne pas vraiment le noyau, mais il y a peut-être des choses que vous ignorez sur le C, ou certaines opérations, qu'il est nécessaire de connaître pour ce petit système. Cela n'a pas été présenté en cours, alors les questions sont précédées d'une présentation du problème et sa solution.
     330
     331
     332**Questions**
     333
     334
     3351. fonction C à nombre d'arguments variables `fprintf`?
     336{{{#!protected ------------------------------------------------------------------------------------
     337'''''''''''''''
     338-
     339'''''''''''''''
     340}}}
     3411. génération de nombres pseudo-aléatoire `rand`?
     342{{{#!protected ------------------------------------------------------------------------------------
     343'''''''''''''''
     344-
     345'''''''''''''''
     346}}}
     3471. traduction d'une chaîne de caractère en nombre `atoi`?
     348{{{#!protected ------------------------------------------------------------------------------------
     349'''''''''''''''
     350-
     351'''''''''''''''
     352}}}
     353
     354
     355------------------------------------------------------------------------------------------------------------------------------------
     356
     357
     358
     359= B. Travaux pratiques
     360
     361
     362
     363Pour les travaux pratiques, vous devez d'abord répondre aux questions, elles ont pour but de vous faire lire le code et revoir les points du cours. Les réponses sont dans le cours ou dans les fichiers sources. Certaines ont déjà été traitées en TD, c'est normal. Ensuite, vous passez aux exercices pratiques.
     364
     365Le code se trouve dans `$AS5/tp2/`, ouvrez un terminal et allez-y. Dans ce répertoire, vous avez 4 sous-répertoires et un Makefile. Le fichier `$AS5/tp2/Makefile` permet de faire le ménage en appelant les Makefiles des sous-répertoires avec la cible `clean`.
     366
     367
     368== B1. Ajout d'une bibliothèque de fonctions standard pour le kernel (klic)
     369
     370
     371Le noyau gère les ressources matérielles et logicielles utilisées par les applications. Il a besoin de fonctions standards pour réaliser des opérations de base, telles qu'une fonction `print` ou une fonction `rand`. Ces fonctions ne sont pas très originales, mais elles recèlent des subtilités que vous ne connaissez peut-être pas encore. En outre, nous allons utiliser un Makefile définissant un graphe de dépendance explicite entre les fichiers cibles et les fichiers source avec des règles de construction.
     372
     373
     374**Objectifs**
     375
     376
     377- Ajouter une bibliothèque de fonctions standards
     378- Utiliser un Makefile avec des règles explicites
     379
     380
     381**Fichiers**
     382
     383
     384{{{
     3851_klibc/
     386├── kinit.c         : fichier contenant la fonction de démarrage du noyau
     387├── harch.h         : API du code dépendant de l'architecture
     388├── harch.c         : code dépendant de l'architecture du SoC
     389├── hcpu.h          : prototype de la fonction clock()
     390├── hcpu.S          : code dépendant du cpu matériel en assembleur
     391├── kernel.ld       : ldscript décrivant l'espace d'adressage pour l'éditeur de lien
     392├── klibc.h         : API de la klibc
     393├── klibc.c         : fonctions standards utilisées par les modules du noyau
     394└── Makefile        : description des actions possibles sur le code : compilation, exécution, nettoyage, etc.
     395}}}
     396
     397
     398**Questions**
     399
     400
     4011. En ouvrant tous les fichiers dessiner le graphe de dépendance de `kernel.x` vis-à-vis de ses sources?
     402{{{#!protected ------------------------------------------------------------------------------------
     403'''''''''''''''
     404- kernel.x : kinit.o harch.o hcpu.o
     405- kinit.o : etc.
     406
     407'''''''''''''''
     408}}}
     4091. ?
     410{{{#!protected ------------------------------------------------------------------------------------
     411'''''''''''''''
     412-
     413'''''''''''''''
     414}}}
     415
     416
     417**Exercices
     418
     419
     420* Ajout de la fonction cpuid() qui lit le registre $15 du coprocesseur système.
     421
     422
     423== B2. Programme utilisateur mais exécuté en mode kernel
     424
     425
     426Nous allons désormais avoir deux exécutables: le noyau et l'application. Dans cette étape, nous allons voir comment le noyau fait pour appeler l'application, alors que celle-ci n'est pas compilée en même temps que le noyau.
     427
     428
     429**Objectifs**
     430
     431
     432**Fichiers**
     433
     434{{{
     4352_appk/
     436├── Makefile        : Makefile racine qui invoque les Makefiles des sous-répertoires et qui exécute
     437├── kernel ────────── Répertoire des fichiers composant le kernel
     438│   ├── kinit.c     : fichier contenant la fonction de démarrage du noyau
     439│   ├── harch.h     : API du code dépendant de l'architecture
     440│   ├── harch.c     : code dépendant de l'architecture du SoC
     441│   ├── hcpu.h      : prototype de la fonction clock()
     442│   ├── hcpu.S      : code dépendant du cpu matériel en assembleur
     443│   ├── klibc.h     : API de la klibc
     444│   ├── klibc.c     : fonctions standards utilisées par les modules du noyau
     445│   ├── kernel.ld   : ldscript décrivant l'espace d'adressage pour l'édition de liens du kernel
     446│   └── Makefile    : description des actions possibles sur le code kernel : compilation et nettoyage
     447└── user ──────────── Répertoire des fichiers composant l'application user
     448    ├── crt0.c      : fonctions d'interface entre kernel et user, pour le momment : crt0()
     449    ├── main.c      : fonction principale de l'application
     450    ├── user.ld     : ldscript décrivant l'espace d'adressage pour l'édition de liens du user
     451    └── Makefile    : description des actions possibles sur le code user : compilation et nettoyage
     452}}}
     453
     454**Questions**
     455
     4561. Question ?
     457{{{#!protected ------------------------------------------------------------------------------------
     458'''''''''''''''
     459- réponse
     460'''''''''''''''
     461}}}
     462
     463
     464
     465== B3. Programme utilisateur utilisé en mode user mais sans libc
     466
     467
     468
     469Le programme utilisateur doit absolument s'exécuter en mode user et il doit passer par des appels système pour accéder aux services du noyau. Les services, ici, sont limités (l'accès au TTY, exit et clock), il n'empêche que pour gérer ces appels, il faut l'analyseur des causes d'appels à l'entrée du noyau et un gestionnaire de `syscall`. Il faut aussi le gestionnaire d'exceptions, parce que s'il y a une erreur de programmation, le noyau doit afficher quelque chose pour aider le programmeur.
     470
     471
     472**Objectifs**
     473
     474 
     475**Fichiers**
     476
     477{{{
     4783_syscalls/
     479├── Makefile        : Makefile racine qui invoque les Makefiles des sous-répertoires et qui exécute
     480├── common ────────── répetoire des fichiers commun kernel / user
     481│   └── syscalls.h  : API la fonction syscall et des codes de syscalls
     482├── kernel ────────── Répertoire des fichiers composant le kernel
     483│   ├── kinit.c     : fichier contenant la fonction de démarrage du noyau
     484│   ├── harch.h     : API du code dépendant de l'architecture
     485│   ├── harch.c     : code dépendant de l'architecture du SoC
     486│   ├── hcpu.h      : prototype de la fonction clock()
     487│   ├── hcpu.S      : code dépendant du cpu matériel en assembleur
     488│   ├── klibc.h     : API de la klibc
     489│   ├── klibc.c     : fonctions standards utilisées par les modules du noyau
     490│   ├── kpanic.h    : déclaration du tableau de dump des registres en cas d'exception
     491│   ├── kpanic.c    : fonction d'affichage des registres avant l'arrêt du programme
     492│   ├── ksyscalls.c : Vecteurs des syscalls
     493│   ├── kernel.ld   : ldscript décrivant l'espace d'adressage pour l'édition de liens du kernel
     494│   └── Makefile    : description des actions possibles sur le code kernel : compilation et nettoyage
     495└── user ──────────── Répertoire des fichiers composant l'application user
     496    ├── crt0.c      : fonctions d'interface entre kernel et user, pour le momment : crt0()
     497    ├── main.c      : fonction principale de l'application
     498    ├── user.ld     : ldscript décrivant l'espace d'adressage pour l'édition de liens du user
     499    └── Makefile    : description des actions possibles sur le code user : compilation et nettoyage
     500}}}
     501
     502**Questions**
     503
     5041. Question ?
     505{{{#!protected ------------------------------------------------------------------------------------
     506'''''''''''''''
     507- réponse
     508'''''''''''''''
     509}}}
     510
     511
     512
     513
     514== B4.  Accès aux registres de contrôle des terminaux `TTY`
     515
     516
     517
     518**Objectifs**
     519
     520 
     521**Fichiers**
     522
     523{{{
     5244_libc/
     525├── Makefile        : Makefile racine qui invoque les Makefiles des sous-répertoires et qui exécute
     526├── common ────────── répetoire des fichiers commun kernel / user
     527│   └── syscalls.h  : API la fonction syscall et des codes de syscalls
     528├── kernel ────────── Répertoire des fichiers composant le kernel
     529│   ├── kinit.c     : fichier contenant la fonction de démarrage du noyau
     530│   ├── harch.h     : API du code dépendant de l'architecture
     531│   ├── harch.c     : code dépendant de l'architecture du SoC
     532│   ├── hcpu.h      : prototype de la fonction clock()
     533│   ├── hcpu.S      : code dépendant du cpu matériel en assembleur
     534│   ├── klibc.h     : API de la klibc
     535│   ├── klibc.c     : fonctions standards utilisées par les modules du noyau
     536│   ├── kpanic.h    : déclaration du tableau de dump des registres en cas d'exception
     537│   ├── kpanic.c    : fonction d'affichage des registres avant l'arrêt du programme
     538│   ├── ksyscalls.c : Vecteurs des syscalls
     539│   ├── kernel.ld   : ldscript décrivant l'espace d'adressage pour l'édition de liens du kernel
     540│   └── Makefile    : description des actions possibles sur le code kernel : compilation et nettoyage
     541├── uapp ──────────── Répertoire des fichiers de l'application user seule
     542│   ├── main.c      : fonction principale de l'application
     543│   └── Makefile    : description des actions possibles sur le code user : compilation et nettoyage
     544└── ulib ──────────── Répertoire des fichiers des bibliothèques système liés avec l'application user
     545    ├── crt0.c      : fonctions d'interface entre kernel et user, pour le momment : crt0()
     546    ├── libc.h      : API pseudo-POSIX de la bibliothèque C
     547    ├── libc.c      : code source de la libc
     548    ├── main.c      : fonction principale de l'application
     549    ├── user.ld     : ldscript décrivant l'espace d'adressage pour l'édition de liens du user
     550    └── Makefile    : description des actions possibles sur le code user : compilation et nettoyage
     551
     552}}}
     553
     554**Questions**
     555
     5561. Question ?
     557{{{#!protected ------------------------------------------------------------------------------------
     558'''''''''''''''
     559- réponse
     560'''''''''''''''
     561}}}
     562