大地址感知 (LAA) 在 Wine 中如何工作?

大地址感知 (LAA) 在 Wine 中如何工作?

谁能澄清一下 Wine 中如何支持 32 位应用程序的大地址感知(LAA)?

我知道默认情况下,在 Windows 中,32 位应用程序的 RAM 最大限制为 2GB;但是,可以在可执行文件上设置 LAA 标志,以允许其使用最多 4GB。

我的理解是,默认情况下,Wine 遵守 32 位 Windows 应用程序的 2GB 限制,并且如果在 .exe 上设置了 LAA 标志,它将允许使用 4GB。然而,我听说还有一个全局选项可以为 Wine 设置为自动允许所有 32 位 Windows 应用程序使用 4GB - LARGE_ADDRESS_AWARE=1(或者类似的东西?)。

有人可以澄清这是否是正确的环境变量吗?它适用于香草葡萄酒,还是仅适用于葡萄酒分期?在 64 位 Wine 前缀中运行 32 位应用程序时是否也需要它?我以为有一个关于它的 Wine 用户指南页面,但我一直找不到它。

答案1

您可以为尝试在 WINE 下运行的每个 x86 应用程序安装一个补丁,您可以在此处找到该补丁:https://ntcore.com/?page_id=371

此外,还有一个 WINE 补丁用于在 PE 文件中设置 LAA 标志。查看 github 中包含的文件内容,看来您正在查找的变量是正确的LARGE_ADDRESS_AWARE https://github.com/randomstuff/pe-set-laa。根据这个补丁的创建者的说法,它可以在 WINE 下正常工作。

根据您尝试运行的内容(游戏或可移植可执行文件),某些应用程序的标志功效似乎存在一些不一致。

如果您想从源代码构建 Wine,您还可以使用此代码在全局范围内修补 LAA。

diff --git a/dlls/kernel32/heap.c b/dlls/kernel32/heap.c
index cac73ec..fb214b9 100644
--- a/dlls/kernel32/heap.c
+++ b/dlls/kernel32/heap.c
@@ -1423,6 +1423,7 @@ VOID WINAPI GlobalMemoryStatus( LPMEMORYSTATUS lpBuffer )
 
     /* values are limited to 2Gb unless the app has the IMAGE_FILE_LARGE_ADDRESS_AWARE flag */
     /* page file sizes are not limited (Adobe Illustrator 8 depends on this) */
+/*
     if (!(nt->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE))
     {
         if (lpBuffer->dwTotalPhys > MAXLONG) lpBuffer->dwTotalPhys = MAXLONG;
@@ -1430,7 +1431,7 @@ VOID WINAPI GlobalMemoryStatus( LPMEMORYSTATUS lpBuffer )
         if (lpBuffer->dwTotalVirtual > MAXLONG) lpBuffer->dwTotalVirtual = MAXLONG;
         if (lpBuffer->dwAvailVirtual > MAXLONG) lpBuffer->dwAvailVirtual = MAXLONG;
     }
-
+*/
     /* work around for broken photoshop 4 installer */
     if ( lpBuffer->dwAvailPhys +  lpBuffer->dwAvailPageFile >= 2U*1024*1024*1024)
          lpBuffer->dwAvailPageFile = 2U*1024*1024*1024 -  lpBuffer->dwAvailPhys - 1;
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 4d4bc3b..2c2264c 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -1845,7 +1845,7 @@ void virtual_set_large_address_space(void)
 {
     IMAGE_NT_HEADERS *nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress );
 
-    if (!(nt->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE)) return;
+    // if (!(nt->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE)) return;
     /* no large address space on win9x */
     if (NtCurrentTeb()->Peb->OSPlatformId != VER_PLATFORM_WIN32_NT) return;
 

相关内容