把现代 Linux 塞进 Windows 9x:一个硬核复古版 WSL 实验
# 导语
WSL9x 是一个带着黑色幽默感的硬核系统项目:它试图在 Windows 95/98/ME 时代的 Windows 9x 内核里,协作式运行一颗现代 Linux 6.19 内核。它显然不是面向生产环境的“实用工具”,而更像一场复古计算、操作系统工程和内核移植能力的展示:让两个时代差异巨大的系统在同一台虚拟机器里并肩运行。
# 核心内容
项目的目标很直接:在不重启的情况下,让 Windows 9x 与 Linux 同时工作,用户可以在经典 Windows 桌面旁边打开 Linux 程序,并利用 Linux 的分页、内存保护、抢占式调度等能力。作者特别说明项目“未使用 AI 编写”,也透露出它更像手工打磨的系统黑客作品。
从架构看,WSL9x 由三部分组成:打过补丁的 Linux 内核、Windows 9x VxD 驱动,以及一个名为 wsl.com 的 16 位 DOS 客户端程序。VxD 驱动负责初始化整个子系统:它为 Linux 内核代码建立初始映射,通过 DOS 中断从磁盘加载 `vmlinux.elf`,并将 Linux 内核固定编译到 `0xd0000000` 的基地址。随后驱动会在 System VM 中创建一个新线程,分配 16 KiB 栈空间进入 Linux,并进入事件循环,处理进入内核、派发 IRQ、返回用户态以及空闲等待等流程。
更有意思的是系统调用和异常的衔接。经典 Linux i386 使用 `int 0x80` 作为系统调用入口,但 Windows 9x 的中断描述表长度不足,无法像传统方式那样安装对应处理器。WSL9x 的做法是借助通用保护错误(GPF)处理器:当捕获到故障指令是 `int 0x80` 时,处理器会像中断成功执行一样推进指令指针,然后把它转发给 Linux 作为系统调用处理。
Linux 侧则基于 User-mode Linux,但被大幅改造:它不再调用 POSIX API,而是调用 Windows 9x 内核 API;运行位置也从用户态 ring 3 变成了内核态 ring 0。大量上下文切换、内存管理和 Win9x 集成逻辑位于 Linux 内核的 `arch/um/os-Win95` 目录中。
最后的 `wsl.com` 是一个小型 16 位 DOS 程序,它的作用不是实现完整终端,而是把 MS-DOS 提示符窗口复用为 Linux 的 TTY。它会向 VxD 申请一个空闲控制台,并在事件循环中等待 IRQ、读取键盘输入;Linux 输出准备好后,则通过 `int 0x29` 在 DOS VM 上下文中输出字符。如果加载了 NNANSI 这类 DOS ANSI 驱动,还能获得 ANSI 转义序列支持。
# 深度解读
WSL9x 的价值不在于“让老 Windows 真的变成现代开发平台”,而在于展示操作系统边界并没有想象中那么硬。微软官方 WSL 的核心意义,是让 Windows 以现代虚拟化、系统调用翻译或轻量虚拟机方式拥抱 Linux;而 WSL9x 则像一个反向考古实验:在没有现代硬件虚拟化、没有 NT 内核安全模型、也没有成熟容器抽象的 Windows 9x 上,硬是找到一条把现代 Linux 嵌进去的路径。
技术上,它把多个年代的机制拼接在一起:DOS 中断、VxD、Windows 9x System VM、User-mode Linux、i386 系统调用、GPF 异常处理、现代 Linux 内核。这种组合既荒诞又优雅,因为每一处“不得不绕路”的设计,恰好揭示了旧系统的真实约束。例如用 GPF 捕获 `int 0x80`,表面是 hack,背后却是对 CPU 异常模型、Win9x 内核接口和 Linux ABI 的精确理解。
它也提醒我们,复古计算并不只是怀旧 UI 或老游戏模拟。真正高级的复古项目,往往是在旧平台的严苛限制中重建现代能力:这既能帮助后来者理解操作系统的底层结构,也能保存那些正在消失的工程知识。
# 启示与展望
对普通读者来说,WSL9x 可能不会成为日常工具,但它很适合被看作一篇“可运行的系统论文”。它说明优秀的工程探索不一定要服务商业 KPI,也可以是纯粹出于好奇心:如果现代 Linux 能跑在 Windows 9x 里,我们对内核、兼容层和系统边界的理解就会被迫更具体。
未来,这类项目可能继续推动复古系统与现代工具链结合:一方面让旧平台获得新的生命,另一方面也给操作系统教学、模拟器开发、兼容层研究提供更生动的案例。它的意义不在“实用”,而在“证明可能”。