- Partage d’une expérience de projet universitaire consistant à tenter le portage du système d’exploitation Xv6 à l’aide d’un CPU basé sur une ISA RISC conçue sur mesure et d’un compilateur C développé en interne
- Le projet a été mené en construisant directement tous les éléments, dont la conception du CPU, le développement du compilateur C (Ucc) et le portage de Xv6
- Pour faire fonctionner l’OS, l’équipe s’est attaquée à la conception de fonctions matérielles et logicielles clés comme les interruptions, la mémoire virtuelle et le cache
- Lors du portage de Xv6, elle a rencontré de nombreux obstacles comme des problèmes de portabilité, la difficulté du débogage et des bugs liés au cache, qu’elle a toutefois résolus par elle-même
- Elle est finalement parvenue à faire tourner des applications interactives comme SL, Minesweeper et 2048, ainsi qu’un programme de ray tracing, obtenant ainsi une réussite majeure sur les plans pédagogique et technique
Vue d’ensemble du projet
- Ce projet est l’un des travaux pratiques emblématiques du département d’informatique de l’Université de Tokyo, centré sur l’acquisition d’une expérience concrète en exécution d’applications, en construction de compilateurs, en conception matérielle et en architecture CPU
- Son objectif était d’implémenter directement sur FPGA l’ISA d’un CPU conçu par les étudiants, de créer pour celui-ci une toolchain C (Ucc), puis d’étendre le tout au portage d’un système d’exploitation comme Xv6
- La majeure partie du travail expérimental s’est déroulée en apprentissage autonome
Expérimentation CPU et travaux demandés
- Des équipes de 4 à 5 personnes ont participé à la conception d’une nouvelle architecture CPU, à son implémentation sur FPGA et au développement d’un compilateur pour cette architecture
- Après la création d’un compilateur pour un sous-ensemble d’OCaml, l’exécution d’un programme de ray tracing constituait l’objectif d’évaluation obligatoire
- En cas de temps disponible, chaque groupe pouvait définir son propre défi, et certains étudiants ont mené des expériences étendues comme l’accélération du CPU, le développement multicœur ou l’exécution de musique et de jeux
- L’équipe Group 6 s’est donné pour objectif le portage d’un système d’exploitation, ce qui a conduit à la formation d’une nouvelle équipe commune, Group X
Xv6 et le défi du portage
- Le choix s’est porté sur Xv6 (basé sur Unix v6, pour x86), développé au MIT à des fins pédagogiques
- Xv6 est un OS de type Unix simple, mais son exécution sur du matériel réel pose divers problèmes, notamment la nécessité d’un compilateur C89, d’interruptions spécifiques, de la prise en charge des adresses virtuelles et une portabilité limitée
- Xv6 a été conçu avec des hypothèses propres au x86, comme
char sur 1 octet et int sur 4 octets, ce qui a entraîné de nombreux problèmes lors du portage
Développement du compilateur et de la toolchain (Ucc)
- Dans les travaux pratiques existants, le développement d’un compilateur OCaml était la norme, mais l’exécution de Xv6 exigeait un compilateur C89, que l’équipe a donc décidé de développer elle-même
- En s’appuyant sur le prototype de compilateur C de l’un des membres, l’équipe a construit sa propre nouvelle toolchain, Ucc
- Elle a également conçu elle-même non seulement le compilateur, mais aussi un Primitive Linker et des outils de débogage
Conception du CPU et du simulateur
- Le CPU a été conçu en langage de description matérielle (HDL, par ex. Verilog / VHDL), puis implémenté sur un FPGA réel via un processus de synthèse logique avec des outils comme Vivado ou Quartus
- Les itérations répétées de synthèse logique prenaient énormément de temps et impliquaient en pratique de longues périodes d’attente
- Après les fonctions de base du CPU, le support matériel nécessaire à l’exécution de l’OS, comme les interruptions, la MMU et la TLB, a également été conçu séparément
- Le CPU final a été baptisé GAIA
- Le simulateur a reçu l’ajout d’interruptions réelles, de traduction d’adresses virtuelles et d’outils de débogage
Problèmes rencontrés pendant le portage et solutions
- En raison de la faible portabilité de Xv6, des comportements anormaux apparaissaient selon les spécifications du CPU et du compilateur
- Exemple : lorsque
char et int étaient définis sur 32 bits, les opérations sur pointeurs et la structure de la pile se retrouvaient cassées
- Le compilateur Ucc a été amélioré afin que
char corresponde à 8 bits
- La gestion des interruptions a constitué une partie particulièrement difficile, conduisant à l’ajout d’outils de débogage comme un désassembleur et des dumps d’état dans le simulateur maison
- Le problème de cache aliasing provenait du fait que GAIA utilisait l’adresse virtuelle comme index de cache ; il a été résolu par l’introduction de la technique du Page Coloring
Résultat final : exécution de l’OS et des applications
- Le 1er mars, l’équipe a finalement réussi à faire tourner complètement Xv6 à la fois sur le simulateur et sur le vrai CPU (matériel)
- Elle a réussi à exécuter des applications interactives comme un mini curses maison, la commande SL, Minesweeper et 2048
- 2048 a notamment nécessité l’ajout d’une prise en charge des entrées en mode non canonique
- En modifiant Xv6, l’équipe a même ajouté des fonctions correspondant à des éléments de style POSIX comme ioctl et termios
- Un petit assembleur, un mini vi et d’autres outils ont aussi été implémentés, permettant un véritable « environnement de programmation en temps réel »
- Le programme de ray tracing a lui aussi été exécuté au-dessus du système d’exploitation, dépassant ainsi les objectifs initiaux du travail pratique
Importance du projet et suites données
- Après cette expérimentation, plusieurs générations d’étudiants ont continué à concevoir directement leurs propres CPU et OS pour mener diverses expériences
- Par exemple en adoptant l’ISA RISC-V, en créant leur propre OS ou en faisant tourner Linux
- Ce type de travail pratique permet d’expérimenter directement toute la stack matériel/logiciel et d’acquérir une compréhension concrète des algorithmes, de l’intégration matériel-logiciel et des structures bas niveau
- Même si certains critiquent l’inefficacité d’une telle « réinvention de la roue », l’effet pédagogique et le plaisir d’apprendre en construisant réellement restent considérables
Démonstration réelle et code source
- Démonstration exécutable directement ici : GAIA CPU + démo Xv6
- La version portée sur MIPS est publiée en open source ici
Conclusion
- L’article souligne l’importance de l’expérience d’intégration matériel-logiciel, avec pour leçon qu’« on n’apprend rien mieux qu’en construisant soi-même »
- Les étudiants suivants ont eux aussi continué à relever de nouveaux défis, avec l’espoir de voir un jour Linux ou une VM fonctionner sur leur propre ISA
- Le récit s’achève en citant les noms des membres du projet
4 commentaires
Je les envie de pouvoir vivre ce genre d’expérience à l’université. Ça a l’air vraiment amusant...
Ça a dû être vraiment amusant.
Descendez un peu plus bas…
Fabriquer un CPU 8 bits… ?
https://eater.net/8bit
Commentaire Hacker News
Ça me rappelle un projet de groupe que nous avions mené à trois pendant trois semaines à l’université. Parmi plusieurs sujets, il y avait notamment l’idée de créer nous-mêmes un système d’exploitation très basique, et nous avons demandé aux professeurs si nous pouvions porter MINIX3 sur un Raspberry Pi, ce qu’ils ont accepté (MINIX3 ayant déjà un port ARM pour BeagleBoard, cela semblait possible).<br>C’était bien plus difficile que prévu, et une avalanche de problèmes techniques totalement inattendus est apparue. En particulier, le Raspberry Pi 3 démarrait en mode hypervisor au lieu du mode supervisor, ce qui nous a bien fait souffrir, et la précision de l’émulation Raspberry Pi dans QEMU était tellement mauvaise qu’elle était presque inutilisable pour le développement d’OS. Nous avons passé une semaine entière à faire du débogage matériel bas niveau pour trouver une solution. <br>Au final, nous avons réussi à produire un port fonctionnel incluant des pilotes UART, GPIO et framebuffer, et nous l’avons fait tourner sur Raspberry Pi 2 et 3. Nous avons fait la présentation sur le vrai matériel, affiché l’image du ramdisk avec un script shell, surveillé les broches GPIO pour faire avancer ou reculer les diapositives, et manipulé le tout directement en court-circuitant les broches avec un couteau. En termes d’originalité, c’était une présentation incroyablement marquante, et je pense que j’ai encore cette image SD quelque part
Ça a l’air d’avoir été une super expérience<br>Au moment où vous avez proposé de porter MINIX3 sur Raspberry Pi, les professeurs se doutaient peut-être déjà que vous alliez échouer<br>Quand la précision de l’émulation Raspberry Pi de QEMU laissait à désirer, j’ai adopté une stratégie consistant à faire d’abord tourner l’OS dans QEMU, puis à m’en remettre à la chance sur le vrai matériel. Ça marchait plutôt bien<br>Je suis curieux de savoir comment vous faisiez le débogage sur le vrai Raspberry Pi
Le coup du couteau pour court-circuiter les GPIO me rappelle une fois où j’ai démarré une carte mère ATX sans bouton d’alimentation en court-circuitant les deux broches d’alim<br>Mais ton setup était bien plus classe. Bien joué
J’ai fait quelque chose de similaire à SFU il y a 25 à 30 ans. Je n’y ai pas installé d’OS ni de compilateur, et ce n’était pas un projet d’équipe<br>Si ce genre d’expérimentation t’intéresse, je recommande Turing Complete, qui propose un guide et un outillage accessible. On peut partir de quelques portes logiques et aller jusqu’à un véritable ordinateur. Il est aussi possible de partager la communauté et des composants, et il y a même un cœur RiscV. C’est vraiment amusant, je recommande de l’essayer sur Steam<br>Lien Steam de Turing Complete
Ce billet me fait penser à un projet universitaire vaguement similaire. Je me souviens qu’il y avait au moins un compilateur C personnalisé et un OS personnalisé. Je ne me rappelle plus exactement du nom
À titre de référence, voici un sujet connexe publié auparavant : lien vers l’ancien billet
Quand on construit soi-même le CPU + le compilateur + l’OS, il n’y a carrément aucune plateforme sous-jacente. La plateforme, c’est moi.<br>Les bugs deviennent les lois du système. D’habitude, on débogue dans des couches d’abstraction conçues par d’autres ; ici, même ces règles-là, c’est moi qui les définis. En un sens, l’OP a dû déboguer ses propres règles
Vraiment impressionnant. Le travail dans le bas niveau est souvent fastidieux et très chronophage, et c’est encore plus dur quand on n’a pas d’outils indispensables comme un débogueur
kprintfbizarre à l’oscilloscope, tu n’as pas encore goûté au vrai bas niveauMagic-1 et BMOW avaient fait des choses similaires autrefois<br>Pour les détails, voir homebrewcpu.com<br>Pour une liste de sites de CPU faits maison, voir homebrewcpuring.org
Le moment est peut-être venu de ne plus se contenter d’une implémentation sur FPGA et d’aller courir dans un labo de semi-conducteurs pour demander qu’on fabrique directement son propre CPU