32bit Linux がブラウザで起動し、そこから本物のインターネットに出るところまで。1993年のFreeDOSからも ping が返り、現代のAlpine Linuxからは wget https:// で実物のファイルが引ける。
試し方 (ダウンロードして2クリック)
rustx86-web-32bit-network.zipを落として展開START.command(macOS/Linux) /START.bat(Windows) をダブルクリック — サーバーが立ってブラウザが開く./fetch-images.shでOSのイメージを取得 (elks/freedos/linuxを個別にも指定可)
index.html の直接ダブルクリックでは動かない (ESモジュールとwasmは file:// で読めない) ため、キャッシュを切る小さなサーバーを同梱してある。
OSのディスクイメージは同梱していない。 ELKS も FreeDOS も Alpine も自由ソフトウェアで再頒布は許されているが、GPLのバイナリ配布にはソースの提供義務が恒久的に付く。教材が他人のOSの再頒布者になる責任は負わず、取得は同梱の fetch-images.sh に任せる方針。イメージが無くてもデバッガと速度計測は試せる。
この時点で動くもの
CPU
- 8086 リアルモード → 80386 プロテクトモード (32bit)。ページング・特権リング・V86モード・TSS
- test386.asm 完全合格 — POST FF完走 + EE出力44926行が386SX実機の期待値と完全一致
- x87 FPU (f64裏打ち)、MMX、SSE / SSE2 — 名乗った命令は全部実装してある。
libcryptoが踏む列も通る - 検証は Unicorn Engine と毎命令の突き合わせ (cosim) + 実カーネルのロックステップ
装置
8259 PIC / 8254 PIT / 16550 UART / 8042 / MC146818 CMOS / MC6845 CRTC / FDC / PCスピーカー / PCIバス (設定空間の列挙) / NE2000 (ISA) / RTL8029AS (PCI)
NE2000 と RTL8029 は同じ DP8390 コアで、皮 (バスの顔) だけが違う — 実物のRTL8029ASがNE2000互換を売りにした廉価チップで、Linuxのドライバもコアを共有しているのと同じ構図。
OS
| OS | 何ができるか |
|---|---|
| ELKS 0.9.1 | ログイン、tetris、urlget で本物のHTMLを引く |
| FreeDOS 1.4 | A:\> 到達、DOSゲーム、PING 1.1.1.1 が返る (NE2000.COM + mTCP) |
| Alpine Linux 6.18 | busyboxシェル、自作ゲーム、DHCP → ping → wget https:// で実物のPNG取得 |
ネットワーク
ゲストのフレームは WebSocket で wsslirp (Go + gVisor netstack のユーザーモードNAT) へ運ぶ。root権限もTAPデバイスも要らないので、ブラウザのタブから素のインターネットに出られる。
TLSが通るまでの壁は6枚あった: MMX未実装 (libcryptoが#UD) → SSE2の語彙の歯抜け → RTCが固定時刻 (証明書の有効期間検証) → ssl_client とCA束の同梱 → CAの置き場所 (/etc/ssl/cert.pem) → ゲストに /tmp が無い。
道具
- gdb風デバッガ (CLI + ブラウザ) — ブレーク・ステップ・「誰がこの番地を書いたか」・実行の足跡
- スナップショット — CPU・装置・メモリ・ディスクを丸ごと保存/復元。起動済みの状態から1秒で復帰
- 層で分けたCI — 土台 (lint/test) → CPU層 (Unicorn照合・test386) → 機械層 (3OS起動回帰・wasm起動) → 機能層 (スナップショット・貼り付け・ネットワーク)。ネットワークの関門は外に出ない作りで、相手のサイトの都合でも権限でも赤くならない
速さ
| 経路 | シェル到達 |
|---|---|
| ネイティブ (bzImageフル起動) | 1160M命令 / 約16秒 |
| ブラウザ (スナップショット復帰) | 約1秒 |
インタプリタのみ (JITは凍結中)。同じカーネルを食わせた v86 は4.4〜5.0秒で、この差が次の目標になっている。
解説
- 開発記 (ブログ連載): https://pocraft.net/category/16bit/
- 設計判断の記録: docs/adr/
- 踏んだ罠の型: docs/explanation/pitfalls.md
🤖 Generated with Claude Code