Files
ft_linux/docs/sujets/kfs-2.md
2026-10-23 11:07:06 +02:00

187 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 ! |
## 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.
![Chevalier du Graal, texte YOU MUST CHOOSE... BUT CHOOSE WISELY.](captures/03-kfs-choose-wisely.png)
**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`.