Linux向け Windows 9x サブシステム
(social.hails.org)- Windows 9x カーネル内部で 最新の Linux カーネル(6.19) を協調動作させ、両OSの全機能を同時に活用できるようにする実験的プロジェクト
- WSL と異なりハードウェア仮想化を使わないため、486 でも実行可能
- ページング、メモリ保護、プリエンプティブスケジューリング などの現代的な OS 機能を Windows 9x 環境で利用でき、再起動なしでアプリケーションを並行して実行可能
- パッチ適用済み Linux カーネル、VxD ドライバ、wsl.com クライアント の3つの構成要素から成り、User-Mode Linux を Win9x カーネル API 呼び出し向けに改造
- システムコールは Win9x の短い割り込みディスクリプタテーブルの制約により
int 0x80の代わりに 一般保護例外(GPF)ハンドラ 経由でディスパッチ - "AI なしで誇りを持って書かれた(Proudly written without AI)"、GPL-3 ライセンス
WSL9x - codeberg.org/hails/wsl9x
概要
- WSL9x は Windows 9x カーネル内部で最新の Linux カーネル(執筆時点では 6.19)を協調的に動作させる Windows 9x 向け Linux サブシステム
- ページング、メモリ保護、プリエンプティブスケジューリングなど、両方の OS の全機能を同時に活用可能
- 再起動なしで 両 OS のアプリケーションを並行して実行可能
- AI を使わずに直接書かれている
技術的構造
- WSL9x は3つの構成要素から成る
- パッチ適用済み Linux カーネル (
win9x-um-6.19ブランチ) - VxD ドライバ
- wsl.com クライアントプログラム
- パッチ適用済み Linux カーネル (
VxD ドライバ
- WSL9x の初期化を担当し、エントリポイントは
vxd/wsl9x.asm - カーネルコードの初期マッピングを設定し、DOS 割り込みを通じて
vmlinux.elfをディスクからロード (vxd/loader.c,vxd/fs.asm) - カーネルは固定ベースアドレス
0xd0000000でコンパイル - System VM 内に新しいスレッドを開始し、Linux へのエントリ用に 16 KiB スタックを割り当て
- その後、カーネルへのエントリ、IRQ ディスパッチ、ユーザースペースへの復帰、アイドル状態を処理するイベントループに入る (
vxd/entry.c)
システムコールとページフォルト処理
- ドライバはカーネルへディスパッチされるべきユーザースペースイベントである ページフォルトとシステムコール を処理
- システムコールは 一般保護例外(GPF)ハンドラ を通じて処理される
- Win9x は Linux i386 システムコール割り込みである
int 0x80に対して適切なハンドラを設置できるほど 割り込みディスクリプタテーブルが長くない - GPF ハンドラがフォルトを起こした命令を調べ、
int 0x80であれば割り込みが成功したかのように命令ポインタを進めて Linux システムコールへディスパッチ (vxd/fault.c)
- Win9x は Linux i386 システムコール割り込みである
Linux カーネルの改造
- User-mode Linux ベースだが、POSIX API の代わりに Windows 9x カーネル API を呼び出すよう変更
- ユーザーモード(ring 3)ではなく ring 0 (スーパーバイザ/カーネルモード) で実行
- コンテキストスイッチを含む Win9x カーネル統合のかなりの部分が Linux カーネル側に存在
- 主なコード位置:
linux/arch/um/os-Win95 - エントリポイント:
main.cの_start、主要ファイルはprocess.c,mmu.c
- 主なコード位置:
wsl.com クライアント
- 16ビット DOS プログラムとして
wsl/wsl.asmに実装 - 別個の TTY 実装なしに MS-DOS プロンプトを TTY ウィンドウとして利用可能にする
- 実行時に WSL9x V86 API (
vxd/v86_api.asm) を呼び出して未使用のコンソールを割り当ててもらい、そのコンソールの出力が自身にディスパッチされるよう通知 - その後 IRQ を待ち、割り込み発生時にキーボード読み取りを試みるイベントループに入る
- コンソールドライバ(
vxd/console.c)の 同期ポイント の役割も果たす- Linux 出力の準備ができるとイベントをスケジュールし、MS-DOS VM コンテキストで
int 0x29を実行して DOS ウィンドウに文字を出力 - この割り込みは NNANSI のような DOS 向け ANSI ドライバが ANSI エスケープコード実装のために端末出力をフックする箇所でもある
- Linux 出力の準備ができるとイベントをスケジュールし、MS-DOS VM コンテキストで
ビルドおよび実行要件
i386-linux-muslターゲットの クロスツールチェーン が必要 (musl-cross-make の使用を推奨)- Windows コンポーネントのビルド用に Open Watcom v2 ツールチェーン が必要
win9x-um-6.19ブランチで パッチ適用済み Linux カーネル をビルドする必要ありWATCOMとLINUX環境変数を適切に設定 (例は.envrc.exampleを参照)- Windows 9x が事前インストールされた ハードディスクイメージ
hdd.base.imgが必要 make実行時に WSL9x が用意されたhdd.imgを生成- MS-DOS プロンプトで
wslを実行して pty を開き、ANSI カラーを使う場合はnnansi.comのようなドライバを事前ロードすることを推奨
ライセンス
- GPL-3
2件のコメント
Hacker Newsのコメント
http://www.colinux.org/
https://github.com/wishstudio/flinux
flinuxは実質的に WSL1の構造 に近く、CoLinuxはLinuxカーネルを横に載せるという点でWSL2寄りの感じだった
技術的にはCygwinのほうがより本道だった気がする。外部のLinux配管を無理やり差し込むより、Windows上でネイティブのPOSIXバイナリを動かすアプローチで、軽いDLLリンクだけで済み、ring 0に触れない点も好ましかった
ただ当時はCLIパッケージマネージャの利便性が足りず、実際にWindowsで作業するときはCoLinuxにかなりハマっていた
自分の記憶では核心的な問題は DLL hell だった。たとえばWindows向けのOpenSSHポートが独自の
cygwin1.dllを持ち込むと、しょっちゅうバージョン衝突が起きたそれでもRAMが少なく、スワップが重かった時代には、オーバーヘッドが少ないという点に意味があった
当時はWeb 2.0やNodeJSのようなものよりネイティブアプリが中心で、Javaの評判も良くなかった
結局いつものように、二歩前進して一歩後退する流れのように感じられた
遅くないという含みとは裏腹に実際には遅く、他の方式より互換性も低く、再コンパイルも必要で、その長い寿命の大半において広く愛されたツールではなかったと思う
cygwin1.dllの中ではとてつもない 互換性の魔術 が行われていて、結局は外部のLinux配管をプロセス内に引き込んだようなものだと思う。特にシステム支援なしにfork()を実装する方法を考えると、なおさらそうだCygwinはWindows AppContainerの隔離内ではまったく動かない。MSYS2も今に至るまでこの基盤を使っているため、MSYS2バイナリはAppContainerで動かせない
そのためClaude Codeのサンドボックス化では、完全に別の道を取る必要があった。Claude CodeはGit for Windowsを必要とし、Git for WindowsはMSYS2でビルドされた
bash.exeなどを配布しているからだ一方で真のネイティブWindowsビルドには、
cygwin1.dllが要求するようなあの手の特殊なハックがないので、自分が見つけたnon-MSYS2ビルドはAppContainerでも問題なく動いたArch Linuxの
pacmanを使えるので、Linux VMなしでもWindowsでネイティブPOSIXバイナリをかなり 扱いやすく 扱えるようになった使いたいCライブラリにあらかじめビルド済みの Cygwin版 がなければ、依存ツリー全体を
configure、makeで自分で回さなければならなかったしかも自分の記憶では、おおよそ3分の2の確率で何かを自分で修正する必要があった。POSIXが完全には一致していなかったからだ
ただし正しいセマンティクスを満たすためにあらゆる回避策やハックが必要で、たとえば
forkはcopy-on-writeではなかった自分は1999年ごろから2022年までCygwinを使っていて、WSL2も少し使ってみて、今でもノートPCではそれを使っている
ただしデスクトップは昨年から完全にLinuxへ移行した
昔XP時代にWindowsを使っていたころColinuxを動かしていたが、本当に驚くようなツールだった
Linux側にLAMPスタックを載せるほうがずっと簡単で、編集はWindowsエディタでしながら、ローカル開発環境をかなりいい感じに整えられた
Windows向けX11サーバをつないで、Linuxデスクトップを上に表示する実験もできた
そうやってますますUnixっぽい環境をWindows上に積み重ねていく自分を見て、結局macOSへ乗り換えた
純粋なハックとしての価値は別として、実用面を考えると、486級のマシンではすぐ メモリの限界 にぶつかりそうだという気もする
http://colinux.org/
ただ、それを理解した人があまり多くなかっただけだと感じる
自分の目にはほとんど不可能に見える作業だった
ただ、その構造を理解する人たちの目にはどう映るのか気になった
それで、数学者二人がある定理を些細だと言い、二時間説明したあとでようやく本当に些細だと認める、あのジョークを思い出した
すると教授もそうだねと言って、そのまま次へ進んだ記憶がある
むしろ、これを可能にする長い 仕様書級のディテール一覧 を作者が一つひとつ解き明かしていった点に大きく感嘆する
そのため各プログラムは自分のメモリの一部しか読めず、CPUも限られた時間だけ使って次のプログラムに渡すことになる
Windowsはこうした機能をWindows NTから本格的に使っていて、XPもその系統だ
一方でWindows 98までは、プログラムがほとんど何でもできてしまい、ハードウェアのそうした保護機能は実質的に遊んでいた
当時のWindowsは、オペレーティングシステムというより、UIを出して周辺機器と対話する 機能ライブラリの束 に近かったように思う
CPUにはメモリアクセスと処理時間を制限する特殊なハードウェアがあるが、Windows 9xはそれを十分に活用していなかった
だからWindows 9x向けLinuxサブシステムが自らOSのふりをして、そのハードウェアを使って現代的なオペレーティングシステムを動かせる余地が生まれたのだと思う
自分の見るところ、この種の作業で最も難しい部分は MicrosoftドライバAPI を解明することだ
9x時代の文書は十分に詳細でもなく、アクセスもしやすくなく、今でもあまり気持ちのいい領域ではないと思う
だからむしろLinuxの低レベル機能の一部を移植して差し込む余地がかなりあるように見えた
一方ではShow HNが3倍に増え、似たようなバイブコーディング風のアプリが多くなったという話があり、もう一方では誰かが 6年間 かけてWin9xの内部を掘り下げ、そこで現代のLinuxカーネルを動かしていた
20分のプロンプトで作られたアプリだらけのスレッドと比べると、こういう投稿は本当に幸せな気分になる
こういう文言を目にできてかなり良かった
create me an owl appの代わりに、owl appを作るための 総合プロンプト を作ってくれと頼み、それを次のAIセッションに貼り付ける形が一般化してきたと思うというのも、Zero AIという実在の製品名があるので、そう読めてしまう可能性があったからだ
表現もずっとはっきりしたし、プロジェクト自体も本当に驚異的だと思う
https://codeberg.org/hails/wsl9x
Mastodonは記事を一つ読むだけでも相変わらず JavaScriptの実行 を要求するので、たいていそのまま無視してしまう
https://github.com/mastodon/mastodon/issues/23153
https://github.com/mastodon/mastodon/issues/19953
VM Monitorがあることや、この種の支援があることくらいは断片的に知っているが、詳しい説明はあちこちに散らばっていると感じる
多くの人はWindowsを単にDOS上で動くもののように要約するが、それは明らかに正確ではないと思う
もちろん今日的な意味での仮想マシンとは違うが、その中にはかなり興味深い技術的構造があり、大半の資料はその部分を浅くしか扱っていない気がする
また、このプロジェクトが BSD on Windows とどの程度似ているのかも気になる
そして Architecture of Windows 9x も知っているが、自分の好みとしては 深さが足りない と感じた
https://winworldpc.com/product/windows-sdk-ddk/windows-95-ddk
文書がとても詳しく、サンプルコードも多いので、実際に掘り下げるのに向いていた
WSLがLinux on Windowsを意味するなら、これも Windows 9x上のLinux という意味でW9xSLと読めるように思えた
今すぐ根拠は出せないが、以前読んだ話では、これは 商標の問題 に関係していた記憶がある
本当はLinux Subsystem for Windowsと呼びたかったが、Linux foundation側が未認可プロジェクトにLinuxで始まる名称を使うことを認めなかった、というような話だった
中核の哲学は複数のpersonalityを持ち、それぞれの環境のシステムコールをNTカーネルの呼び出しへ変換する構造だった
だからWSL1も、2016年に事実上同じ手品をLinux向けに再実装したようなものだと思う
一方でWindows 9xはDOS系なので、その中でLinuxを動かすには、はるかに泥臭く本質的に異なるハックが必要だったはずだ
おそらく当時誰もやらなかったのもそのためだろうと推測する
だから、これが実際に動くという事実そのものが、NTアーキテクチャがいかに 時代を先取りしていたか を示しているように感じる
実用的な用途としては、Windows 98に縛られた古い医療用・産業用ソフトウェアの環境が思い浮かぶ
ただ、2026年に486を手元に持っているなら、30年前のDOS派生OSの中にLinuxを押し込むより、単にネイティブLinuxを動かすほうがずっと有用である可能性が高いと思う
Windows 9xがDOSを実行できたというだけでも、すでに かなりの魔法 が入っていた
関連して読む価値のある記事も挙げておく
ああ、coLinux(笑)
-_-懐かしい名前。まあ今はWSLがあっても使わないけど、Windows 95+Linux これはちょっと惹かれる。