是否可以在RAM模块出现故障的情况下运行Windows(7,x64)?更准确地说,是否有某种方法可以告诉Windows不要分配已知的错误地址或地址块?
对于Linux,有BadRAM。Windows是否有现有的实现?Windows内核(NT 6.1)甚至可以实现吗?也许是内核模式驱动程序?
是否可以在RAM模块出现故障的情况下运行Windows(7,x64)?更准确地说,是否有某种方法可以告诉Windows不要分配已知的错误地址或地址块?
对于Linux,有BadRAM。Windows是否有现有的实现?Windows内核(NT 6.1)甚至可以实现吗?也许是内核模式驱动程序?
Answers:
鲍勃,您的问题分为三个部分。我一次给一个。
确实有可能在模块损坏的情况下运行Windows 7。根据损坏扇区的位置以及模块在DIMM内存中的位置,只要不尝试触摸内存的损坏部分,Windows 7就会像没有任何东西一样运行。因此,理想情况下,应将有故障的模块尽可能地远离bank0。自然,如果这是您唯一的模块,那么您就不走运了。
在x86(32位和64位)操作系统上,内存由内核管理。如您所述,BadMem能够阻止Linux中的坏内存扇区。它通过指示内核锁定您指定的那些内存地址来工作。这有效地阻止了Linux在分配(和取消分配)内存时访问这些地址。但是,为此,BadMem需要修补内核。BadMem仅仅是您在应用之前配置的内核补丁。
现在,您在Windows上没有该功能。您无法修补内核。开发内核模式驱动程序也不会带来任何好处,因为Windows内核永远不会让您的驱动程序优先于其内存管理体系结构(这是可以理解的)。
因此,您不能以任何方式指示窗口不使用某些内存地址。唯一的方法是Microsoft为您的案例专门修补内核。不太可能。
内存模块可能包含错误地址的原因并不多。最终,所有这些归结为生产线中的错误,前提是假定它在进入计算机之前没有遭受损坏。众所周知,与硬盘驱动器相反,内存模块中没有活动部件。因此,不良扇区不会像硬盘扇区那样容易扩散。
但是,内存测试软件并非万无一失。它有可能(而且很常见)传递实际上是错误的某些地址。因此,随着越来越多的地址显示不正确,错误的内存可能会给人“传播”的印象。因此,诸如BadMem之类的工具会显示出它们的弱点,因为它们自然只能处理您指示它们的地址。
任何人都不可能对存储模块进行全面测试并识别所有不良的存储器地址,然后锁定它们并最终得到一个“良好”的存储模块。最简单的方法是将地址错误的模块视为有缺陷的模块,因此始终不被信任。
这意味着,尽管BadMem是一个有吸引力的主张,但它实际上并不是解决内存不足问题的解决方案。更有可能的是,您仍然会遇到尝试读取坏扇区并因停止错误而崩溃的操作系统。坏模块是坏模块,是坏模块。
Windows BCD(引导配置数据)实际上有一个{badmemory}
对象。似乎ECC内存“预计将失败”的内存地址将在此处列出,而不被操作系统使用。
该{badmemory}
对象接受一个BadMemoryList
(BCD type 0x1700000a
)元素,该元素是可以用十六进制输入的整数列表,以空格分隔。我想可以手动将memtest86发现的坏内存地址插入到此元素中-但我尚未对此进行测试。显然,它接受“页帧号”,即实际地址除以4096。不幸的是,这些地址/ PFN可能与内存诊断报告的地址/ PFN不匹配。可以使用Visual BCD Editor进行手动编辑。
在任何情况下,都应按照其他答案所示更换故障的记忆棒。这仅仅是解决此问题的一种方法(暂时?)。
Windows BCD具有{badmemorylist}
和{badmemoryaccess}
对象。您应将第一个设置为以空格(例如bcdedit /set badmemorylist 1499543 1434007
)分隔的错误内存页面,第二个设置为No
(bcdedit /set badmemoryaccess No
)
请记住,通常Windows中的内存页面大小 4KB
在Windows 7中进行了测试,效果很好
您可以通过Sysinternals的Rammap测试设置
PS我有从 "Windows Internals Book" chapter 10
我在使用SoC的平板电脑中遇到内存问题。内存已焊接或集成到SoC中,无法更换。
我在阿根廷,卖家在中国,运费和时间都没有保证意义。
我设法了一些命中。
传递损坏的内存参数的关键是:
0x10000000
对应于Windows中的0x100000x00001000
对应于Windows中的0x1bcdedit /set {badmemory} badmemorylist 0xB7 0xB8 0xB9 0xBA
memtest中的错误从0x000B7000到0x000BAFFF。请注意,您不能放置一系列记忆,但是所有页面都一个接一个bcdedit /enum {badmemory}
,显示已标记页面的列表。bcdedit /set badmemoryaccess no
防止使用标记的页面/
和命令之间的空白才能使它工作,所以对于其他命令来说,空白bcdedit / enum {badmemory}
将是bcdedit /enum {badmemory}
相同的
据我所知,唯一的方法是使用BurnMem命令,该命令可以人为限制RAM窗口的使用量。
maxmem
,因为显然burnmem
并没有限制最大物理地址maxmem
。Vista和7等效truncatememory
。尽管这是一个可能的解决方案,但是对于有缺陷的存储器位于地址空间的中间或开头并在不需要之后阻塞所有内容的情况,是否有一种更精确的方法?
看看这个工具:https : //github.com/prsyahmi/BadMemory
它非常易于使用,并支持地址范围的阻塞。而且,您可以使用从MemTest86收到的完整地址,而无需删除最后三位数字。
警告!!!Windows可能无法启动,请准备重建BCD。在这种情况下,请使用“高级启动选项”中的“命令提示符”。我不知道为什么它不会再启动,似乎是随机发生的,或者如果您将太多地址输入到badmemorylist中。
bootrec /rebuild bcd
bcdedit /export c:\bcdbackup
attrib c:\boot\bcd -h -r -s
ren c:\boot\bcd bcd.old
bootrec /rebuild bcd
继承人C ++命令提示符PROGRAMM是得到一个连续的内存ADRESS列表中的.txt文件准备bcdedit /set badmemorylist
或bcdedit /set {badmemory} badmemorylist
(没有工作Win7上对我来说)
使用bcdedit /set badmemoryaccess 0
拒绝访问。
您可以在视图设置->详细中使用EasyBCD进行检查。重新启动后,使用Rammap检查物理地址空间是否消失。
#include <cstdlib>
#include <iostream>
#include <fstream>
//converts hex into base10
unsigned long convertHexToIntBase10(char* inputHex)
{
unsigned long hexValue = std::strtoul(inputHex, 0, 16);
return hexValue;
}
int main(int argc, char* argv[])
{
if(argc < 3){
std::cerr << "Usage: MemoryPageListHex [Low Memory Adress] [High Memory Adress] in 4k Pages i.e. MemoryPageListHex 1bae50 1bb0e7 for 0x1bae50148 to 0x1bb0e7fe8" << std::endl;
return 0;
}
auto lowAdr = convertHexToIntBase10(argv[1]);
auto highAdr = convertHexToIntBase10(argv[2]);
std::ofstream myfile;
myfile.open ("MemoryAdress4k.txt");
for (auto i=lowAdr; i<highAdr; i++){
myfile << std::hex << "0x" << i << " ";
}
myfile.close();
return 0;
}
是。有启动参数可以控制Windows可以使用的内存量。但是,您只能从内存空间的末尾删除。请参阅此msdn文章以控制启动参数。感兴趣的参数是truncatememory
和removememory
。
您可以在Windows 7中尝试此功能,但是我不确定它会影响哪个芯片,或者每个功能是否削去了相同的数量。我必须环顾四周才能找到答案。