2025 年 1 月 2 日发表,主要讲述在尝试修复比自己年龄还大的视频驱动程序时,对 VGA 硬件了解过多并生成了一些很酷的 glitch 艺术。
- 拥有的设备及现状:是一位复古技术爱好者,拥有 2008 年的 Asus Eee PC 1000H 上网本,如今已基本无用(因不支持 x86_64 而无法运行最新的 Linux 发行版),通过安装各种稀奇古怪的操作系统来保持其“活力”。
- Windows 3.11 下的视频输出问题:Windows 3.x 默认使用 VGA 640x480 16 色视频输出,在 Eee PC 的 1024x600 屏幕上显示效果极差且纵横比不对。3.11 安装程序虽包含一些早已过时的视频适配器驱动,但不支持 Eee PC 中的 Intel GMA 950。包含的“Super VGA”驱动名义上支持 1024x768 256 色,但不起作用。
- IBM PC 视频的恐怖之处:如今提到“VGA”通常想到蓝色模拟连接器或 640x480 分辨率,而 VGA 是 20 世纪 80 年代 IBM 设计的特定视频控制器,“Super VGA”只是比普通 VGA 更先进的统称,并非标准,各软件需为不同的 SVGA 卡实现支持,导致 Windows 驱动的混乱,其支持的供应商列表中不包括 Eee PC 的 Intel 视频适配器。
- 应该制定标准:后来有了 VESA BIOS Extensions(VBE)标准,但对 Windows 3.x 已太晚。BearWindows 发布的 VBE9x 和 VBEMP 可让 Windows 9x 和 NT 使用 VBE,效果不错,但没有 3.x 版本。japheth.de 的 SVGAPatch 可将 Microsoft 的 256 色 Super VGA 驱动修补为使用 VBE,效果很好,但与早期 Windows 的 DOS 软件兼容性存在问题,进入全屏模式再返回 Windows GUI 会导致屏幕损坏,打开任何 DOS 提示符(即使是窗口模式)也会出现问题。
- Windows 3.x 的地狱景象:了解 Windows 3.x 在“增强模式”下作为 MS-DOS 之上的操作系统的工作原理,有三个操作系统同时运行,其中 32 位虚拟机管理器创建虚拟机器运行 Standard mode Windows,允许 Windows 3.x 运行 DOS 应用程序而不占用整个机器。
- 显示驱动的地狱景象:在 Windows Setup 中选择视频适配器会安装多个文件并修改 SYSTEM.INI,不同的 256 色 SVGA 条目实际上是相同的底层驱动,只是 INI 条目不同。显示驱动包含 Grabber、Display Driver 和 Virtual Display Device(VDD)三个组件,Grabber 负责渲染窗口化的 DOS 应用,Display Driver 负责设置硬件和渲染 GUI,VDD 作为虚拟机管理器的一部分,模拟视频硬件。SVGAPatch 工具只修改显示驱动,未修改 VDD,可能是导致问题的原因之一。
- 收集信息:通过“OS/2 Museum”的博客和 Windows 3.1 DDK 了解相关系统信息,DDK 中的显示驱动、VDD 和 Grabber 源文件对研究有帮助,但缺少 256 色 SVGA 显示驱动及其相关的 VDD。
逆向显示驱动:
- 加载代码:Disassembling 16 位 x86 代码较难,IDA 可加载二进制文件但免费版受限,Ghidra 可加载.drv 显示驱动但 VxD 不行,需使用特定工具加载。
- 匹配事物:从.svga256.drv 文件的导出函数开始比较,发现其与 VGA 驱动的一些函数相似,但也有差异,如
GETCHARWIDTH
函数在 VGA 驱动中有调整粗体字体宽度的功能,而在.svga256.drv 中没有。 - 初始化视频适配器:选择“Super VGA (800x600, 256 colours, small fonts)”后,Windows Setup 会在 SYSTEM.INI 中添加相关条目,SVGA256 驱动的
driver_initialization
函数简单,主要是从 INI 文件中读取分辨率和 DPI 等信息。physical_enable
函数负责设置 VGA 适配器,扫描支持的模式,找到可用模式后进行初始化和设置。
- SVGAPatch 的秘密 sauce:SVGAPatch 会修改显示驱动的一些代码,如设置特殊功能 ID、重写
SetAndValidateMode
函数等,以使用 VBE 标准支持任何 VBE 兼容的视频适配器,但与 DOS 提示符的兼容性存在问题。 - 理解虚拟显示设备(VDD):DOS 程序期望独占访问硬件,Windows 通过虚拟显示设备让它们与虚拟实现交互。VDD 有复杂的架构,包含多个文件和函数,用于管理虚拟机和视频硬件状态,不同的 VGA 适配器在 VDD 中有特定的标志和行为,这使得对 VDD 的状态跟踪和修改变得困难。
- DspDrvr_Addresses 的问题:VDD 提供的一些 API 用于与抓取器交互,
DspDrvr_Addresses
函数用于告诉 VDD 如何与显示驱动交互,其代码在 VGA 和 SVGA 版本中有所不同,SVGA 版本中还有特殊的行为,而 SVGA256 驱动在调用该函数时会传递特定的值。 - 后续行动:分析驱动和 VDD 未找到明显可修补的问题,打算进行调试,在 DOSBox 中重现问题,发现 VGA 状态在全屏和窗口模式切换时会发生变化,怀疑是 VDD 的特殊行为导致,通过查看内存和 VGA 寄存器,发现显示驱动在设置扫描线长度时与 DOSBox 的视频模式判断不一致,导致状态混乱,SVGAPatch 也存在问题,未处理视频模式设置的部分,导致显示异常。
- 修复补丁:分析 Windows 3.1 告诉驱动屏幕切换的代码,发现 SVGAPatch 遗漏了一处视频模式设置的地方,通过修改显示驱动代码解决了进入全屏 DOS 会话后 GUI 不被破坏的问题,但仍存在从窗口模式切换到全屏模式时出现问题。进一步调试发现银行配置问题,尝试在
dev_to_background
中添加重置银行的代码但未成功,因为 DOSBox 实现 VBE 操作的方式与预期不同。 - 后续尝试及结果:尝试在不同的模拟器中使用各种显卡,发现即使是原始的 SVGA 256 色驱动支持也存在问题,新的显卡在 Eee PC 上的表现也各不相同,有的卡顿,有的导致屏幕损坏等。最终作者的更新驱动虽然不是完美的,但比原始的 SVGAPatch 有了很大改进,作者将继续关注 PluMGMK/vbesvga.drv 。
总结来说,这是一篇关于在老旧设备上尝试修复视频驱动以获得更好视频输出的技术探索文章,涉及到 VGA、SVGA、VBE 等技术概念以及相关驱动程序的逆向工程和调试,过程充满挑战和趣味。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。