177 lines
6.9 KiB
Markdown
177 lines
6.9 KiB
Markdown
# KFS_2 — GDT & Stack
|
||
|
||
Traduction française du sujet. Le PDF reste la source en cas de doute.
|
||
|
||
| | |
|
||
|--|--|
|
||
| Fichier d’origine à la racine | `kfs-2sujet.pdf` |
|
||
| Copie de travail | [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 ! |
|
||
|
||
Visuels : [C1](captures/01-couverture-42.png), [C2](captures/02-habillage-page.png), et la même image [C3](captures/03-kfs-choose-wisely.png) dans la section langage. Pas de schéma de GDT.
|
||
|
||
## 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).
|
||
|
||
« Get it ? Good. Now, let’s move on. »
|
||
|
||
## III. Objectifs
|
||
|
||
Créer, remplir et lier une Global Descriptor Table dans le noyau.
|
||
|
||
« 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
|
||
|
||
Même cadre que KFS-1, avec quelques formulations différentes.
|
||
|
||
### IV.1.1 Émulation
|
||
|
||
Partie non obligatoire. N’importe quel gestionnaire de virtuel convient. KVM est suggéré. Les exemples du sujet utilisent KVM.
|
||
|
||
### IV.1.2 Langage
|
||
|
||
Le C n’est pas obligatoire pour cette suite de projets. Les documentations sont souvent en C : un autre langage implique de traduire. Exemple C++ : `new` et les classes exigent une interface mémoire que le noyau n’a pas encore. C++, Rust, Go, ou même tout en ASM, sont cités.
|
||
|
||
Image [C3](captures/03-kfs-choose-wisely.png) au même endroit que dans KFS-1.
|
||
|
||
### IV.2 Compilation
|
||
|
||
Compilateur libre. L’auteur utilise gcc et nasm. Un Makefile doit être ajouté au dépôt.
|
||
|
||
Mêmes flags, présentés comme un exemple C++ :
|
||
|
||
- `-fno-builtin`
|
||
- `-fno-exception`
|
||
- `-fno-stack-protector`
|
||
- `-fno-rtti`
|
||
- `-nostdlib`
|
||
- `-nodefaultlibs`
|
||
|
||
Pas de lien vers une bibliothèque de l’hôte, sinon le noyau ne s’exécute pas.
|
||
|
||
### IV.3 Édition de liens
|
||
|
||
Il faut créer un linker pour le noyau. On CAN utiliser le binaire `ld` de l’hôte. Il est FORBIDDEN d’utiliser le fichier `.ld` de l’hôte. (KFS-1 disait CANNOT ; KFS-2 dit FORBIDDEN.)
|
||
|
||
### IV.4 Architecture
|
||
|
||
i386 (x86) obligatoire.
|
||
|
||
### IV.5 Documentation
|
||
|
||
Le wiki OSDev est recommandé par l’auteur. Lien sur le mot `OSDev`.
|
||
|
||
### IV.6 Code de base
|
||
|
||
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.
|
||
|
||
« Have fun ! »
|
||
|
||
Encadré PERFECT, identique à KFS-1 : bonus évalué seulement si l’obligatoire est intégralement fonctionnel.
|
||
|
||
## VII. Rendu et évaluation par les pairs
|
||
|
||
Rendre le travail dans le dépôt Git. Seul le contenu du dépôt est évalué. Vérifier les noms de dossiers et de 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`.
|