新闻详情

新闻详情

首页 / 资讯中心 / 详情

Madeira 跨平台兼容层:Wine、FEX-Emu 与 DXMT 在 ARM 上运行 Windows 应用

发布时间:2026/10/1 8:49:09来源:尧图网络
Madeira 跨平台兼容层:Wine、FEX-Emu 与 DXMT 在 ARM 上运行 Windows 应用
1. 从Madeira这个名字说起一个跨平台兼容层的真实需求第一次看到Madeira这个项目名很多人会以为是某个度假岛屿或者葡萄酒品牌——毕竟马德拉岛确实以加强型葡萄酒出名。但放在当前的技术语境里结合 Wine、FEX-Emu、DXMT、x86-64 这些关键词它指向的其实是一个非常具体的方向在非 x86 架构的平台上把 Windows 应用和游戏跑起来。这不是一个新问题但Madeira这个命名背后代表的思路和传统的 Wine 方案有本质区别。我接触跨平台兼容层差不多有七八年时间从最早的 Wine 编译踩坑到后来 Box86/Box64 的折腾再到 FEX-Emu 出现后重新审视整个技术栈中间踩过的坑足够写一本小册子。Madeira 这个项目吸引我的地方在于它没有试图重新发明轮子而是把几个已经相对成熟的组件——Wine 负责 Win32 API 转换、FEX-Emu 负责 x86-64 到 ARM64 的指令翻译、DXMT 负责 Direct3D 到 Metal 的图形转换——组合成一个完整的运行时环境。这个组合思路本身不新鲜但 Madeira 在集成层面做了不少工程上的取舍值得拆开来看。这篇文章适合谁读如果你是在 ARM 设备比如 Apple Silicon Mac、树莓派、各种国产 ARM 开发板上想跑 Windows 程序的人或者你本身在做兼容层相关的开发再或者你只是好奇为什么 Wine 有时候能跑有时候跑不起来那接下来的内容应该对你有用。我会从架构拆解讲到实操配置再到实际跑起来之后会遇到的各种奇怪问题尽量把每个环节的为什么说清楚。需要提前说明的是Madeira 目前并不是一个像 Wine 那样有十几年积累的成熟项目它的很多设计还在演进中。我下面提到的配置方法和参数是基于当前公开的技术资料和我在类似技术栈上的实操经验整理出来的具体到你的设备上可能需要微调。但核心原理和排查思路是通用的。2. Madeira 的三层架构Wine、FEX-Emu、DXMT 各自在干什么2.1 Wine 层Win32 API 到 POSIX 的翻译官Wine 的核心工作是把 Windows 程序调用的 Win32 API 翻译成宿主系统能理解的 POSIX 调用。比如一个 Windows 程序调用CreateFileW打开文件Wine 会把它转换成 Linux 或 macOS 上的open()系统调用。这个过程不是简单的函数映射因为 Windows 和 POSIX 在文件路径、权限模型、线程调度、注册表机制上都有本质差异。Wine 最容易被误解的一点是它不是模拟器。它不模拟 x86 指令也不模拟 Windows 内核。它是一套 API 兼容层直接在你的系统上以原生速度运行程序的非 Windows 部分。这也是为什么 Wine 跑某些程序比虚拟机快得多——因为大部分代码是原生执行的。但在 Madeira 的场景里Wine 面临一个额外挑战如果宿主是 ARM64 架构那 Windows 程序编译出来的 x86-64 指令没法直接执行。这时候就需要第二层。2.2 FEX-Emu 层x86-64 到 ARM64 的指令翻译FEX-Emu 是一个用户态的 x86-64 指令翻译器专门为 ARM64 宿主设计。它的工作方式是把 x86-64 的机器码动态翻译成 ARM64 指令然后交给 CPU 执行。和 QEMU 的全系统模拟不同FEX-Emu 运行在用户态只翻译应用程序本身的指令系统调用直接透传给宿主内核。FEX-Emu 有几个关键特性值得注意。第一它支持JIT 编译缓存翻译过的代码块会被缓存起来下次执行同样的代码路径时直接复用避免重复翻译的开销。第二它对 x86-64 的 SIMD 指令集SSE、AVX有较好的支持这对游戏和多媒体应用很重要。第三它支持64 位和 32 位两种模式因为很多老游戏是 32 位的。在实际使用中FEX-Emu 的性能损耗通常在 20% 到 50% 之间具体取决于工作负载。计算密集型的代码翻译开销大I/O 密集型的开销小。这个损耗对于办公类应用基本无感但对于帧率敏感的游戏就比较明显了。2.3 DXMT 层Direct3D 到 Metal 的图形桥梁DXMT 是 Madeira 技术栈里最年轻也最关键的组件。它的作用是把 Windows 程序使用的 Direct3D 11/12 调用转换成 Apple Metal API 调用。为什么是 Metal 而不是 Vulkan因为在 Apple Silicon Mac 上Metal 是原生图形 API直接走 Metal 比先转 Vulkan 再转 Metal 少一层开销。DXMT 的工作机制和 DXVK 类似都是把 D3D 的着色器字节码转换成目标 API 的着色器语言。DXMT 把 HLSL 编译成 Metal Shading Language然后通过 Metal 的管线状态对象提交给 GPU。这个过程涉及大量的状态跟踪和资源管理因为 D3D 和 Metal 在资源绑定模型、同步机制、内存管理上差异很大。目前 DXMT 对 D3D11 的支持比较成熟D3D12 的支持还在完善中。如果你要跑的游戏是 D3D9 时代的可能需要走 DXVK 转 Vulkan 再转 Metal 的路径或者用 Wine 自带的 D3D9 实现。2.4 三层如何协同一次 Draw Call 的完整旅程举个具体例子一个 Windows 游戏调用DrawIndexedInstanced绘制一个模型。这个调用首先被 Wine 的 D3D 实现捕获Wine 把它转给 DXMT。DXMT 检查当前的管线状态把 D3D 的着色器转换成 Metal 着色器把顶点缓冲和索引缓冲映射到 Metal 的缓冲区对象然后编码一个 Metal 的 draw call。这个 draw call 最终由 Metal 驱动提交给 Apple GPU 执行。与此同时游戏的逻辑代码比如物理计算、AI是 x86-64 指令由 FEX-Emu 翻译成 ARM64 在 CPU 上执行。Wine 负责处理游戏的文件读写、窗口创建、输入事件等系统交互。三层各司其职通过明确定义的接口通信。这个架构的优雅之处在于每一层都可以独立替换或升级。比如你觉得 FEX-Emu 性能不够可以换成 Box64觉得 DXMT 兼容性不好可以换成 DXVK。Madeira 的价值在于它把这些组件的集成配置做好了省去了你自己拼装的麻烦。3. 在 Apple Silicon 上从零搭建 Madeira 运行环境3.1 前置条件检查你的设备能不能跑在动手之前先确认几个硬性条件。首先是架构Madeira 目前主要面向 ARM64 宿主Apple Silicon MacM1/M2/M3/M4 系列是最常见的平台。其次是系统版本macOS 14 Sonoma 或更高版本比较稳妥因为 Metal 3 的一些特性在旧版本上不可用。最后是磁盘空间Wine prefix 加上 FEX-Emu 的缓存建议预留至少 20GB。如果你用的是 Linux ARM 设备比如树莓派 5 或者各种 RK3588 开发板Madeira 的 Wine 和 FEX-Emu 部分可以工作但 DXMT 依赖 Metal在 Linux 上不可用。这种情况下你需要用 DXVK 转 Vulkan 的方案图形性能会打折扣。注意不要试图在 Intel Mac 上跑 Madeira。Intel Mac 本身就是 x86-64 架构不需要 FEX-Emu 翻译直接用 Wine 就行。强行装 Madeira 只会增加不必要的复杂度。3.2 安装 Wine版本选择和编译选项Madeira 对 Wine 的版本有要求建议使用 Wine 9.0 或更高版本。如果你用 Homebrew可以直接brew install --cask wine-stable但这样装的是预编译版本可能缺少一些 Madeira 需要的补丁。更稳妥的方式是从源码编译加上--enable-archsi386,x86_64参数确保同时支持 32 位和 64 位 Windows 程序。编译 Wine 的时候有几个选项值得注意。--without-coreaudio可以避免在某些 macOS 版本上的音频驱动冲突--with-metal确保 Metal 后端被启用。如果你不需要 Wine 自带的 D3D 实现因为要用 DXMT可以加上--without-d3d减少编译时间但这样 Wine 自带的 D3D 测试程序就跑不了。编译过程大概需要 20 到 40 分钟取决于你的 Mac 性能。编译完成后用wine --version确认版本用winecfg打开配置界面确认能正常启动。3.3 FEX-Emu 的编译与配置RootFS 是关键FEX-Emu 的安装比 Wine 稍微复杂一点因为它需要一个 x86-64 的 RootFS 来提供基本的系统库。这个 RootFS 本质上是一个精简的 x86-64 Linux 文件系统包含 FEX-Emu 运行 x86-64 程序时需要的动态链接库。获取 RootFS 的常见方式是用 FEX-Emu 官方提供的脚本从 Docker 镜像里提取或者手动从 Debian/Ubuntu 的 x86-64 镜像里裁剪。提取完成后需要设置FEX_ROOTFS环境变量指向这个目录。FEX-Emu 的配置文件在~/.fex-emu/Config.json几个关键参数RootFS指向 RootFS 目录的绝对路径ThunkHostLibs设置为true让 FEX-Emu 把宿主系统的库透传给 x86-64 程序X87ReducedPrecision设置为true可以提升浮点运算性能但可能影响精度敏感的程序TSOEnabled设置为true保证内存序一致性对多线程程序很重要但会带来性能损耗编译 FEX-Emu 需要 CMake 3.20 以上和 Clang 编译器。在 Apple Silicon 上用 Homebrew 装的 LLVM 通常没问题。编译命令大概是git clone https://github.com/FEX-Emu/FEX.git cd FEX git submodule update --init --recursive mkdir Build cd Build CCclang CXXclang cmake -DCMAKE_BUILD_TYPERelease -DENABLE_ASSERTIONSOFF .. make -j$(sysctl -n hw.ncpu)编译完成后FEXInterpreter和FEXBash是两个最常用的可执行文件。FEXBash会启动一个 x86-64 的 bash shell你可以在里面直接运行 x86-64 的 Linux 程序来测试 FEX-Emu 是否工作正常。3.4 DXMT 的部署把 D3D 调用接到 Metal 上DXMT 的部署相对简单因为它主要是一组 DLL 文件。你需要把编译好的d3d11.dll、dxgi.dll、winemetal.dll等文件放到 Wine prefix 的drive_c/windows/system32目录下然后在 Wine 的注册表里设置 DLL 覆盖让 Wine 优先加载 DXMT 的版本而不是自带的。DXMT 的配置文件是dxmt.conf放在和 DLL 同级的目录。几个关键配置项d3d11.maxFeatureLevel设置 D3D 特性等级一般设为11_1兼容性最好dxgi.maxFrameLatency控制最大帧延迟设为1可以减少输入延迟但可能影响帧率稳定性d3d11.metalShaderCache设置为true启用 Metal 着色器缓存首次运行会慢一些但后续启动快很多DXMT 目前对 D3D11 的支持覆盖了大部分常用特性包括计算着色器、纹理数组、多重采样等。但一些较新的 D3D11.3/11.4 特性可能还不完整遇到不支持的调用时 DXMT 会记录日志并尝试降级处理。4. 跑起来之后才会遇到的真实问题排查链路实录4.1 程序启动就崩溃先看日志再猜这是最常见的情况。你按照教程配好了所有东西双击 exe窗口闪一下就没了。这时候不要急着重装先看日志。Wine 的日志通过WINEDEBUG环境变量控制。最常用的组合是WINEDEBUGloaddll,d3d,dxgi这会输出 DLL 加载和图形相关的详细信息。如果崩溃发生在 FEX-Emu 层面还需要设置FEX_LOG_LEVELinfo来查看指令翻译的日志。我遇到过一个典型案例某个游戏启动时崩溃日志显示d3d11.dll加载失败。排查后发现是 DXMT 的d3d11.dll依赖一个特定版本的libc而系统里的版本不匹配。解决方法是把 DXMT 编译时用的libc.1.dylib一起复制到 Wine prefix 的system32目录或者用install_name_tool修改 DLL 的依赖路径。另一个常见原因是32 位和 64 位混淆。有些程序是 32 位的但你的 Wine prefix 是 64 位的或者 FEX-Emu 的 RootFS 只有 64 位库。这种情况下需要创建 32 位的 Wine prefixWINEARCHwin32 winecfg并确保 FEX-Emu 的 RootFS 包含 32 位的系统库。4.2 图形渲染异常花屏、黑屏、纹理错乱图形问题比启动崩溃更难排查因为涉及 Wine、DXMT、Metal 三层。我的排查顺序是先确认是 Wine 的问题还是 DXMT 的问题再确认是 DXMT 的问题还是 Metal 的问题。判断方法设置WINEDEBUG-all,d3d只输出 D3D 相关日志。如果日志显示 D3D 调用正常但画面不对问题大概率在 DXMT 或 Metal 层。如果 D3D 调用本身就报错问题在 Wine 的 D3D 实现。DXMT 的日志通过DXMT_LOG_LEVELdebug开启。重点看着色器编译是否有报错资源绑定是否有冲突。我遇到过纹理错乱的情况日志显示某个纹理的格式转换失败——D3D 的DXGI_FORMAT_BC7_UNORM在 Metal 上没有直接对应的格式DXMT 需要做软件解码但解码路径有 bug。这种情况只能等 DXMT 更新或者用d3d11.forceTextureFormat配置强制转换到其他格式。黑屏问题经常和垂直同步有关。Metal 的CAMetalLayer在某些刷新率下会出现画面不更新的情况。可以尝试在 DXMT 配置里关闭垂直同步dxgi.syncInterval0或者在 Wine 注册表里设置HKCU\Software\Wine\Direct3D\VideoMemorySize为一个合理的值比如 4096。4.3 性能不达预期瓶颈在哪一层性能问题需要分层定位。先用Activity Monitor看 CPU 和 GPU 的占用率。如果 CPU 占用高但 GPU 占用低瓶颈在 FEX-Emu 的指令翻译或 Wine 的 API 转换。如果 GPU 占用高但帧率低瓶颈在 DXMT 的图形转换或 Metal 驱动。FEX-Emu 的性能调优有几个方向。启用 JIT 缓存FEX_JIT_CACHE1可以避免重复翻译。调整X87ReducedPrecision和TSOEnabled可以在精度和性能之间取舍。对于多线程程序设置FEX_TSO_ENABLED0可以关闭内存序模拟但可能导致程序行为异常。DXMT 的性能调优主要是着色器缓存和管线状态缓存。确保d3d11.metalShaderCachetrue并且缓存目录有写入权限。另外Metal 的MTLCommandQueue数量也会影响性能DXMT 默认使用 1 个队列对于多线程渲染的程序可以尝试增加到 2 到 3 个。还有一个容易被忽略的点Wine 的音频后端。macOS 上 Wine 默认用 CoreAudio但某些情况下 PulseAudio 的兼容层性能更好。可以通过WINEDLLOVERRIDESwinepulse.drv来切换。4.4 中文乱码字体和编码的双重问题Wine 中文乱码是个老问题但在 Madeira 场景下更复杂因为涉及 FEX-Emu 的 RootFS 里的字体配置。乱码通常有两个原因字体缺失和编码不匹配。字体缺失的解决方法是把 Windows 的中文字体比如simsun.ttc、msyh.ttf复制到 Wine prefix 的drive_c/windows/Fonts目录然后在注册表里设置字体替换。编码问题则需要确认 Wine 的 locale 设置LANGzh_CN.UTF-8和LC_ALLzh_CN.UTF-8都要设置。FEX-Emu 的 RootFS 里如果缺少中文字体x86-64 程序在渲染文字时也会出问题。可以在 RootFS 的/usr/share/fonts目录下添加中文字体或者通过ThunkHostLibs让 FEX-Emu 使用宿主系统的字体。提示Wine 的字体配置在HKCU\Software\Wine\Fonts\Replacements注册表键下。把MS Shell Dlg替换为Microsoft YaHei或SimSun可以解决大部分界面乱码。5. 兼容性调优让更多程序跑起来的实战技巧5.1 DLL 覆盖策略什么时候该用原生什么时候该用内置Wine 的 DLL 加载策略是兼容性的核心。默认情况下Wine 优先使用自己的内置 DLL 实现只有在内置实现不完整或有问题时才回退到 Windows 的原生 DLL。但在 Madeira 场景下DXMT 提供了自己的d3d11.dll和dxgi.dll需要确保这些 DLL 被优先加载。DLL 覆盖通过WINEDLLOVERRIDES环境变量或 Wine 注册表的HKCU\Software\Wine\DllOverrides键设置。格式是dllnamemodemode 可以是native只用原生、builtin只用内置、native,builtin优先原生或builtin,native优先内置。对于 DXMT 相关的 DLL设置为native确保 DXMT 的版本被加载。对于mscoree.NET 运行时通常设置为builtin因为 Wine 的 Mono 实现比安装完整 .NET 更轻量。对于msvcp140等 VC 运行库设置为native,builtin让程序优先使用自带的版本。5.2 注册表调优那些文档里不会写的键值Wine 注册表里有几个对兼容性影响很大的键值但官方文档很少提及。HKCU\Software\Wine\Direct3D下的MaxVersionGL控制 OpenGL 版本设置为0x40005可以强制使用 OpenGL 4.5。VideoMemorySize控制 Wine 报告的显存大小设置得太小会导致某些游戏拒绝启动设置得太大可能导致内存分配失败。HKCU\Software\Wine\Explorer下的Desktop键可以设置一个虚拟桌面把程序窗口限制在一个固定大小的窗口里。这对某些全屏游戏很有用可以避免分辨率切换导致的崩溃。HKCU\Software\Wine\X11 Driver下的GrabFullscreen控制全屏抓取行为设置为Y可以强制全屏程序使用虚拟桌面。5.3 针对特定程序的配置模板不同类型的程序需要不同的配置。办公类程序比如老版本的 Office通常对图形要求不高重点是字体和打印支持。游戏类程序对图形和输入延迟敏感需要重点调优 DXMT 和 FEX-Emu。开发工具类程序比如老版本的 Visual Studio可能需要 .NET 和 MSBuild 的支持。我整理了一个简单的配置对照表程序类型关键配置常见问题办公软件字体替换、打印驱动界面乱码、打印崩溃2D 游戏DXMT 垂直同步关闭画面撕裂、输入延迟3D 游戏DXMT 着色器缓存、FEX JIT 缓存帧率低、纹理错乱开发工具.NET 版本、MSBuild 路径编译失败、调试器无法附加媒体播放器音频后端、硬件解码音画不同步、解码失败5.4 性能监控与瓶颈定位的常用命令在 macOS 上Activity Monitor可以看整体的 CPU/GPU 占用但看不到具体的线程级信息。更精细的监控需要用powermetrics或者 Instruments。powermetrics --samplers cpu_power,gpu_power -i 1000可以每秒输出一次 CPU 和 GPU 的功耗和占用率。对于 FEX-EmuFEXInterpreter有一个--profile参数可以输出指令翻译的统计信息包括翻译了多少个代码块、缓存命中率等。对于 DXMTDXMT_LOG_LEVELdebug会输出每个 Metal 命令缓冲的提交时间和 GPU 执行时间。Wine 本身有一个winedbg调试器可以在程序崩溃时生成调用栈。winedbg --auto会自动附加到崩溃的进程并输出 backtrace。这个 backtrace 对于定位是 Wine 的问题还是程序本身的问题很有帮助。6. 从 Madeira 看跨平台兼容层的未来走向Madeira 这个项目让我重新思考了一个问题跨平台兼容层的终极形态是什么是像 QEMU 那样全系统模拟还是像 Wine 那样 API 翻译还是像 FEX-Emu 那样指令翻译我的判断是未来一定是混合方案——不同层次用不同的技术根据负载动态选择最优路径。Madeira 目前的做法是静态组合Wine 负责 APIFEX-Emu 负责指令DXMT 负责图形。这个组合在大多数场景下工作得不错但存在优化空间。比如如果一段代码是计算密集型的FEX-Emu 的翻译开销就很大如果一段代码是 I/O 密集型的翻译开销就可以忽略。理想情况下运行时应该能识别热点代码对热点代码做更激进的优化比如提前编译对冷代码做更简单的解释执行。另一个趋势是GPU 侧的兼容层。DXMT 把 D3D 转 Metal 是一个方向但未来可能有更激进的方案——直接在 GPU 上执行 x86 的着色器字节码跳过转换步骤。这需要 GPU 硬件层面的支持目前还不现实但值得关注。对于普通用户来说Madeira 这类项目的意义在于它让 ARM 设备跑 Windows 程序这件事从极客玩具变成了可用方案。虽然还有各种小问题但已经能满足一部分实际需求了。我在 M1 Mac 上用 Madeira 跑一些老游戏和工具软件体验比两年前好了太多。最后分享一个我在调试过程中总结的小技巧遇到问题时先把问题隔离到单层。不要同时怀疑 Wine、FEX-Emu 和 DXMT。先用FEXBash跑一个纯 x86-64 的 Linux 程序确认 FEX-Emu 正常。再用wine notepad确认 Wine 正常。最后用 DXMT 自带的测试程序确认图形层正常。逐层排除比盲目猜测效率高得多。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

附录 D.1 tests 单元测试(直连 libvirglrenderer) 2026/10/1 9:45:06

附录 D.1 tests 单元测试(直连 libvirglrenderer)

1. 概述 virglrenderer 的tests/目录包含的不是与 vtest_server 配合使用的客户端测试,而是直接针对 virglrenderer 库 API 的单元测试集合。这些测试通过直接调用 libvirglrenderer 的 API 来验证各种功能,使用 Check 框架进行测试管理。 1.1 测试架构…

阅读更多 →
运维转网安:不是改行而是顺路,经验就是你的最大筹码 2026/10/1 9:45:06

运维转网安:不是改行而是顺路,经验就是你的最大筹码

1. 先搞清楚一件事:运维转网安,不是改行,是顺路干了几年运维的人,心里大概都有这么一股劲儿——白天配交换机、晚上发版本、凌晨三点爬起来处理磁盘告警,第二天还要假装精神抖擞地出现在周会上。别人问起工作&#xff…

阅读更多 →
突破性个人商业模式框架:三步打造你的专属创业系统 2026/10/1 9:45:06

突破性个人商业模式框架:三步打造你的专属创业系统

突破性个人商业模式框架:三步打造你的专属创业系统 在竞争激烈的创业环境中,个人创业者需要一套高效、可落地的商业模式框架来指导实践。《一人企业方法论》第二版提供了适合非技术人群(如自媒体、电商、数字商品从业者)的创业系…

阅读更多 →
从零编写Nessus自定义扫描策略:插件集配置与性能调优实战 2026/10/1 9:45:06

从零编写Nessus自定义扫描策略:插件集配置与性能调优实战

1. 为什么默认策略总是“差点意思”先聊个日常。干安全评估这几年,Nessus基本是随身工具了。但说实话,大部分人的用法就是装完开默认策略直接扫,出个报告就算交差。这个流程应付常规巡检没问题,真到实战项目里就捉襟见肘了。举几个…

阅读更多 →
JavaScript 数值范围操作实战:Clamp(钳制)与 Map(映射)的正确用法 2026/10/1 9:45:06

JavaScript 数值范围操作实战:Clamp(钳制)与 Map(映射)的正确用法

教程文档 【免费下载链接】30-seconds-of-code Coding articles to level up your development skills 项目地址: https://gitcode.com/gh_mirrors/30/30-seconds-of-code 点击查看 免费下载 在数值处理中,将数字限制在指定范围内(Clamp&…

阅读更多 →
JavaScript 数组按引用复制:解析 javascript.info “Is array copied“ 习题及背后的引用语义 2026/10/1 9:45:00

JavaScript 数组按引用复制:解析 javascript.info “Is array copied“ 习题及背后的引用语义

文档/教程前端 【免费下载链接】en.javascript.info Modern JavaScript Tutorial 项目地址: https://gitcode.com/gh_mirrors/en/en.javascript.info 点击查看 免费下载 导读 本文围绕 Modern JavaScript Tutorial(javascript.info)《Arra…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉