随着内存价格的不断下降,相信很多朋友都和 Aulddays 一样已经用上了 4G 甚至更多的内存。在 64 位 Windows 系统仍存在一些驱动兼容性问题的情况下,32 位的系统仍然是绝对的主流,但 32 位的桌面版 Windows 版系统对 4G 以上内存的支持似乎一直不好。关于这个问题,网上的文章清一色的会提到 PAE(Physical Address Extension 物理地址扩展)技术。遗憾的是,据绝大多数朋友的测试情况来看,即使启用了 PAE,32 位的 Windows Vista 仍然无法使用全部的 4G 内存。在 Vista SP1 中,微软使了个小技巧,让系统属性中可以显示“已安装”的 4G 内存;但更进一步,在任务管理器中证实实际可用的内存仍然只有 3069M(最多不超过 3.25G,依不同配置而定),如下图所示:
![32 位 Vista 4G 内存](http://s3.amazonaws.com/scrnshots.com/screenshots/184914/3069mpng)
这一点,在系统属性程序(开始\运行,输入“msinfo32”,回车)中可以更清楚的看出“已安装物理内存”和“可用物理内存”的数量。
PAE?并不足够
PAE 是 32 位系统内存支持不得不说的一个问题。在没有 PAE 的情况下,32 位系统使用 32 位的地址空间,因此总共可以支持 2^32=4G 的内存,再加上一些系统的限制,没有 PAE 的 32 位 Windows 上本来实际只能使用 3G 的内存。而 PAE 则是一种地址扩展技术,通过它可以让操作系统拥有更多的地址空间,理论上可以支持 128G 甚至更多的内存。PAE 在 Windows Server 系统上可以很好的工作,如下图所示,32 位的 Server 2008 (和 Vista 实际使用相同的内核)在开启 PAE 之后可以很好的使用 4G 内存,但 Vista 上即使开启了 PAE 也仍然只能使用 3G 内存(事实上,Vista 默认是开启 DEP 的,而 DEP 功能需要 PAE 支持,因此一般来说 PAE 其实并不需要手动设置而是自动开启的。点击这里可以看到关于 DEP 的详细讨论),这又是为什么呢?
![Server 2008 4G 内存](http://s3.amazonaws.com/scrnshots.com/screenshots/184918/win2008_4gpng)
技术大牛 Geoff Chappell 在研究了 Vista 和 Server 2008 的内核之后发现,造成这个限制的实际上是 Vista 的许可证限制!简单来说,vista/2008 内核在启动初期会调用 MxMemoryLicense 未公开 API 函数来确定系统“许可(licensed)”使用的最大内存数量;而 MxMemoryLicense 则会查询 tokens.dat 和 pkeyconfig.xrm-ms 两个文件确定系统的许可证(桌面系统还是服务器系统),接下来再根据许可证类型确定支持内存的最大值。如果系统内存大于根据许可证确定的值,则在内核启动时多余的内存就会被完全忽略掉。这也就是造成 32 位 Vista 不能使用 4G 或以上内存的根本原因。
目前已经有两个测试证实了这个情况,并成功在 32 位 Vista 下使用了 4G 内存。注意:进行这两个测试实际已经违反了 Windows Vista 的使用许可证,所以是存在版权问题的;在弄清这个问题之前请不要轻易进行类似的测试!
测试1. 替换系统授权:
将 Vista 中的 C:\ Windows\ ServiceProfiles\ NetworkService\ AppData\ Roaming\ Microsoft\ SoftwareLicensing\ tokens.dat 文件和 C:\ Windows\ System32\ licensing\ pkeyconfig\ pkeyconfig.xrm-ms 文件分别用 Server 2008 中的同名文件替换。之后再启动系统时内核就会误认为启动的是 Server 2008 系统,而消除 Vista 许可证对内存的限制。但是这样一来很多系统服务和系统组件也会按照 2008 的方式来运行,造成很多不兼容性。
测试2. 修改系统内核
在 Geoff Chappell 的文章中(点击查看原文)采用了直接 patch 系统内核的方法。经 Aulddays 测试,这种方法同样适用于目前最新版的 Windows 7 RTM 系统。这种方法难度较大,但带来的不兼容性则小的多,并且可以完美支持多至 128G 的内存!他的具体做法如下:为避免原始内核被破坏,首先复制系统内核文件 ntkrnlpa.exe,并命名为 ntkr128g.exe,之后的修改都在 ntkr128g.exe 上进行。用 hex 编辑器打开 ntkr128g.exe,查找下列两个字符串:
特征串1:7C 11 8B 45 FC 85 C0 74 0a
特征串2:7C 10 8B 45 FC 85 C0 74 09
两个特征串在内核中都出现且只出现一次,虽然特征串内容不同,但修改方式相同:把 0x8B 开始的 7 个字节(即上面标记为深红色的部分。最前两个字节不作修改!)修改成:
后7个字节修改成:B8 00 00 02 00 90 90
对于目前的两个版本的 Vista 和最新的 Windows 7,修改处的文件偏移地址(即 0x8B 字节的位置)分别如下:
版本号 |
版本 |
文件偏移地址 |
6.0.6000.16386 |
Windows Vista |
0x003040B1, 0x003040F2 |
6.0.6001.18000 |
Windows Vista SP1 |
0x00309AA3, 0x00309AE4 |
6.1.7600.16385 |
Windows 7 |
0x0035C243, 0x0035c283 |
接下来测试加载修改后的内核。首先需要为修改后的内核重新计算 checksum 和生成数字签名。在命令行中输入下面3个命令:
editbin /release ntkr128g.exe
makecert -r -ss my -n "CN=My Own Testing Authority"
signtool sign -s my -n "My Own Testing Authority" ntkr128g.exe
上述签名过程需要用到三个命令行工具,其中 editbin 在 Visual Studio 中自带,而 makecert 和 signtool 在 Windows SDK 6.0 中自带,如果你机器上安装了 Visual Studio 2008 的话,第一个工具可以在 %VS2008_Dir%\ VC\ Bin\ 中找到,后两个工具可以在 %ProgramFiles%\ Microsoft SDKs\ Windows\ v6.0A\ bin\ 中找到。Visual Studio 2008 Express 和 Windows SDK 6.0 都可以从微软网站免费下载; 如果不想麻烦另外安装的话,也可以点击这里单独下载这几个工具; 如果运行时提示缺少 MSVCR90.DLL,请先点击这里下载安装 VC2008 的运行时组件。
最后在系统启动菜单中加入一条新的启动菜单项(需以管理员方式运行命令提示符)(如果是Windows 7 系统的话可将命令中的 Vista 换成 7):
bcdedit /copy {current} /d "Windows Vista With More Than 4GB"
运行成功后,该命令会返回一个 GUID 值,记录下该 GUID 值,并运行下面三条,用之前返回的 GUID 值替换命令中的 guid(命令中包含 guid 的大括号也要输入):
bcdedit /set {guid} pae ForceEnable
bcdedit /set {guid} kernel ntkr128g.exe
bcdedit /set {guid} testsigning on
最后,重启系统并在启动菜单中选择 "Windows Vista (或 7) With More Than 4GB" 一项即可。由于修改了内核,系统启动后桌面上会显示“Test Mode”的提示。
查看:原文地址;来源:live.aulddays.com。