不久前,我在一台计算机上安装了16 GB的内存。 它的
富士康P55MX主板上装有Core i5 750,可以更换旧的CPU,但它仍然可以正常工作并满足我的所有需求。
这是有趣的事情。 主板不正式支持16 GB的RAM。 上页的规格表示最多支持8 GB。 主板上只有两个插槽,所以我怀疑主板出来时8GB的条带很少见。 我还是决定尝试一下。 在许多情况下,主板支持的RAM比制造商官方宣称的要多。
我确保已安装最新的BIOS版本(946F1P06版),并插入了我的8 GB修剪中的两个。 然后我下载了Ubuntu 16.04,一切运行正常。 我认为我的理论认为开发板支持的内存比文档中所述要多,这是正确的,而我却忘记了。 我喜欢与额外的RAM一起工作,并且我为游戏的回报感到高兴。
但是几个月后,我尝试下载Windows10。基本上,计算机在Linux上运行。 仅在某些情况下,您需要引导Windows进行检查。 就在那时,乐趣开始了。
当GRUB出现时,我从菜单中选择Windows 10,然后按Enter。 Windows引导屏幕短暂出现,然后我被死亡的蓝屏欢迎。

停止码:ACPI_BIOS_ERROR。 我经过大量的搜索,发现其实质是BIOS中的ACPI表存在某种问题。 除其他事项外,ACPI表还告诉操作系统如何配置硬件。 尝试从Windows安装USB驱动器引导会导致相同的错误。 所以,我认为富士康没有撒谎。 这台计算机确实不支持16 GB的RAM。 返回到8 GB导致下载成功。 RAM测试也非常出色,因此它的内存条也不错。
我试图与富士康支持部门联系以修复BIOS,但没有收到响应。 该电子邮件地址已列在其网站上,但无法使用。 也许富士康不再处理主板。 看来他们也不提供支持。
在这一点上,一个普通人只会放弃,辞职到8 GB的内存或购买一台新计算机。 但是我不想轻易放弃。 我知道理论上一台计算机可以使用16 GB,因为它可以在Linux上完美运行。 因此,我开始学习ACPI并尝试使用BIOS设置。
我找到了一个有趣的BIOS部分,您可以在其中使用一些内存设置。 一个参数是“内存重映射功能”。 她被包括在内。 BIOS文档说,该选项允许“重叠PCI内存”用于映射到共享物理内存之上。 Internet上的搜索表明,引导到64位OS时必须将其启用。 仅出于实验目的,我将其关闭,Windows真正启动了! 但是,她说她可以使用少于4 GB的RAM。 但这很好:我有一种方法可以进入Windows,而不必实际卸下内存条。
Ubuntu是一样的。 禁用内存重新映射功能后,将我的内存限制为不足4 GB。 此刻,我确定存在某种内存映射问题。 我决定更详细地研究ACPI_BIOS_ERROR错误及其原因-并遇到了用于调试Microsoft驱动程序的
出色文档 ,
该文档解释了ACPI_BIOS_ERROR错误检查。
根据该文档,有必要找到以前在旧版Windows中蓝屏上显示的四个错误参数。 Windows 10默认情况下隐藏所有信息,但是您可以通过向注册表添加条目来重新启用其他错误信息的显示。 这是
superuser.com上的一个
很好的答案,它为我指明了正确的方向 。
在相应地编辑了注册表之后,我再次在BIOS中打开了内存重新映射功能,并启动了Windows。 BSOD现在在左上角显示四个附加代码:

太好了! 因此,参数1为0x0000000000000002。 Microsoft文档说参数1等于0x02,表示处理PCI根总线的资源列表时出现问题。 由于参数2、3和4看起来像疯狂值,因此它们可能是指针。 而且,如果这里只有指针,微软表示问题在于PCI解码区域与E820 BIOS返回的存储区域列表重叠。
好吧 有很多信息,但是您可以从某种角度开始研究。 我发现了有关如何调用E820 BIOS提供有关内存区域的信息的信息。 然后,他返回Linux,并使用dmesg命令查看了所有内核启动信息,特别注意了E820和ACPI。 发现了以下内容:
BIOS-e820:[内存0x0000000000000000-0x000000000009ebff]可用
BIOS-e820:保留[mem 0x000000000009ec00-0x000000000009ffff]
BIOS-e820:[内存0x00000000000e0000-0x00000000000fffff]保留
BIOS-e820:[内存0x0000000000100000-0x00000000cf77ffff]可用
BIOS-e820:[mem 0x00000000cf780000-0x00000000cf78dfff] ACPI数据
BIOS-e820:[mem 0x00000000cf78e000-0x00000000cf7cffff] ACPI NVS
BIOS-e820:保留[mem 0x00000000cf7d0000-0x00000000cf7dffff]
BIOS-e820:保留[mem 0x00000000cf7ed000-0x00000000cfffffff]
BIOS-e820:保留[mem 0x00000000fee00000-0x00000000fee00fff]
BIOS-e820:保留[mem 0x00000000ffb00000-0x00000000ffffffff]
BIOS-e820:[内存0x0000000100000000-0x000000042fffffff]可用
后来我看到了:
acpi PNP0A08:00:忽略主机桥接窗口[mem 0x400000000-0xfffffffff
窗口](与系统RAM [mem 0x100000000-0x42fffffff]冲突)
PCI主机桥接到总线0000:00
pci_bus 0000:00:根总线资源[io 0x0000-0x0cf7窗口]
pci_bus 0000:00:根总线资源[io 0x0d00-0xffff窗口]
pci_bus 0000:00:根总线资源[mem 0x000a0000-0x000bffff窗口]
pci_bus 0000:00:根总线资源[mem 0x000d0000-0x000dffff窗口]
pci_bus 0000:00:根总线资源[mem 0xd0000000-0xdfffffff窗口]
pci_bus 0000:00:根总线资源[mem 0xf0000000-0xfed8ffff窗口]
pci_bus 0000:00:根总线资源[bus 00-ff]
是的 看到冲突警告? 我不会注意到它,但是在安装内存之后,Linux在每次引导时开始显示此消息。 我尝试使用BIOS中禁用的内存重新映射功能启动Linux。 在这种情况下,最后一个e820区域从0x100000000消失到0x42fffffffff,因此冲突消息也消失了,另一个“根总线资源”出现在列表中,主桥窗口从0x400000000变为0xfffffffff。
那么会发生什么。 Linux使用16 GB,因为它注意到冲突并且忽略了ACPI提供的冲突的PCI范围,而Windows却厌恶地举起了手,吐出了蓝屏:“您的BIOS出现了问题!” 我不能怪Windows。 确实存在重叠,因此您可以理解它是混乱的。
在这一点上,我不确定是否要继续。 从0x400000000到0x42fffffffffffff的最后768 MB内存映射到主板用于PCI的巨大存储空间区域的开头。 显然,如果主板期望在那儿使用PCI,则可能会发生某些严重错误。 因此,主板仅支持15.25 GB的RAM,对吗?
但是……在Linux上,一切都可以正常工作,而无需此额外的PCI映射区域的支持! 如果我们以某种方式修改ACPI表,以便较大的PCI范围从0x430000000而不是0x400000000开始,也就是说,在物理RAM结束后立即开始,该怎么办? 然后,冲突将消失,并且大多数PCI映射窗口仍将可用。
通话被接听。
我开始深入研究ACPI表。 幸运的是,Linux使转储非常容易。 有一些特殊的工具,但是可以在sysfs中轻松找到表:
/ sys /固件/ acpi /表
他们在这里。 我也很高兴GRUB有机会用新版本替换您的ACPI表。 因此,如果找出涉及哪个表,则可以使用GRUB安装该表的新版本。 从理论上讲,Windows将对此感到满意。
在其他工具中,我使用
iasl解析了各种ACPI表并找到了要替换的值0x400000000。 最有可能的是,该值是按逆字节顺序(little-endian)排列的,大小为64位,因此我运行
binwalk搜索了所有表文件:
binwalk -R'\ x00 \ x00 \ x00 \ x00 \ x04 \ x00 \ x00 \ x00'*
OEMB表中有一个结果。 其后的下一个64位字为0x1000000000,略大于主桥窗口冲突消息中的结束地址。 非常有前途的线索。 OEMB表是特殊的,因为它不是根据ACPI规范的标准表。 Linux抱怨校验和无效,但是我认为这并不重要。 我想你猜我接下来要做什么...
我制作了一个OEMB表的副本,将字节0x04之前的字节0x00立即替换为0x30,以将值更改为0x430000000(请记住,这是相反的顺序)。 我将此修改后的副本放置在文件/boot/oemb.dat中。 然后,他用GRUB用我的副本替换了OEMB表,将以下命令暂时粘贴到引导命令列表中(选择Ubuntu后在GRUB中输入字母'e'):
acpi --exclude = OEMB /boot/oemb.dat
其想法是,它告诉GRUB加载除OEMB表之外的所有ACPI表,然后加载/boot/oemb.dat的内容并将其添加为附加表。 这将有效地将旧的OEMB表替换为新的OEMB表。
好的,我启动了Linux,然后...
acpi PNP0A08:00:忽略主机桥接窗口[mem 0x400000000-0xfffffffff
窗口](与系统RAM [mem 0x100000000-0x42fffffff]冲突)
. WTF? , PCI - , , . , OEMB , .
iasl DSDT. , DSDT
_CRS
, .
iasl -d DSDT
.dsl _CRS, PCI, . DSDT , . _CRS . , _CRS , 0xCF78E064. Linux dmesg :
ACPI: Early table checksum verification disabled
ACPI: RSDP 0x00000000000F9820 000014 (v00 ACPIAM)
ACPI: RSDT 0x00000000CF780000 000044 (v01 012110 RSDT0821 20100121 MSFT 00000097)
ACPI: FACP 0x00000000CF780200 000084 (v01 012110 FACP0821 20100121 MSFT 00000097)
ACPI: DSDT 0x00000000CF780460 006FE7 (v01 946F1 946F1P06 00000000 INTL 20051117)
ACPI: FACS 0x00000000CF78E000 000040
ACPI: APIC 0x00000000CF780390 00008C (v01 012110 APIC0821 20100121 MSFT 00000097)
ACPI: MCFG 0x00000000CF780420 00003C (v01 012110 OEMMCFG 20100121 MSFT 00000097)
ACPI: OEMB 0x00000000CF78E040 000082 (v01 012110 OEMB0821 20100121 MSFT 00000097)
ACPI: HPET 0x00000000CF78A460 000038 (v01 012110 OEMHPET 20100121 MSFT 00000097)
ACPI: GSCI 0x00000000CF78E0D0 002024 (v01 012110 GMCHSCI 20100121 MSFT 00000097)
ACPI: DMAR 0x00000000CF790100 000090 (v01 AMI OEMDMAR 00000001 MSFT 00000097)
ACPI: SSDT 0x00000000CF7917C0 000363 (v01 DpgPmm CpuPm 00000012 INTL 20051117)
! OEMB. . OEMB?
dmesg OEMB. , , , GRUB , OEMB, . , DSDT 0xCF78E064 OEMB. - , - . .
DSDT, OEMB, , , GRUB , OEMB.
. GRUB
write_byte
,
write_word
,
write_dword
read_
. GRUB OEMB? BIOS' . , RAM, .
. GRUB:
write_byte 0xCF78E0B5 0x30
0x00 0x04 0x30, 64- PCI 0x0000000430000000. OEMB, Linux , , , , .
Linux dmesg PCI.
PCI host bridge to bus 0000:00
pci_bus 0000:00: root bus resource [io 0x0000-0x0cf7 window]
pci_bus 0000:00: root bus resource [io 0x0d00-0xffff window]
pci_bus 0000:00: root bus resource [mem 0x000a0000-0x000bffff window]
pci_bus 0000:00: root bus resource [mem 0x000d0000-0x000dffff window]
pci_bus 0000:00: root bus resource [mem 0xd0000000-0xdfffffff window]
pci_bus 0000:00: root bus resource [mem 0xf0000000-0xfed8ffff window]
pci_bus 0000:00: root bus resource [mem 0x430000000-0xfffffffff window]
pci_bus 0000:00: root bus resource [bus 00-ff]
! 0x430000000-0xfffffffffff , . , Linux , Windows .
! Windows 16 RAM, GRUB write_byte. Windows 10, , . - Windows, , RAM, . !
GRUB, /etc/grub.d/00_patchbios :
# This file patches the BIOS in my Foxconn P55MX motherboard to work
# properly when I have 16 GB of RAM installed. It's a nasty hack.
# Basically, the BIOS is hardcoded in the OEMB ACPI table
# to have a PCI address range from 0x400000000 to 0xfffffffff, but
# that overlaps with 16 GB of RAM being installed, because the RAM
# uses up (among other ranges) 0x100000000 to 0x42fffffff.
# This patch changes the table to actually list a PCI range of:
# 0x430000000 to 0xfffffffff
echo "write_byte 0xCF78E0B5 0x30"
sudo update-grub
. GRUB.
, . PCI - . , RAM. Linux 16 RAM, . , PCI/PCIe - , , , , . , , , ACPI BIOS .
, , ! , - . , .