195 lines
8.9 KiB
Markdown
195 lines
8.9 KiB
Markdown
# KFS_2 — GDT & Stack
|
||
|
||
Traduction française du sujet. Le PDF reste la source en cas de doute.
|
||
|
||
| | |
|
||
|--|--|
|
||
| PDF | [originaux/kfs-2_subject.pdf](originaux/kfs-2_subject.pdf) |
|
||
| Auteurs | 42 Staff, pedago@42.fr |
|
||
| Version | 2 |
|
||
| Date du PDF | 26 juillet 2022 |
|
||
| Pages | 10 |
|
||
| Résumé (anglais) | Let’s code the stack ! |
|
||
|
||

|
||
|
||
**Fig. C1 — page de titre.** Aucun texte dans l’image. Interprétation : habillage 42, pas une consigne. Pas de schéma de GDT dans ce PDF.
|
||
|
||

|
||
|
||
**Fig. C2 — pages intérieures.** Aucun texte. Interprétation : filigrane répété. La fig. C3, plus bas, est la seule image légendée.
|
||
|
||
## Liens
|
||
|
||
| Ancre | Cible |
|
||
|-------|--------|
|
||
| `pedago@42.fr` | mailto |
|
||
| `OSDev` | <http://wiki.osdev.org/Main_Page> |
|
||
|
||
Ce PDF ne reprend pas le lien « Some docs here » vers la doc de `ld`.
|
||
|
||
---
|
||
|
||
## I. Avant-propos
|
||
|
||
Le chapitre I est une blague (rotations de classes d’un jeu, patch 6.2.4). Il ne pose aucune exigence. Libellés gardés :
|
||
|
||
- Hunter 6.2.4 Rotation : `Barrage`, `Aspect of the pack`, `Die`, `Blame the heal`
|
||
- Rogue 6.2.4 Rotation : `Pull without the tank`, `Die`, `Blame the heal`
|
||
- Warrior tank 6.2.4 Rotation : `Pull the entire dungeon`, `Die`, `Blame the heal`
|
||
- Druid Heal 6.2.4 Rotation : `Blame the other heal`
|
||
- Death Knight 6.2.4 Rotation : `Roll`, `Your`, `Head`, `On`, `The`, `Keyboard`
|
||
|
||
## II. Introduction
|
||
|
||
Deuxième sujet Kernel from Scratch. Cette fois, coder une pile, et l’intégrer à la GDT.
|
||
|
||
Définition donnée par le sujet. La GDT (« Global Descriptor Table ») est une structure de données qui définit les différentes zones mémoire : adresse de base, taille, et privilèges d’accès comme l’exécution et l’écriture. Ces zones s’appellent des « segments ».
|
||
|
||
Dans une GDT, on peut trouver :
|
||
|
||
- Kernel code, pour stocker le code binaire exécutable
|
||
- Kernel data
|
||
- Kernel stack, pour la pile d’appels pendant l’exécution du noyau
|
||
- User code, pour le code binaire exécutable des programmes utilisateur
|
||
- User program data
|
||
- User stack, pour la pile d’appels pendant l’exécution en userland
|
||
|
||
Le sujet conclut : on voit pourquoi cette structure est vraiment importante dans un noyau.
|
||
|
||
Ensuite, la pile. Rappel donné tel quel, en anglais dans le PDF, traduit ici :
|
||
|
||
> En informatique, une stack est un type abstrait qui sert de collection d’éléments, avec deux opérations principales : push, qui ajoute un élément à la collection, et pop, qui retire l’élément ajouté le plus récemment et pas encore retiré. L’ordre de sortie donne l’autre nom, LIFO (last in, first out).
|
||
|
||
Tu as compris ? Bien. On avance. Le PDF écrit : « Get it ? Good. Now, let’s move on. »
|
||
|
||
## III. Objectifs
|
||
|
||
Créer, remplir et lier une Global Descriptor Table dans le noyau.
|
||
|
||
Ouais, c’est tout. Pas grand-chose, hein ? Le PDF écrit : « Yup, that’s it. Not so much, eh ? »
|
||
|
||
En fait, il faut comprendre comment la mémoire fonctionne vraiment dans un système, comment la pile et la RAM fonctionnent, comment les utiliser, les remplir, et les lier au BIOS.
|
||
|
||
Oui, le BIOS. Grâce à GRUB, il aidera beaucoup. Heureusement qu’il est déjà installé.
|
||
|
||
## IV. Instructions générales
|
||
|
||
### IV.1 Code et exécution
|
||
|
||
#### IV.1.1 Émulation
|
||
|
||
Cette partie n’est pas obligatoire. N’importe quel gestionnaire de machines virtuelles convient. Le sujet suggère KVM : un Kernel Virtual Manager, avec des fonctions avancées d’exécution et de debug. Tous les exemples ci-dessous utilisent KVM.
|
||
|
||
#### IV.1.2 Langage
|
||
|
||
Le C n’est pas obligatoire. On peut utiliser n’importe quel langage pour cette suite de projets.
|
||
Tous les langages ne sont pas adaptés à un noyau. On pourrait coder un noyau en Javascript, mais est-ce une bonne idée ?
|
||
Beaucoup de documentations sont en C. Choisir un autre langage implique de traduire le code tout du long.
|
||
|
||
Toutes les fonctionnalités d’un langage ne sont pas utilisables dans un noyau basique. Exemple avec le C++ : ce langage utilise `new` pour l’allocation, les classes et les déclarations de structures. Dans ce noyau, il n’y a pas encore d’interface mémoire, donc ces fonctionnalités sont inutilisables pour l’instant.
|
||
|
||
Beaucoup de langages peuvent remplacer le C : C++, Rust, Go, etc. On peut même coder le noyau entier en ASM.
|
||
|
||

|
||
|
||
**Fig. C3 — section Langage.** Même image que dans KFS-1. Texte dans l’image : « YOU MUST CHOOSE... » puis « BUT CHOOSE WISELY. » Interprétation : elle illustre le choix du langage. Pas un schéma de GDT ni de pile. Crédit « quickmeme.com » en bas à droite.
|
||
|
||
### IV.2 Compilation
|
||
|
||
#### IV.2.1 Compilateurs
|
||
|
||
N’importe quel compilateur. L’auteur utilise personnellement gcc et nasm. Un Makefile doit être ajouté au dépôt.
|
||
|
||
#### IV.2.2 Flags
|
||
|
||
Pour booter sans dépendance, compiler avec les flags suivants. Les adapter au langage. Ceux-ci sont un exemple pour le C++ :
|
||
|
||
- `-fno-builtin`
|
||
- `-fno-exception`
|
||
- `-fno-stack-protector`
|
||
- `-fno-rtti`
|
||
- `-nostdlib`
|
||
- `-nodefaultlibs`
|
||
|
||
Attention à `-nodefaultlibs` et `-nostdlib`. Le noyau est compilé sur un système hôte, mais il ne peut être lié à aucune bibliothèque de cet hôte, sinon il ne s’exécutera pas.
|
||
|
||
### IV.3 Édition de liens
|
||
|
||
On ne peut pas utiliser un linker existant pour lier le noyau. Comme écrit plus haut, le noyau ne booterait pas. Il faut créer un linker pour ce noyau.
|
||
Attention : on CAN utiliser le binaire `ld` disponible sur l’hôte, mais il est FORBIDDEN d’utiliser le fichier `.ld` de l’hôte. KFS-1 écrivait CANNOT à cet endroit. KFS-2 écrit FORBIDDEN.
|
||
|
||
### IV.4 Architecture
|
||
|
||
L’architecture i386 (x86) est obligatoire (on pourra remercier l’auteur plus tard).
|
||
|
||
### IV.5 Documentation
|
||
|
||
Il existe beaucoup de documentation, bonne et mauvaise. L’auteur estime que le wiki OSDev est l’un des meilleurs. Le mot `OSDev` pointe vers <http://wiki.osdev.org/Main_Page>.
|
||
|
||
### IV.6 Code de base
|
||
|
||
Pour ce sujet, il faut prendre le code KFS précédent et travailler à partir de lui.
|
||
Ou pas... et tout réécrire depuis le début. Au choix.
|
||
|
||
## V. Partie obligatoire
|
||
|
||
Récapitulatif du sujet :
|
||
|
||
- Créer une Global Descriptor Table.
|
||
- La GDT doit contenir :
|
||
- Kernel Code
|
||
- Kernel Data
|
||
- Kernel stack
|
||
- User code
|
||
- User data
|
||
- User stack
|
||
- Le travail ne devrait pas dépasser 10 MB. (La puce est indentée dans la liste de la GDT, dans le PDF.)
|
||
- Déclarer la GDT au BIOS.
|
||
- La GDT doit être placée à l’adresse `0x00000800`.
|
||
|
||
Ensuite, coder un outil pour afficher la pile noyau, de façon lisible par un humain. Astuce du sujet : si `printk` n’existe pas encore, c’est le moment.
|
||
|
||
## VI. Partie bonus
|
||
|
||
En supposant que le clavier fonctionne correctement dans le noyau, et qu’on sache capter une entrée, coder un Shell.
|
||
Pas un shell POSIX, juste un shell minimaliste avec quelques commandes, pour le debug.
|
||
|
||
Exemple du sujet : y mettre l’affichage de la pile noyau, et d’autres choses comme `reboot`, `halt`, etc.
|
||
|
||
Amuse-toi. Le PDF écrit : « Have fun ! »
|
||
|
||
Encadré : le bonus n’est évalué que si la partie obligatoire est PERFECT. Perfect veut dire que l’obligatoire a été fait intégralement et fonctionne sans dysfonctionnement. Si tous les prérequis obligatoires ne sont pas validés, le bonus n’est pas évalué du tout.
|
||
|
||
## VII. Rendu et évaluation par les pairs
|
||
|
||
Rendre le travail dans le dépôt Git, comme d’habitude. Seul le travail à l’intérieur du dépôt est évalué pendant la soutenance. Ne pas hésiter à revérifier les noms des dossiers et des fichiers.
|
||
|
||
Rendre le code, un Makefile et une image virtuelle basique pour le noyau.
|
||
Note du sujet, en capitales dans le PDF : le noyau n’en fait encore rien, donc l’image n’a pas à être taillée comme un éléphant. La borne « 10 MB » est dans la partie obligatoire, pas répétée dans ce paragraphe.
|
||
|
||
---
|
||
|
||
## Grille de lecture
|
||
|
||
### Obligatoire
|
||
|
||
- Repartir du code KFS-1, ou le réécrire. Le sujet laisse les deux.
|
||
- GDT créée, remplie, liée au noyau, déclarée au BIOS, posée à `0x00000800`.
|
||
- Six descripteurs nommés : Kernel Code, Kernel Data, Kernel stack, User code, User data, User stack.
|
||
- Outil d’affichage de la pile noyau, lisible.
|
||
- i386, GRUB déjà là, image et travail dans la limite de 10 MB.
|
||
- Makefile, code, image virtuelle basique.
|
||
- Même interdiction de lien : binaire `ld` autorisé, fichier `.ld` de l’hôte forbidden.
|
||
|
||
### Bonus
|
||
|
||
- Shell minimal de debug, pas POSIX.
|
||
- Exemples de commandes cités : affichage de la pile, `reboot`, `halt`.
|
||
- Le sujet suppose que le clavier du bonus KFS-1 fonctionne.
|
||
- Évalué seulement si l’obligatoire est parfait.
|
||
|
||
### Libellés exacts
|
||
|
||
`Global Descriptor Table`, `GDT`, `0x00000800`, `Kernel Code`, `Kernel Data`, `Kernel stack`, `User code`, `User data`, `User stack`, `printk`, `reboot`, `halt`, `push`, `pop`, `LIFO`, `BIOS`, `GRUB`, `FORBIDDEN`, `10 MB`.
|