Maestro : un noyau en Rust visant la compatibilité avec Linux
(blog.lenot.re)- Maestro est un projet qui vise à recréer en Rust un système d’exploitation de type Unix, léger tout en étant suffisamment compatible avec Linux pour un usage quotidien
- Lancé en 2018 comme projet scolaire, il a d’abord été implémenté en langage C, avant de passer à Rust en raison de problèmes de maintenance de la base de code et des exigences de sûreté propres au développement de noyau
- Il s’agit actuellement d’un noyau monolithique pour x86 32 bits ; 135 des 437 appels système Linux y sont implémentés à un certain degré, soit environ 31 %
- Le projet développe aussi Solfège, un système de démarrage et gestionnaire de démons, des utilitaires système et le gestionnaire de paquets blimp ; musl, bash et une partie des GNU coreutils fonctionnent également
- Le projet reste à un stade très précoce et instable ; les tests étant principalement réalisés sous QEMU, VMWare et VirtualBox, il est plus sûr de ne pas l’installer sur une machine contenant des données importantes
Objectifs et point de départ de Maestro
- Maestro est un système d’exploitation de type Unix écrit en Rust à partir de zéro
- L’objectif est de créer un système léger, suffisamment compatible avec Linux pour pouvoir être utilisé au quotidien
- Le projet a été lancé pour disposer d’un environnement permettant de comprendre directement un système de A à Z et de le personnaliser comme souhaité
Pourquoi être passé de C à Rust
- Le premier commit a été créé le 22 décembre 2018 à 03:18, et le projet a commencé comme devoir scolaire
- L’implémentation initiale a été menée pendant environ un an et demi en langage C, mais il est devenu difficile de garder la base de code propre
- Les avantages obtenus en repartant avec Rust
- Pouvoir reconcevoir le projet depuis le début à partir des enseignements tirés des erreurs précédentes
- Pouvoir tenter quelque chose de plus nouveau que simplement réécrire en C un noyau similaire à Linux
- Grâce au système de types de Rust, une partie de la responsabilité de la sécurité mémoire peut être confiée au compilateur plutôt qu’au programmeur
Les points où Rust s’est révélé avantageux pour le développement de noyau
- Le débogage du développement de noyau est bien plus difficile que celui d’une application classique
- La documentation est difficile à trouver, et les implémentations du BIOS elles-mêmes peuvent contenir des défauts
- Au démarrage, le noyau a accès à toute la mémoire et peut donc écrire à de mauvais emplacements, y compris dans son propre code
- Il n’est pas possible d’utiliser des outils comme valgrind pour suivre les fuites mémoire
- gdb peut être utilisé avec QEMU et VMWare, mais le comportement du noyau peut varier selon l’émulateur ou la machine virtuelle
- Certains environnements, comme VirtualBox, ne prennent pas gdb en charge, et les fonctions de prise en charge de gdb dans QEMU et VMWare sont elles aussi incomplètes ; gdb peut également planter
- Pour réduire ces problèmes, un langage à sûreté mémoire est avantageux même pour le développement de noyau
- Rust a aidé à intégrer plusieurs garde-fous dans le noyau et est considéré comme la meilleure décision du projet
État actuel de l’implémentation
- Maestro est actuellement un noyau monolithique et ne prend en charge que l’architecture x86 32 bits
- État de l’implémentation au moment de la rédaction
- 135 des 437 appels système Linux sont implémentés à un certain degré
- Taux d’implémentation des appels système : {p:31}
- L’ensemble du dépôt compte 615 fichiers et 48 800 lignes de code
- Le nombre de lignes est calculé avec la commande
cloc
- Composants de l’OS hors noyau
- Solfège : un système de démarrage et gestionnaire de démons, assez proche de systemd mais plus léger
- maestro-utils : un ensemble de commandes utilitaires système
- blimp : un gestionnaire de paquets
- Les autres composants sont publiés sur GitHub
- Logiciels tiers dont le fonctionnement a été vérifié
- La bibliothèque standard C musl
-
bash
- Certaines commandes GNU coreutils, comme
ls,cat,mkdir,rm,rmdir,unameetwhoami - Comme le neofetch d’origine ne connaît pas Maestro, une version patchée de neofetch est nécessaire
- Certaines commandes GNU coreutils, comme
Comment tester soi-même et quelles sont les limites
- L’OS en est encore à un stade très précoce et est très instable
- Il n’est pas recommandé de l’installer sur une machine contenant des données importantes
- Jusqu’à présent, il a principalement été testé avec QEMU, VMWare et VirtualBox
- Il existe deux méthodes d’installation
- Télécharger un fichier
.isocompressé précompilé - Construire soi-même l’ISO
- Télécharger un fichier
- L’ISO contient l’installateur de l’OS et peut être exécutée dans QEMU, VMWare, VirtualBox, etc.
- L’exécution de l’ISO nécessite suffisamment de RAM, et 1 Go suffit
- Cela s’explique par le fait que les paquets à installer sont stockés en RAM dans l’initramfs, et non sur disque
- L’OS ne peut actuellement pas lire directement une clé USB ou un CD-ROM et dépend donc du bootloader
Sujets qui seront abordés dans l’article
- L’objectif n’est pas d’écrire un tutoriel de création d’OS
- Comme ressources de base pour créer un OS, osdev.org et le blog de Philipp Oppermann sont recommandés
- À l’avenir, les sujets abordés porteront sur des thèmes plus avancés, les processus de résolution de problèmes, et la manière dont les ordinateurs, les systèmes d’exploitation et Internet fonctionnent en interne
Orientations de développement à venir
- La priorité est le nettoyage de la base de code et l’optimisation des performances
- Comme le projet a commencé comme projet scolaire, certains raccourcis ont été pris pour respecter les délais, et la dette technique accumulée doit être remboursée
- Certaines fuites mémoire doivent aussi être corrigées, et l’optimisation des performances pourrait faire l’objet d’un article
- Le prochain grand objectif est de faire fonctionner entièrement le gestionnaire de paquets au-dessus de l’OS
- La prise en charge réseau est nécessaire et est actuellement en développement
- La prise en charge des bibliothèques partagées est nécessaire
- Les bibliothèques partagées doivent mapper directement des fichiers en mémoire, mais l’implémentation actuelle de l’appel système
mmapdu noyau ne le prend pas en charge
- Ensuite, il sera plus facile d’installer et de tester des programmes comme gcc/g++, clang, rustc, make, Git et Vim
- À terme, l’objectif est de développer le noyau directement sur Maestro
Processus de développement pour améliorer la maturité du noyau
- Le développement consiste à exécuter des programmes sur le noyau puis, s’ils ne fonctionnent pas, à identifier l’appel système responsable pour l’implémenter ou le corriger
- Exécuter un programme sur le noyau
- S’il ne fonctionne pas, observer la sortie des appels système pour trouver le premier appel système qui pose problème
- Si cet appel système n’est pas implémenté ou contient un bug, l’implémenter ou le corriger
- Relancer le programme
- Plus le nombre de programmes qui fonctionnent correctement sur le noyau augmente, plus le noyau devient stable et abouti
1 commentaires
Avis sur Hacker News
Merci beaucoup pour vos encouragements, cela compte énormément car j’ai consacré beaucoup d’efforts à ce projet.
Le site semble assez lent, voire indisponible, pour le moment ; il y a plus de trafic que prévu et je soupçonne aussi une attaque DoS.
Je suis au travail pour l’instant, donc je ne peux pas vraiment m’y consacrer tout de suite, mais j’essaierai de le rendre plus fiable une fois rentré chez moi.
En 2010, avant l’existence de Rust, juste après la fac, j’avais un peu bricolé un OS hobby de type Unix en C, et c’était vraiment amusant.
Je t’envie d’avoir pu trouver le temps d’aller aussi loin.
La barre de navigation occupe environ 33 % de l’écran et on ne peut pas la retirer.
Je ne comprends pas pourquoi les gens fixent ce genre d’élément et privent les lecteurs d’un espace de lecture précieux. Si on veut, on peut remonter tout en haut en environ 300 ms.
Petit projet très sympa. C’est étonnant que ça démarre aussi bien alors que moins d’un tiers des appels système de Linux sont implémentés.
Cela dit, les éléments manquants sont probablement les plus complexes. Par exemple, la couche TTY semble pour l’instant assez rudimentaire, et il y aura sans doute beaucoup de travail pour la faire correctement.
Donc j’ai du mal à imaginer que Maestro fasse tourner des applications Linux dans les trois prochaines années. Et cela, même sans prendre en compte les milliers de pilotes dont dispose Linux.
Les plateformes matures accumulent de la logique pour prendre en charge de nombreux scénarios, si bien que la plupart des usages n’ont pas besoin de la majorité du système.
C’est un peu comme le dicton : « personne n’utilise plus de 10 % d’Excel, mais les 10 % utilisés ne sont pas les mêmes pour chacun ».
En implémentant seulement 30 % des fonctions d’Excel, on pourrait probablement créer un moteur capable d’ouvrir 99 % des feuilles de calcul existantes. Mais si l’on veut une compatibilité documentaire complète, il reste encore beaucoup de chemin.
Certains appels système ne sont invoqués que dans certains chemins de code, ou peuvent être de nouveaux appels nécessaires seulement lorsqu’on cible un noyau plus récent.
Il y a beaucoup d’appels système, et certains sont assez obscurs. Une réimplémentation totalement ouverte devra sans doute finir par en prendre en charge la plupart, mais un tiers est un bon point de départ.
[1] Je voulais faire tourner la VM sur bare metal ou démarrer dessus comme sur une VM, et à part quelque chose du genre
init=/path/to/the/vm, cela semblait être le moyen demandant le moins d’efforts pour y parvenir. Mais cette approche ne m’apportait pas ce que je voulais vraiment, à savoir mettre les pilotes matériels et la pile TCP dans le langage de la VM.Je ne pense pas qu’il soit nécessaire de faire tourner Steam, LibreOffice ou Firefox pour que ce soit utile. Beaucoup de composants d’un serveur classique ou d’une architecture de microservices font des choses relativement simples, et pourraient tirer de gros bénéfices d’un noyau sûr et simple.
Il y a aussi Kerla, un noyau monolithique écrit en Rust qui visait la compatibilité avec l’ABI Linux. Il semble toutefois être en sommeil depuis plusieurs années.
[1] https://news.ycombinator.com/item?id=28986229
Il repose sur une architecture microkernel et est sans doute un peu plus mature. Comme il est sous licence MIT, il pourrait aussi y avoir des possibilités de partage de code.
Rien que pour voir « si un hacker compétent peut trouver quelque chose du seul fait que ce soit écrit en Rust », ce serait intéressant de faire de la sécurité / du test d’intrusion / du fuzzing.
Je suis sûr à 100 % que des tests de fuzzing ou d’intrusion feraient apparaître beaucoup de problèmes. Je n’ai simplement pas encore eu le temps de m’en occuper.
On dirait quelque chose qui avait déjà été tenté dans le projet Kerla, désormais arrêté.
Ça a l’air d’un projet intéressant. Cela dit, je pense que les inconvénients du C et les difficultés du développement d’OS se situent surtout du côté du débogage.
En passant à Rust, certains types d’erreurs mémoire ont sans doute disparu, mais le débogage reste-t-il aussi pénible ? Ou bien est-il devenu suffisamment réduit pour être supportable ?
Le débogage reste pénible, mais beaucoup moins qu’avant.
Par exemple, il est peu probable d’oublier d’utiliser un mutex, car le compilateur le signale comme une erreur.
Cela ne veut pas dire que c’est une solution miracle : des problèmes comme les interblocages existent toujours, surtout quand les interruptions s’en mêlent.
Par exemple, si un mutex est verrouillé et qu’une interruption survient, le code qui l’a verrouillé est suspendu jusqu’à la fin de l’interruption. Mais si le gestionnaire d’interruption essaie de verrouiller le même mutex, on obtient un interblocage, et le système de types ne peut pas aider sur ce point.
La solution consiste à désactiver le traitement des interruptions pendant qu’un mutex est verrouillé, mais le compilateur ne peut pas l’imposer.
C’est un peu hors sujet, mais j’aime bien Gource, que l’auteur a utilisé dans la vidéo des contributions.
Je ne l’avais jamais vu auparavant, mais j’avais eu l’idée de créer quelque chose de similaire il y a quelques années. Comme quoi il n’y a vraiment pas d’idée totalement nouvelle.
J’aime beaucoup l’idée de créer son propre noyau, surtout à des fins d’apprentissage. Je me demande quelles ressources il a utilisées pour comprendre les noyaux et les OS en général.
Je suis surpris que Theseus OS n’ait pas été mentionné. C’est un OS en cours de développement, écrit en Rust depuis zéro, qui exploite les garanties de sûreté mémoire du compilateur Rust pour fournir automatiquement beaucoup de choses qu’un OS traditionnel devrait soigneusement câbler.
Par exemple, il est sûr malgré une architecture à niveau de privilège unique et espace d’adressage unique. Toutes les parties de l’OS sont hot-pluggables.
L’inconvénient est que tout le code natif doit être en Rust, mais un runtime WASM a été implémenté l’an dernier. Fil de discussion connexe d’il y a trois ans :
https://news.ycombinator.com/item?id=25741729
Je ne pensais pas qu’il y aurait quelqu’un d’assez fou pour s’attaquer au projet ft_penguin. Je ne sais même plus si c’est bien son nom, mais franchement, bravo.
Quand j’étais à l’école il y a sept ans, je pensais que c’était l’un des projets offrant le pire rapport récompense/temps nécessaire.
Je me demande s’il a commencé avec un ami au départ, et à quoi cela ressemblait avant la réécriture en Rust. Je me demande aussi s’il travaillait en parallèle sur d’autres projets.
En regardant le code, ça m’a rappelé à quel point c’était amusant, et maintenant j’ai envie de quitter mon boulot DevOps pour revenir à ce que je voulais faire au départ : de l’embarqué ou d’autres travaux bas niveau.