12 Punkte von GN⁺ 7 일 전 | 2 Kommentare | Auf WhatsApp teilen
  • Ein experimentelles Projekt, das einen modernen Linux-Kernel (6.19) kooperativ innerhalb des Windows-9x-Kernels ausführt und so die vollständigen Funktionen beider Betriebssysteme gleichzeitig nutzbar macht
  • Anders als WSL wird keine Hardware-Virtualisierung verwendet, daher läuft es sogar auf einem 486er
  • Paging, Speicherschutz und präemptives Scheduling sowie andere moderne OS-Funktionen werden in der Windows-9x-Umgebung verfügbar, und Anwendungen beider Systeme können ohne Neustart nebeneinander laufen
  • Es besteht aus drei Komponenten: einem gepatchten Linux-Kernel, einem VxD-Treiber und dem wsl.com-Client; User-Mode Linux wurde dafür so umgebaut, dass es Win9x-Kernel-API-Aufrufe nutzt
  • Systemaufrufe werden wegen der Begrenzung der kurzen Interrupt-Deskriptor-Tabelle von Win9x nicht über int 0x80, sondern über einen General Protection Fault (GPF)-Handler verteilt
  • „Proudly written without AI“, Lizenz GPL-3

WSL9x - codeberg.org/hails/wsl9x

Überblick

  • WSL9x ist ein Linux-Subsystem für Windows 9x, das einen modernen Linux-Kernel (zum Zeitpunkt der Beschreibung 6.19) kooperativ innerhalb des Windows-9x-Kernels ausführt
  • Dadurch lassen sich die vollständigen Funktionen beider Betriebssysteme gleichzeitig nutzen, darunter Paging, Speicherschutz und präemptives Scheduling
  • Anwendungen beider Betriebssysteme können ohne Neustart nebeneinander ausgeführt werden
  • Es wurde direkt und ohne AI geschrieben

Technische Struktur

  • WSL9x besteht aus drei Komponenten
    • gepatchter Linux-Kernel (win9x-um-6.19-Branch)
    • VxD-Treiber
    • wsl.com-Clientprogramm

VxD-Treiber

  • Zuständig für die Initialisierung von WSL9x; der Einstiegspunkt ist vxd/wsl9x.asm
  • Richtet das anfängliche Mapping des Kernel-Codes ein und lädt vmlinux.elf über DOS-Interrupts von der Festplatte (vxd/loader.c, vxd/fs.asm)
  • Der Kernel wird mit der festen Basisadresse 0xd0000000 kompiliert
  • Startet einen neuen Thread in der System-VM und reserviert einen 16-KiB-Stack für den Linux-Einstieg
  • Wechselt anschließend in eine Ereignisschleife, die den Kernel-Einstieg, IRQ-Dispatch, die Rückkehr in den User-Space und Leerlaufzustände verarbeitet (vxd/entry.c)

Systemaufrufe und Behandlung von Page Faults

  • Der Treiber verarbeitet Page Faults und Systemaufrufe als User-Space-Ereignisse, die an den Kernel weitergeleitet werden müssen
  • Systemaufrufe werden über einen General Protection Fault (GPF)-Handler verarbeitet
    • Win9x hat keine ausreichend lange Interrupt-Deskriptor-Tabelle, um einen sauberen Handler für den Linux-i386-Systemaufruf-Interrupt int 0x80 zu installieren
    • Der GPF-Handler untersucht die fehlerauslösende Instruktion und schiebt, falls es sich um int 0x80 handelt, den Instruktionszeiger so weiter, als wäre der Interrupt erfolgreich gewesen, und dispatcht dann zum Linux-Systemaufruf (vxd/fault.c)

Umbauten am Linux-Kernel

  • Basiert auf User-Mode Linux, wurde jedoch so modifiziert, dass statt der POSIX-API die Windows-9x-Kernel-API aufgerufen wird
  • Läuft nicht im User-Modus (Ring 3), sondern in Ring 0 (Supervisor-/Kernel-Modus)
  • Ein erheblicher Teil der Win9x-Kernel-Integration, einschließlich des Context Switching, befindet sich auf der Linux-Kernel-Seite
    • Wichtiger Code liegt in linux/arch/um/os-Win95
    • Einstiegspunkt: _start in main.c; zentrale Dateien sind process.c und mmu.c

wsl.com-Client

  • Ein 16-Bit-DOS-Programm, implementiert in wsl/wsl.asm
  • Nutzt die MS-DOS-Eingabeaufforderung als TTY-Fenster, ohne eine separate TTY-Implementierung zu benötigen
  • Beim Start ruft es die WSL9x-V86-API (vxd/v86_api.asm) auf, um eine ungenutzte Konsole zuzuweisen, und meldet an, dass deren Ausgabe an das Programm dispatcht werden soll
  • Danach geht es in eine Ereignisschleife über, wartet auf IRQs und versucht bei Interrupts, Tastatureingaben zu lesen
  • Dient außerdem als Synchronisationspunkt für den Konsolentreiber (vxd/console.c)
    • Wenn Linux-Ausgabe bereitsteht, wird ein Ereignis geplant und im Kontext der MS-DOS-VM int 0x29 ausgeführt, um Zeichen im DOS-Fenster auszugeben
    • Dieser Interrupt ist auch der Punkt, an dem DOS-ANSI-Treiber wie NNANSI die Terminalausgabe abfangen, um ANSI-Escape-Codes umzusetzen

Anforderungen für Build und Ausführung

  • Erfordert eine Cross-Toolchain für das Ziel i386-linux-musl (empfohlen wird musl-cross-make)
  • Erfordert die Open Watcom v2 Toolchain zum Bauen der Windows-Komponenten
  • Erfordert den Build des gepatchten Linux-Kernels aus dem Branch win9x-um-6.19
  • Die Umgebungsvariablen WATCOM und LINUX müssen passend gesetzt werden (Beispiele siehe .envrc.example)
  • Benötigt ein Festplatten-Image hdd.base.img, auf dem Windows 9x bereits vorinstalliert ist
  • Bei Ausführung von make wird ein für WSL9x vorbereitetes hdd.img erzeugt
  • Durch Ausführen von wsl in der MS-DOS-Eingabeaufforderung wird ein pty geöffnet; für ANSI-Farben wird empfohlen, vorher einen Treiber wie nnansi.com zu laden

Lizenz

  • GPL-3

2 Kommentare

 
GN⁺ 7 일 전
Hacker-News-Kommentare
  • Vor WSL waren CoLinux und flinux wohl die bekanntesten Wege, um unveränderte Linux-Binärdateien unter Windows auszuführen.
    http://www.colinux.org/
    https://github.com/wishstudio/flinux
    flinux war strukturell eigentlich näher an WSL1, während CoLinux eher wie WSL2 wirkte, weil dort ein Linux-Kernel daneben mitlief.
    Technisch wirkte Cygwin auf mich eher wie der orthodoxe Ansatz. Statt mit Gewalt externe Linux-Mechanik einzubauen, ließ es native POSIX-Binärdateien auf Windows laufen, und mir gefiel auch, dass es mit einer leichten DLL-Verknüpfung auskam, ohne Ring 0 anzufassen.
    Allerdings fehlte damals der Komfort eines CLI-Paketmanagers, und wenn ich tatsächlich unter Windows gearbeitet habe, war ich ziemlich stark bei CoLinux.
    • Soweit ich mich erinnere, ist Cygwin viel älter als CoLinux. CoLinux kam 2004, Cygwin bereits 1995.
      Das Hauptproblem, an das ich mich erinnere, war die DLL-Hölle. Wenn zum Beispiel ein OpenSSH-Port für Windows seine eigene cygwin1.dll mitbrachte, kam es oft zu Versionskonflikten.
      Trotzdem war der geringe Overhead in einer Zeit mit wenig RAM und schwerfälligem Swapping durchaus relevant.
      Damals dominierten native Apps, nicht so etwas wie Web 2.0 oder NodeJS, und auch Java hatte keinen guten Ruf.
      Am Ende wirkte es wie so oft: zwei Schritte vor, einer zurück.
    • Dass Cygwin der orthodoxe Weg sei, mag nach manchen Maßstäben stimmen, aber für mich war es ein ziemlich merkwürdiger Ansatz.
      Entgegen dem Unterton, es sei nicht langsam, war es in der Praxis langsam, weniger kompatibel als andere Lösungen, erforderte Neukompilierung und war über den Großteil seiner Lebensdauer kein breit geliebtes Werkzeug.
      In cygwin1.dll lief eine enorme Menge Kompatibilitätszauberei, und letztlich wurde die externe Linux-Mechanik einfach in den Prozess hineingezogen. Besonders wenn man daran denkt, wie fork() ohne Systemunterstützung umgesetzt wurde.
      Cygwin läuft in einer Windows-AppContainer-Isolation überhaupt nicht. MSYS2 basiert bis heute darauf, daher laufen auch MSYS2-Binärdateien nicht im AppContainer.
      Deshalb musste man für das Sandboxen von Claude Code einen völlig anderen Weg gehen. Claude Code erwartet Git for Windows, und Git for Windows verteilt unter anderem bash.exe, das mit MSYS2 gebaut wurde.
      Echte native Windows-Builds haben dagegen nicht diese seltsamen Hacks, die cygwin1.dll verlangt, und die non-MSYS2-Builds, die ich gefunden habe, liefen im AppContainer problemlos.
    • Heutzutage bietet MSYS2 wohl einen Paketmanager, obwohl es intern weiterhin von Cygwin abhängt.
      Man kann pacman aus Arch Linux nutzen, sodass sich native POSIX-Binärdateien unter Windows auch ohne Linux-VM ziemlich benutzerfreundlich handhaben lassen.
    • Aus echter Entwicklererfahrung heraus war Arbeit auf Cygwin wirklich schmerzhaft.
      Wenn es von einer gewünschten C-Bibliothek keine vorgebaute Cygwin-Version gab, musste man den kompletten Abhängigkeitsbaum selbst mit configure, make usw. durchbauen.
      Und meiner Erinnerung nach musste man dabei in etwa zwei von drei Fällen noch selbst irgendetwas patchen, weil POSIX eben nicht ganz perfekt passte.
    • Cygwin implementierte im Kern die POSIX-API auf Win32 und mischte zur besseren Kompatibilität einige NT-Aufrufe hinein.
      Um die korrekten Semantiken nachzubilden, waren aber allerlei Umwege und Hacks nötig; zum Beispiel war fork kein Copy-on-Write.
      Ich habe Cygwin ungefähr von 1999 bis 2022 benutzt, WSL2 auch ein wenig, und auf dem Laptop nutze ich es noch immer.
      Mein Desktop ist allerdings seit letztem Jahr komplett auf Linux umgezogen.
  • Ich habe mich ziemlich gefreut, weil das wie eine pre-NT-Version von colinux wirkte.
    Früher, in meinen XP-Zeiten unter Windows, habe ich Colinux laufen lassen, und es war wirklich ein faszinierendes Werkzeug.
    Einen LAMP-Stack auf der Linux-Seite aufzusetzen war viel einfacher, und mit Windows-Editoren konnte man sich eine ziemlich gute lokale Entwicklungsumgebung bauen.
    Man konnte sogar einen X11-Server für Windows anhängen und darauf einen Linux-Desktop laufen lassen.
    Als ich merkte, wie ich mir immer mehr Unix-artige Umgebung auf Windows stapelte, bin ich am Ende einfach zu macOS gewechselt.
    Abseits des reinen Hack-Werts wirkt es für praktische Zwecke so, als würde man auf einem 486er schnell an Speichergrenzen stoßen.
    http://colinux.org/
    • Colinux war wirklich eine technische Meisterleistung.
      Nur haben das nicht viele erkannt.
  • Die Person, die das gebaut hat, wirkt auf mich fast wie ein Zauberer.
    Für mich sah das nach einer nahezu unmöglichen Aufgabe aus.
    Mich würde aber interessieren, wie es auf Leute wirkt, die die Architektur verstehen.
    Deshalb musste ich an den Witz denken, in dem zwei Mathematiker einen Satz als trivial bezeichnen und erst nach zwei Stunden Erklärung zugeben, dass er tatsächlich trivial ist.
    • Ich stand im ersten CS-Semester in einer Mengenlehre-Vorlesung einmal selbst an der Tafel, konnte einen Teil des Beweises absolut nicht erkennen und habe ihn einfach als trivial abgetan.
      Der Professor meinte nur, ja, stimmt, und wir sind einfach weitergegangen.
    • Ich würde sagen, ich verstehe die Architektur im Großen und Ganzen, und auf mich wirkt das nicht wie Magie.
      Beeindruckend ist vielmehr, dass der Autor nach und nach die lange Liste fast visionsartiger Details herausgearbeitet hat, die so etwas überhaupt möglich machen.
    • Ich verstehe die Kernaufgabe moderner Betriebssysteme so, dass mehrere Programme gleichzeitig laufen können, ohne sich gegenseitig zu stören.
      Deshalb kann jedes Programm nur einen Teil seines eigenen Speichers lesen, und auch die CPU steht ihm nur begrenzte Zeit zur Verfügung, bevor zum nächsten Programm gewechselt wird.
      Windows begann diese Mechanismen mit Windows NT ernsthaft zu nutzen, und XP gehört zu dieser Linie.
      Bei Windows bis 98 konnten Programme dagegen fast alles tun, und die entsprechenden Schutzmechanismen der Hardware lagen im Grunde brach.
      Das damalige Windows wirkte deshalb eher wie ein Bündel von Funktionsbibliotheken, das eine UI anzeigt und mit Peripherie spricht, als wie ein echtes Betriebssystem.
      Die CPU besitzt spezielle Hardware, um Speicherzugriffe und Rechenzeit zu begrenzen, aber Windows 9x nutzte das nicht vollständig aus.
      Genau dadurch entstand wohl Spielraum dafür, dass ein Linux-Subsystem für Windows 9x selbst Betriebssystem spielen und diese Hardware nutzen konnte, um ein modernes Betriebssystem laufen zu lassen.
    • Wenn man auf die Projektseite schaut, ist das ziemlich gut erklärt.
      Der schwierigste Teil solcher Arbeit ist meiner Ansicht nach, die Microsoft-Treiber-API herauszufinden.
      Die Dokumentation aus der 9x-Zeit war weder detailliert genug noch leicht zugänglich, und angenehm ist der Bereich auch heute nicht gerade.
    • Der Win9x-Kernel war ursprünglich dafür bekannt, nicht besonders viel zu tun.
      Gerade deshalb schien dort genug Raum zu sein, um einige Low-Level-Funktionen von Linux hineinzupflanzen.
  • Ich fand es schön, dass so ein Beitrag am selben Tag auf der Startseite auftauchte.
    Auf der einen Seite hieß es, Show HN habe sich verdreifacht und es gebe immer mehr Apps mit ähnlichem Vibe-Coding-Gefühl, und auf der anderen Seite gräbt sich jemand sechs Jahre lang in Win9x ein, um darin einen modernen Linux-Kernel laufen zu lassen.
    Verglichen mit Threads voller Apps, die aus 20-Minuten-Prompts entstanden sind, machte so ein Post einfach glücklich.
    • Im README steht offenbar Proudly written without AI.
      So eine Formulierung zu lesen, fand ich ziemlich gut.
    • Inzwischen stammt wahrscheinlich sogar der Prompt selbst von einer AI.
      Statt „create me an owl app“ ist es wohl üblich geworden, sich einen umfassenden Prompt zum Bau einer Owl-App schreiben zu lassen und den dann in die nächste AI-Session zu kopieren.
  • Die Formulierung im README, > Proudly written with zero AI, wirkte etwas mehrdeutig auf mich.
    Es gibt nämlich tatsächlich ein Produkt namens Zero AI, daher konnte man das auch so lesen.
    • Inzwischen scheint es klarer zu > Proudly written without AI geändert worden zu sein.
      Das ist deutlich eindeutiger formuliert, und auch das Projekt selbst ist wirklich erstaunlich.
    • Hier ist der Unterschied in der Groß- und Kleinschreibung wichtig.
  • Ich lasse mal den direkten Link ohne sozialen Umweg hier.
    https://codeberg.org/hails/wsl9x
  • Ich frage mich, welche guten Quellen es gibt, die die Architektur von Windows 3.x und 9x gut erklären.
    Ich kenne nur Bruchstücke wie den VM Monitor und dass es diese Art von Unterstützung gab, aber die eigentlichen Erklärungen scheinen überall verstreut zu sein.
    Viele fassen Windows so zusammen, als sei es einfach nur etwas, das auf DOS läuft, aber das ist eindeutig nicht präzise.
    Natürlich ist das nicht dasselbe wie eine virtuelle Maschine im heutigen Sinn, aber darin steckte eine ziemlich interessante technische Struktur, und die meisten Quellen behandeln das nur oberflächlich.
    Mich würde auch interessieren, wie ähnlich dieses Projekt BSD on Windows ist.
    Und Architecture of Windows 9x kenne ich ebenfalls, aber mir fehlte dort Tiefgang.
  • Nach Microsofts Namensschema müsste das hier nicht Windows Subsystem for Linux, sondern eher Linux Subsystem for Windows heißen.
    • Nicht unbedingt.
      Wenn WSL für Linux on Windows steht, könnte man das hier auch als W9xSL im Sinn von Linux auf Windows 9x lesen.
    • Ich fand diesen Namen schon immer nicht intuitiv.
    • Da stimme ich ebenfalls zu.
      Ich kann es gerade nicht belegen, aber ich meine mich zu erinnern, einmal gelesen zu haben, dass das mit Markenrecht zu tun hatte.
      Eigentlich wollte man es wohl Linux Subsystem for Windows nennen, aber die Linux Foundation habe es nicht erlaubt, dass ein nicht autorisiertes Projekt einen Namen benutzt, der mit Linux beginnt.
  • Ich vermute, das war wohl einfacher als https://github.com/haileys/doslinux.
    • Bis zum nächsten Schritt hat es trotzdem sechs Jahre gedauert, würde ich sagen.
  • Der NT-Kernel wurde von NT 3.1 über 2000 und XP bis hin zu Teilen von WSL in Windows 10/11 weitergeführt und war wohl von Anfang an 1993 mit einem POSIX-Subsystem im Blick entworfen.
    Die Grundphilosophie bestand darin, mehrere Personalities zu haben, deren Systemaufrufe jeweils in NT-Kernel-Aufrufe übersetzt werden.
    In diesem Sinn war WSL1 2016 im Grunde derselbe Trick noch einmal für Linux.
    Windows 9x stammte dagegen aus der DOS-Linie, daher brauchte man dort zum Ausführen von Linux wahrscheinlich viel schmutzigere und grundlegend andere Hacks.
    Vermutlich hat es damals auch deshalb niemand gemacht.
    Dass es hier tatsächlich funktioniert, zeigt für mich, wie weit seiner Zeit voraus die NT-Architektur war.
    Als praktischer Anwendungsfall kommen mir Umgebungen in den Sinn, die an Windows 98 gebunden sind, etwa alte medizinische oder industrielle Software.
    Wenn man 2026 allerdings einen 486er in der Hand hat, ist es wahrscheinlich weit sinnvoller, einfach natives Linux zu betreiben, statt Linux in eine 30 Jahre alte DOS-Abspaltung hineinzustecken.
 
plumpmath 6 일 전

Ach, coLinux, haha -_- ein vertrauter Name. Haha, aber aktuell nutze ich selbst mit WSL nichts davon, doch win95+linux klingt schon verlockend.