Windows模拟器-Wine


Wine提供了一个在Unix/Linux上用来运行Windows程序的平台,是一款开源的兼容层。Wine系Wine Is Not an Emulator的缩写,即Wine不仅仅是一个模拟器)是一个在X-Windows和Unix上执行的Windows APIs(应用程序接口),也可以认为Wine是一个Windows兼容层,其能够在多种兼容 POSIX 接口的操作系统(诸如 Linux、MacOS 与 BSD 等)上运行 Windows 应用的兼容层。它不是像虚拟机或者模拟器一样模仿内部的 Windows 逻辑,而是将 Windows API 调用翻译成为动态的 POSIX 调用,使得在运行 Linux、BSD 或其他一些操作系统的计算机上运行一些 Windows 应用程序成为可能。它也是 Valve 用来让 Steam Deck 用户在 Linux 驱动的手持设备上玩 Windows 游戏的 Proton 软件的基础。其采用C/C++开发并在LGPL协议下授权。

Wine 项目由 Bob Amstadt 于 1993 年发起,旨在寻求一种在 Linux 上运行 Windows 3.1 程序的办法。不久之后,Alexandre Julliard 开始接手领导 Wine 的开发,从此由他管理这个项目。随着 Windows API 和应用为了适应新硬件及软件而不断演变,其也一直不断发展来支持新的特性,移植到更多其他系统,并且更加稳定,提供着更好的用户体验。
通过确立一个宏伟的目标,在2008年项目到达 v1.0 之前,Wine 一直稳健地持续了 15 年之久,那是第一个稳定版。多个版本以后,虽然还有许多工作要做,但今天 Wine 仍然在活跃地开发着。 并且有大约数以百万人计的人们使用 Wine 在他们所选择的系统上运行 Windows 软件。
开放源代码和用户驱动的
Wine 将会永远是自由软件。大约一半的 Wine 代码由志愿者编写,其余部分由商业公司赞助。
可跨指令架构运行程序的Wine-Wine-CE首个正式版发布
Wine-CE 首个正式版 v8.0 于2023年1月发布,该版本基于 Wine 8.0 和 Qemu 7.2.0,可在 ARM 平台上运行 x86 Win32 程序。在此版本之前,已发布 2 个预览版。并已经在树莓派 4 平台上成功进行了测试。和其它在 ARM 平台上运行 x86 应用程序的方案相比,该方案将指令翻译层,即修改过的 Qemu,嫁接于 Wine 的 Windows Dll 层和 Unix 库层之间,从而遵循了非必要不模拟的原则,即只对 x86 架构的 Windows Dll 和所模拟的应用程序进行翻译,并且和原生的 Wine 共用一套 Unix 库。从而可以直接使用宿主架构 ARM 的库和驱动,避免了图形 API 等底层库和驱动的模拟工作。相比其它方案,该项目可直接使用宿主的文件系统,无需 rootfs 和 chroot 操作,从而无需 root 权限也可正常使用。
该项目基于 Wine 和 Qemu 项目的最新稳定版分支,并充分利用 Wine 和 Qemu 的最新特性。在此项目的开发过程中,修复了 Qemu x86 用户模式下的全局描述表(GDT)bug,该 bug 会导致多线程运行时所模拟的段寄存器值被意外修改。由于此 bug 的修复,Wine-CE 可以直接将 Qemu 的无软页表用户模式作为指令翻译层,从而让模拟层和本基层使用共同的内存地址空间,进而保证两者间通过协程方式进行双向快速交互。另外,此项目使用了 DXVK 作为 Direct3D 的实现。和其它项目相比,此项目将 DXVK 进行了修改,使之可以在树莓派上运行。因此,针对 Direct3D 程序的执行,会将 Direct3D 调用翻译为 Vulkan 调用,交由宿主端本机执行,从而大幅提升图形渲染性能,为 3D 游戏的运行打好基础。
Wine-CE 项目在仓库中不但提供了完整的源码和构建过程描述,还提供了二进制包,可以快速部署到机器上进行执行。
1、可移植的CPU指令
在Linux与Windows生成的代码都是基于x86 CPU的,即CPU指令集(mov、imul、ret之类指令)是完全相同的。
Linux上可执行文件是ELF格式,下图的.text 区域就是CPU的指令

Window上的可执行文件是PE格式,CPU指令也在.text区域

既然.text区域的CPU指令在Windows和Linux之间是“可移植的”,如果一个程序可以把foo函数在Windows编译出的.text 给“取”出来,拿到Linux上执行,应该是可以运行的。Wine其实就是这么干的,它把Windows可执行文件加载到内存中,分析一下,找到可执行代码的位置,跳转到这个地方执行就可以了!
2、系统调用
如果事情就这么简单,任何人都可以写一个Wine,Windows上的海量软件就可以轻松移植到Linux上,其生态的优势将受到挑战。但Windows的桌面霸主地位稳固,这其中的关键就是:系统调用。
操作系统是对硬件功能的封装,它对外提供了一系列服务如读写硬盘、读写内存、进程管理等。应用程序想使用这些服务,必须通过系统调用来进行,别无它法。而Windows和Linux的系统调用,是完全不同的。名称不同、参数不同、语义也不同。

应用程序肯定要使用系统调用(无论是直接还是间接方式),那就立刻和操作系统绑定了。在Linux上用C语言的输出调用的是puts函数;在Windows上编译后调用的是printf函数。puts和printf都C标准库的函数,C标准库最终还是走到系统调用那里,毕竟要在控制台输出这个只能操作系统来处理。要在Linux上运行Windows程序大致有两种方式:
(1)把Windows系统调用在Linux上重新实现一遍,这和重写OS差不多了;
(2)把Windows系统调用拦截,转发到Linux的系统调用。
Wine开发团队选择了第二条道路,当应用程序调用Windows 系统调用时,Wine进行“拦截”,然后转发到Linux的系统调用。但实现起来会比较麻烦。

Windows的系统调用非常多,源码又不公开,全是黑盒子,外界不知道Windows内部到底是如何实现的,开发文档又很模糊......;且这些系统调用还存在一些错误、缺陷、奇怪的副作用,Wine在拦截转发的时候,这些错误和缺陷不但不能修复,还必须原封不动地去复现它们。如果不这么干,那些Windows软件在Linux上运行起来的行为就不同了。另外Windows游戏基本都在调用微软的DirectX,这是微软专门为游戏开发提供的API,仅支持Windows。
在Linux平台下也有个对应的东西,原来叫OpenGL,现在新一代的图形API叫做Vulkan。很明显,DirectX和Vulkan是不同的东西。为了把DirectX调用转换成Vulkan,Valve(Steam就是他们家的)和CodeWeavers(主要赞助Wine)于20218年8月合作开发了Proton,当时Valve还发布了一个 27 款游戏的名单,这些游戏经过测试和认证,性能与 Windows 原生版本相同,无需最终用户进行调整。其中包括《毁灭战士》(2016 年)、《雷神之锤》和《最终幻想 VI》等。
微软通过Windows系统调用API和DirectX等API,构建了非常宽的护城河;开源的Wine在这个护城河上建立一座桥,这座桥虽然还不完美,但广大的技术人员正在让它更加好用。
Wine版本更新录(202x)
官方主页:http://www.winehq.org/

Wine 项目由 Bob Amstadt 于 1993 年发起,旨在寻求一种在 Linux 上运行 Windows 3.1 程序的办法。不久之后,Alexandre Julliard 开始接手领导 Wine 的开发,从此由他管理这个项目。随着 Windows API 和应用为了适应新硬件及软件而不断演变,其也一直不断发展来支持新的特性,移植到更多其他系统,并且更加稳定,提供着更好的用户体验。
通过确立一个宏伟的目标,在2008年项目到达 v1.0 之前,Wine 一直稳健地持续了 15 年之久,那是第一个稳定版。多个版本以后,虽然还有许多工作要做,但今天 Wine 仍然在活跃地开发着。 并且有大约数以百万人计的人们使用 Wine 在他们所选择的系统上运行 Windows 软件。
开放源代码和用户驱动的
Wine 将会永远是自由软件。大约一半的 Wine 代码由志愿者编写,其余部分由商业公司赞助。
可跨指令架构运行程序的Wine-Wine-CE首个正式版发布
Wine-CE 首个正式版 v8.0 于2023年1月发布,该版本基于 Wine 8.0 和 Qemu 7.2.0,可在 ARM 平台上运行 x86 Win32 程序。在此版本之前,已发布 2 个预览版。并已经在树莓派 4 平台上成功进行了测试。和其它在 ARM 平台上运行 x86 应用程序的方案相比,该方案将指令翻译层,即修改过的 Qemu,嫁接于 Wine 的 Windows Dll 层和 Unix 库层之间,从而遵循了非必要不模拟的原则,即只对 x86 架构的 Windows Dll 和所模拟的应用程序进行翻译,并且和原生的 Wine 共用一套 Unix 库。从而可以直接使用宿主架构 ARM 的库和驱动,避免了图形 API 等底层库和驱动的模拟工作。相比其它方案,该项目可直接使用宿主的文件系统,无需 rootfs 和 chroot 操作,从而无需 root 权限也可正常使用。
该项目基于 Wine 和 Qemu 项目的最新稳定版分支,并充分利用 Wine 和 Qemu 的最新特性。在此项目的开发过程中,修复了 Qemu x86 用户模式下的全局描述表(GDT)bug,该 bug 会导致多线程运行时所模拟的段寄存器值被意外修改。由于此 bug 的修复,Wine-CE 可以直接将 Qemu 的无软页表用户模式作为指令翻译层,从而让模拟层和本基层使用共同的内存地址空间,进而保证两者间通过协程方式进行双向快速交互。另外,此项目使用了 DXVK 作为 Direct3D 的实现。和其它项目相比,此项目将 DXVK 进行了修改,使之可以在树莓派上运行。因此,针对 Direct3D 程序的执行,会将 Direct3D 调用翻译为 Vulkan 调用,交由宿主端本机执行,从而大幅提升图形渲染性能,为 3D 游戏的运行打好基础。
Wine-CE 项目在仓库中不但提供了完整的源码和构建过程描述,还提供了二进制包,可以快速部署到机器上进行执行。
1、可移植的CPU指令
在Linux与Windows生成的代码都是基于x86 CPU的,即CPU指令集(mov、imul、ret之类指令)是完全相同的。
Linux上可执行文件是ELF格式,下图的.text 区域就是CPU的指令

Window上的可执行文件是PE格式,CPU指令也在.text区域

既然.text区域的CPU指令在Windows和Linux之间是“可移植的”,如果一个程序可以把foo函数在Windows编译出的.text 给“取”出来,拿到Linux上执行,应该是可以运行的。Wine其实就是这么干的,它把Windows可执行文件加载到内存中,分析一下,找到可执行代码的位置,跳转到这个地方执行就可以了!
2、系统调用
如果事情就这么简单,任何人都可以写一个Wine,Windows上的海量软件就可以轻松移植到Linux上,其生态的优势将受到挑战。但Windows的桌面霸主地位稳固,这其中的关键就是:系统调用。
操作系统是对硬件功能的封装,它对外提供了一系列服务如读写硬盘、读写内存、进程管理等。应用程序想使用这些服务,必须通过系统调用来进行,别无它法。而Windows和Linux的系统调用,是完全不同的。名称不同、参数不同、语义也不同。

应用程序肯定要使用系统调用(无论是直接还是间接方式),那就立刻和操作系统绑定了。在Linux上用C语言的输出调用的是puts函数;在Windows上编译后调用的是printf函数。puts和printf都C标准库的函数,C标准库最终还是走到系统调用那里,毕竟要在控制台输出这个只能操作系统来处理。要在Linux上运行Windows程序大致有两种方式:
(1)把Windows系统调用在Linux上重新实现一遍,这和重写OS差不多了;
(2)把Windows系统调用拦截,转发到Linux的系统调用。
Wine开发团队选择了第二条道路,当应用程序调用Windows 系统调用时,Wine进行“拦截”,然后转发到Linux的系统调用。但实现起来会比较麻烦。

Windows的系统调用非常多,源码又不公开,全是黑盒子,外界不知道Windows内部到底是如何实现的,开发文档又很模糊......;且这些系统调用还存在一些错误、缺陷、奇怪的副作用,Wine在拦截转发的时候,这些错误和缺陷不但不能修复,还必须原封不动地去复现它们。如果不这么干,那些Windows软件在Linux上运行起来的行为就不同了。另外Windows游戏基本都在调用微软的DirectX,这是微软专门为游戏开发提供的API,仅支持Windows。
在Linux平台下也有个对应的东西,原来叫OpenGL,现在新一代的图形API叫做Vulkan。很明显,DirectX和Vulkan是不同的东西。为了把DirectX调用转换成Vulkan,Valve(Steam就是他们家的)和CodeWeavers(主要赞助Wine)于20218年8月合作开发了Proton,当时Valve还发布了一个 27 款游戏的名单,这些游戏经过测试和认证,性能与 Windows 原生版本相同,无需最终用户进行调整。其中包括《毁灭战士》(2016 年)、《雷神之锤》和《最终幻想 VI》等。
微软通过Windows系统调用API和DirectX等API,构建了非常宽的护城河;开源的Wine在这个护城河上建立一座桥,这座桥虽然还不完美,但广大的技术人员正在让它更加好用。
Wine版本更新录(202x)
官方主页:http://www.winehq.org/