Sous-système Windows 9x pour Linux
(social.hails.org)- Projet expérimental permettant d’exécuter de manière coopérative un noyau Linux moderne (6.19) à l’intérieur du noyau Windows 9x, afin de tirer parti simultanément de l’ensemble des fonctionnalités des deux systèmes d’exploitation
- Contrairement à WSL, il n’utilise pas la virtualisation matérielle, ce qui permet de l’exécuter même sur un 486
- Il apporte dans l’environnement Windows 9x des fonctions d’OS modernes comme la pagination, la protection mémoire et l’ordonnancement préemptif, tout en permettant d’exécuter des applications côte à côte sans redémarrage
- Il se compose de trois éléments : un noyau Linux patché, un pilote VxD et un client
wsl.com, avec une adaptation de User-Mode Linux pour appeler l’API du noyau Win9x - Les appels système sont distribués via le gestionnaire d’erreur générale de protection (GPF) au lieu de
int 0x80, en raison de la limite de taille de la table des descripteurs d’interruptions de Win9x - « Fièrement écrit sans IA », sous licence GPL-3
WSL9x - codeberg.org/hails/wsl9x
Aperçu
- WSL9x est un sous-système Linux pour Windows 9x qui exécute de manière coopérative un noyau Linux moderne à l’intérieur du noyau Windows 9x (version 6.19 au moment de la rédaction)
- Il permet d’exploiter simultanément l’ensemble des fonctionnalités des deux systèmes d’exploitation, notamment la pagination, la protection mémoire et l’ordonnancement préemptif
- Il est possible d’exécuter côte à côte des applications des deux OS sans redémarrage
- Il a été écrit manuellement, sans IA
Architecture technique
- WSL9x se compose de trois éléments
- Noyau Linux patché (branche
win9x-um-6.19) - Pilote VxD
- Programme client
wsl.com
- Noyau Linux patché (branche
Pilote VxD
- Il prend en charge l’initialisation de WSL9x, avec pour point d’entrée
vxd/wsl9x.asm - Il configure le mappage initial du code noyau et charge
vmlinux.elfdepuis le disque via des interruptions DOS (vxd/loader.c,vxd/fs.asm) - Le noyau est compilé avec une adresse de base fixe de
0xd0000000 - Il démarre un nouveau thread dans la System VM et lui alloue une pile de 16 KiB pour l’entrée dans Linux
- Il entre ensuite dans une boucle d’événements qui gère l’entrée dans le noyau, la distribution des IRQ, le retour vers l’espace utilisateur et l’état inactif (
vxd/entry.c)
Appels système et gestion des défauts de page
- Le pilote gère les défauts de page et les appels système, c’est-à-dire les événements de l’espace utilisateur qui doivent être distribués au noyau
- Les appels système sont traités via le gestionnaire GPF
- Win9x ne dispose pas d’une table des descripteurs d’interruptions suffisamment longue pour installer correctement un gestionnaire pour
int 0x80, l’interruption d’appel système Linux i386 - Le gestionnaire GPF inspecte l’instruction fautive et, s’il s’agit de
int 0x80, fait avancer le pointeur d’instruction comme si l’interruption avait réussi avant de distribuer l’appel système Linux (vxd/fault.c)
- Win9x ne dispose pas d’une table des descripteurs d’interruptions suffisamment longue pour installer correctement un gestionnaire pour
Modifications du noyau Linux
- Le projet est basé sur User-Mode Linux, mais modifié pour appeler l’API du noyau Windows 9x au lieu de l’API POSIX
- Il s’exécute non pas en mode utilisateur (ring 3), mais en ring 0 (mode superviseur/noyau)
- Une grande partie de l’intégration avec le noyau Win9x, y compris le changement de contexte, se trouve côté noyau Linux
- Emplacement principal du code :
linux/arch/um/os-Win95 - Point d’entrée :
_startdansmain.c, avec notammentprocess.cetmmu.c
- Emplacement principal du code :
Client wsl.com
- Il s’agit d’un programme DOS 16 bits, implémenté dans
wsl/wsl.asm - Il permet d’utiliser l’invite MS-DOS comme fenêtre TTY sans implémentation TTY séparée
- À l’exécution, il appelle l’API WSL9x V86 (
vxd/v86_api.asm) pour obtenir une console inutilisée et demander que la sortie de cette console lui soit distribuée - Il entre ensuite dans une boucle d’événements en attente d’IRQ et tente une lecture clavier lorsqu’une interruption survient
- Il sert aussi de point de synchronisation pour le pilote de console (
vxd/console.c)- Lorsque la sortie Linux est prête, il planifie un événement puis exécute
int 0x29dans le contexte de la VM MS-DOS afin d’afficher les caractères dans la fenêtre DOS - Cette interruption est aussi le point où des pilotes ANSI pour DOS, comme NNANSI, interceptent la sortie terminal pour implémenter les séquences d’échappement ANSI
- Lorsque la sortie Linux est prête, il planifie un événement puis exécute
Prérequis de compilation et d’exécution
- Une toolchain croisée pour la cible
i386-linux-muslest nécessaire (usage de musl-cross-make recommandé) - Une toolchain Open Watcom v2 est nécessaire pour compiler les composants Windows
- Il faut compiler le noyau Linux patché depuis la branche
win9x-um-6.19 - Les variables d’environnement
WATCOMetLINUXdoivent être correctement définies (voir.envrc.examplepour un exemple) - Une image de disque dur
hdd.base.imgavec Windows 9x préinstallé est nécessaire - L’exécution de
makegénèrehdd.imgpréparée pour WSL9x - Depuis l’invite MS-DOS, l’exécution de
wslouvre un pty ; pour les couleurs ANSI, il est recommandé de précharger un pilote commennansi.com
Licence
- GPL-3
2 commentaires
Avis Hacker News
http://www.colinux.org/
https://github.com/wishstudio/flinux
flinux était en réalité assez proche de l’architecture de WSL1, tandis que CoLinux faisait davantage penser à WSL2 dans la mesure où il embarquait le noyau Linux à côté
Techniquement, j’avais l’impression que Cygwin était une approche plus orthodoxe. Au lieu de forcer une plomberie Linux externe, il faisait tourner des binaires POSIX natifs sur Windows, et j’aimais aussi le fait qu’il se contentait d’un simple lien DLL léger sans toucher au ring 0
Cela dit, à l’époque, la commodité des gestionnaires de paquets en ligne de commande faisait défaut, et en pratique, quand je travaillais sous Windows, j’étais assez accro à CoLinux
Le principal problème, dans mon souvenir, c’était le DLL hell. Par exemple, quand un portage Windows d’OpenSSH arrivait avec sa propre version de cygwin1.dll, les conflits de versions étaient fréquents
Malgré tout, à une époque où la RAM était limitée et le swap coûteux, le faible overhead avait son importance
À l’époque, les applications natives dominaient davantage que des choses comme le Web 2.0 ou NodeJS, et Java avait aussi mauvaise réputation
Au final, ça donnait l’impression habituelle de faire deux pas en avant et un pas en arrière
Contrairement à l’idée qu’il n’était pas lent, en pratique il l’était, il était moins compatible que d’autres méthodes, nécessitait une recompilation, et je n’ai pas le sentiment qu’il ait été un outil massivement apprécié pendant la majeure partie de sa vie
Il se passait une énorme magie de compatibilité dans cygwin1.dll, et au bout du compte, on faisait quand même entrer une plomberie Linux externe à l’intérieur du processus. C’est encore plus évident quand on pense à la manière dont il implémentait fork() sans support système
Cygwin ne fonctionne tout simplement pas dans l’isolation AppContainer de Windows. MSYS2 repose encore aujourd’hui sur cette base, donc les binaires MSYS2 ne tournent pas dans AppContainer
C’est pourquoi, pour le sandboxing de Claude Code, il a fallu suivre une voie totalement différente. Claude Code veut Git for Windows, et Git for Windows distribue bash.exe et d’autres outils construits avec MSYS2
En revanche, les vrais builds Windows natifs n’ont pas besoin de ces bidouilles particulières exigées par cygwin1.dll, donc les builds non-MSYS2 que j’ai trouvés fonctionnaient bien dans AppContainer
On peut utiliser pacman d’Arch Linux, ce qui a rendu la gestion de binaires POSIX natifs sur Windows assez conviviale, même sans VM Linux
S’il n’existait pas de version Cygwin précompilée de la bibliothèque C dont on avait besoin, il fallait faire tourner soi-même tout l’arbre de dépendances avec configure et make
Et de mémoire, dans environ deux tiers des cas, il fallait modifier quelque chose à la main, parce que POSIX n’était pas implémenté de façon parfaitement fidèle
Mais obtenir la bonne sémantique demandait toutes sortes de contournements et de hacks ; par exemple, fork n’était pas en copy-on-write
J’ai utilisé Cygwin d’environ 1999 à 2022, j’ai aussi un peu utilisé WSL2, et je m’en sers encore sur mon portable
En revanche, sur mon poste fixe, je suis passé complètement à Linux l’an dernier
À l’époque de Windows XP, je faisais tourner Colinux, et c’était un outil vraiment fascinant
Il était bien plus facile d’y monter une stack LAMP côté Linux, et on pouvait se bricoler un environnement de développement local assez agréable en gardant des éditeurs Windows pour l’édition
On pouvait même expérimenter en y branchant un serveur X11 pour Windows afin d’afficher un bureau Linux par-dessus
En me voyant empiler ainsi un environnement de plus en plus Unix-like sur Windows, j’ai fini par passer à macOS
Au-delà de l’intérêt purement hack, pour un usage réel, je me dis aussi qu’une machine de classe 486 atteindrait vite ses limites de mémoire
http://colinux.org/
J’ai juste l’impression que peu de gens s’en sont rendu compte
À mes yeux, ça ressemblait à une tâche presque impossible
Cela dit, je me suis demandé comment cela apparaîtrait à des gens qui comprennent l’architecture
Ça m’a rappelé cette blague où deux mathématiciens disent qu’un théorème est trivial, puis il faut quand même deux heures d’explication avant d’admettre que oui, c’était vraiment trivial
Le professeur a confirmé et on est simplement passés à la suite
En revanche, je suis profondément impressionné par le fait que l’auteur ait identifié une à une la longue liste de détails digne d’un grimoire qui rendent cela possible
Ainsi, chaque programme ne peut lire qu’une partie de sa propre mémoire, et le CPU ne lui est accordé que pour un temps limité avant de passer au suivant
Windows utilise sérieusement ces mécanismes depuis Windows NT, dont XP fait partie
En revanche, jusqu’à Windows 98, les programmes pouvaient à peu près tout faire, et ces protections matérielles restaient largement sous-exploitées
Le Windows de cette époque me semblait moins être un système d’exploitation qu’un ensemble de bibliothèques fonctionnelles affichant une interface utilisateur et dialoguant avec les périphériques
Le CPU dispose d’un matériel spécial permettant de limiter l’accès à la mémoire et le temps de traitement, et Windows 9x n’en tirait pas pleinement parti
C’est pour cela qu’un sous-système Linux pour Windows 9x pouvait se donner lui-même des airs de système d’exploitation et s’approprier ce matériel pour faire tourner un OS moderne
À mon avis, la partie la plus difficile dans ce genre de travail consiste à comprendre l’API des pilotes Microsoft
La documentation de l’époque 9x n’était ni assez détaillée ni très facile d’accès, et même aujourd’hui, ce n’est pas un domaine particulièrement plaisant
Du coup, il semblait y avoir pas mal de place pour y greffer certaines fonctionnalités bas niveau de Linux
D’un côté, on parlait du fait que les Show HN avaient triplé et qu’il y avait de plus en plus d’apps au même parfum de vibe coding, et de l’autre, quelqu’un passait six ans à creuser les entrailles de Win9x pour y faire tourner un noyau Linux moderne
Comparé aux fils remplis d’apps produites avec des prompts de 20 minutes, ce genre de post me met vraiment de bonne humeur
J’ai trouvé ça plutôt agréable à voir
Au lieu de dire create me an owl app, on demande à une IA de produire un prompt complet pour créer une owl app, puis on le colle dans une autre session d’IA
Parce qu’il existe réellement un produit appelé Zero AI, donc on pouvait aussi le lire ainsi
La formulation est bien plus nette, et le projet lui-même est vraiment impressionnant
https://codeberg.org/hails/wsl9x
Mastodon exige toujours l’exécution de JavaScript rien que pour lire un post, donc en général je passe mon chemin
https://github.com/mastodon/mastodon/issues/23153
https://github.com/mastodon/mastodon/issues/19953
Je connais quelques éléments épars, comme l’existence du VM Monitor et le fait qu’il y ait eu ce type de support, mais j’ai l’impression que les explications détaillées sont dispersées un peu partout
Beaucoup de gens résument Windows comme quelque chose qui tournerait simplement au-dessus de DOS, mais cela ne me semble clairement pas exact
Bien sûr, ce n’est pas une machine virtuelle au sens actuel, mais il y avait là une structure technique assez intéressante, et la plupart des ressources semblent ne l’aborder qu’en surface
Je me demande aussi à quel point ce projet ressemble à BSD on Windows
Et je connais aussi Architecture of Windows 9x, mais je l’ai trouvée pas assez approfondie à mon goût
https://winworldpc.com/product/windows-sdk-ddk/windows-95-ddk
La documentation est très détaillée et contient beaucoup de code d’exemple, ce qui la rend idéale pour creuser le sujet soi-même
Puisque WSL signifie Linux on Windows, cela semble aussi se lire ici comme W9xSL au sens de Linux sur Windows 9x
Je ne peux pas citer de source immédiatement, mais il me semble avoir lu autrefois que cela avait un lien avec une question de marque
En gros, ils auraient voulu l’appeler Linux Subsystem for Windows, mais la Linux Foundation n’autorisait pas un projet non approuvé à utiliser un nom commençant par Linux
La philosophie centrale consistait à avoir plusieurs personality et à traduire les appels système de chaque environnement en appels au noyau NT
WSL1 serait donc, en 2016, une réapplication pour Linux de pratiquement le même tour de force
En revanche, Windows 9x appartenait à la lignée DOS, donc pour y faire tourner Linux, il a probablement fallu des hacks bien plus sales et fondamentalement différents
J’imagine que c’est aussi pour cela que personne ne l’avait fait à l’époque
Le simple fait que cela fonctionne montre à quel point l’architecture NT était en avance sur son temps
Pour un usage pratique, cela fait penser à des environnements encore liés à Windows 98, comme certains logiciels médicaux ou industriels anciens
Cela dit, si quelqu’un a un 486 entre les mains en 2026, il y a de fortes chances qu’il soit bien plus utile d’y faire tourner directement Linux plutôt que de l’injecter dans un dérivé de DOS vieux de 30 ans
Rien que le fait que Windows 9x puisse exécuter DOS impliquait déjà une bonne dose de magie
Je laisse aussi quelques lectures utiles à ce sujet
Ah, coLinux haha -_- un nom qui rappelle de bons souvenirs. Haha. Mais aujourd’hui, même avec WSL, je ne l’utilise pas, alors Win95+Linux, ça, ça me tente bien.