![GRUB 因 64 位 Memtest86+ BadRAM 模式而挂起?](https://linux22.com/image/220388/GRUB%20%E5%9B%A0%2064%20%E4%BD%8D%20Memtest86%2B%20BadRAM%20%E6%A8%A1%E5%BC%8F%E8%80%8C%E6%8C%82%E8%B5%B7%EF%BC%9F.png)
当我添加“巴德拉姆“ 模式64位内存测试86+v6.10/v6.20 给了我,GRUB 2启动时完全挂起。
![](https://i.stack.imgur.com/plSjd.jpg)
![](https://i.stack.imgur.com/MUYys.jpg)
问:
- 为什么 badram 模式地址与显示的“错误地址”不同 (
0x0ac...
vs0x62c...
)?造成这种明显偏移的原因是什么? - 为什么 GRUB 在传递 64 位
badram
模式时挂起?
这是我的 GRUB...
# grub-mkimage --version
grub-mkimage (GRUB) 2.06-3~deb11u5
工作中睡觉...
![](https://i.stack.imgur.com/2rnxr.jpg)
超过 ”欢迎使用 GRUB!“消息,什么也没有。没有重新启动,对按键输入没有反应,没有救援 shell。
系统完全”砖砌的“ - 我必须构建一个救援 USB UEFI 启动棒才能从中恢复。(顺便说一句,没有安全启动硬件,没有签名的 grub 安装,所以没有借口。)
反正。我对系统内存没有太多了解,并且确实无法从 Memtests 的十六进制数字中看出太多信息。
但我不认为我可以只修剪前导零并将这些 32 位数字传递给 GRUB,或者可以吗? ...reddit 上的某个人似乎就是这么做的,但是,像我一样,事后无法验证这些数字是否确实按预期工作,并掩盖了正确的内存区域。
为什么 GRUB 会在这个问题上搞砸呢?这是一个不好屏蔽的内存区域吗?区域是否太小,是否应该是特定大小(例如 4K 页面大小)或对齐?
也许GRUBbadram
刚刚坏掉了吗?或者是硬件? (我不这么认为,但你永远不知道这些 ACPI 表,对吧?)
无论如何,我发现了很多其他人报告与 GRUB + 64 位地址相同的问题的实例(显然我的 GRUB 不是唯一的懒惰工作者):
发出此命令(通过 grub.cfg 或在命令行上交互)后,我的系统挂起并变得无响应。
badram 0x000000008c4e0800,0xffffffffffffcfe0
GRUB_BADRAM="0x00000000b3a9feec,0xfffffffffffffffc"
经过上述更改后,我甚至无法看到 Grub 启动屏幕。当它应该出现时,计算机只是挂起并显示黑屏。
我做了所有这些,但是在添加 GRUB_BADRAM= 行后,计算机完全正常并且没有错误拒绝启动。它永远不会启动并且根本不提供菜单。
...我无法判断这些模式之间是否存在任何使它们变坏的关系,或者 GRUB 是否badram
只是简单地不适用于 64 位地址,因为我找不到任何积极的“对我有用”报告。
(这些都归结为人们使用 Linuxmemmap=
格式或 Linuxmemtest=
内核参数。)
最后,我又找到了一位似乎在badram
……方面取得了成功的人。使用 32 位地址表示法(在 64 位机器上)?
所以接下来我要尝试一下。
答案1
虽然我没有真正找到答案为什么,因为我无法理解 GRUB 源代码,所以我现在非常确定 GRUB 2 的badram
命令是刚刚坏了对于 64 位地址空间。
因此,此信息适用于可能陷入这个兔子洞的其他人。
(tl;dr:badram
无法使用!请使用 Linux 的memmap=
内核模式。)
应用 grub 命令行后badram 0xac4d96c0,0xfffffff8
,我在 Linux 的 e820 内存映射中看到的是这样的碎片(抱歉,SE 没有彩色差异突出显示):
--- a/e820
+++ b/e820
@@ -1,5 +1,7 @@
[ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009ffff] usable
-[ 0.000000] BIOS-e820: [mem 0x0000000000100000-0x00000000bd6f5fff] usable
+[ 0.000000] BIOS-e820: [mem 0x0000000000100000-0x00000000ac4d8fff] usable
+[ 0.000000] BIOS-e820: [mem 0x00000000ac4d9000-0x00000000ac4d9fff] unusable
+[ 0.000000] BIOS-e820: [mem 0x00000000ac4da000-0x00000000bd6f5fff] usable
[ 0.000000] BIOS-e820: [mem 0x00000000bd6f6000-0x00000000bd749fff] ACPI NVS
[ 0.000000] BIOS-e820: [mem 0x00000000bd74a000-0x00000000bd751fff] ACPI data
[ 0.000000] BIOS-e820: [mem 0x00000000bd752000-0x00000000bd752fff] ACPI NVS
@@ -28,4 +30,18 @@
[ 0.000000] BIOS-e820: [mem 0x00000000fed61000-0x00000000fed70fff] reserved
[ 0.000000] BIOS-e820: [mem 0x00000000fed80000-0x00000000fed8ffff] reserved
[ 0.000000] BIOS-e820: [mem 0x00000000fef00000-0x00000000ffffffff] reserved
-[ 0.000000] BIOS-e820: [mem 0x0000000100001000-0x000000083effffff] usable
+[ 0.000000] BIOS-e820: [mem 0x0000000100001000-0x00000001ac4d8fff] usable
+[ 0.000000] BIOS-e820: [mem 0x00000001ac4d9000-0x00000001ac4d9fff] unusable
+[ 0.000000] BIOS-e820: [mem 0x00000001ac4da000-0x00000002ac4d8fff] usable
+[ 0.000000] BIOS-e820: [mem 0x00000002ac4d9000-0x00000002ac4d9fff] unusable
+[ 0.000000] BIOS-e820: [mem 0x00000002ac4da000-0x00000003ac4d8fff] usable
+[ 0.000000] BIOS-e820: [mem 0x00000003ac4d9000-0x00000003ac4d9fff] unusable
+[ 0.000000] BIOS-e820: [mem 0x00000003ac4da000-0x00000004ac4d8fff] usable
+[ 0.000000] BIOS-e820: [mem 0x00000004ac4d9000-0x00000004ac4d9fff] unusable
+[ 0.000000] BIOS-e820: [mem 0x00000004ac4da000-0x00000005ac4d8fff] usable
+[ 0.000000] BIOS-e820: [mem 0x00000005ac4d9000-0x00000005ac4d9fff] unusable
+[ 0.000000] BIOS-e820: [mem 0x00000005ac4da000-0x00000006ac4d8fff] usable
+[ 0.000000] BIOS-e820: [mem 0x00000006ac4d9000-0x00000006ac4d9fff] unusable
+[ 0.000000] BIOS-e820: [mem 0x00000006ac4da000-0x00000007ac4d8fff] usable
+[ 0.000000] BIOS-e820: [mem 0x00000007ac4d9000-0x00000007ac4d9fff] unusable
+[ 0.000000] BIOS-e820: [mem 0x00000007ac4da000-0x000000083effffff] usable
大块可用内存被许多小区域分割成碎片,我猜这意味着0xfffffff8
我们给 GRUB 传递的地址掩码在逻辑上0x00000000fffffff8
位于 64 位空间中。
然后内核继续记录将所有这些“不可用”的漏洞从系统 RAM 映射为 RAM 缓冲区,这应该使该模式更加明显:
[ 0.615775] e820: reserve RAM buffer [mem 0xac4d9000-0xafffffff]
[ 0.615779] e820: reserve RAM buffer [mem 0x1ac4d9000-0x1afffffff]
[ 0.615780] e820: reserve RAM buffer [mem 0x2ac4d9000-0x2afffffff]
[ 0.615781] e820: reserve RAM buffer [mem 0x3ac4d9000-0x3afffffff]
[ 0.615782] e820: reserve RAM buffer [mem 0x4ac4d9000-0x4afffffff]
[ 0.615783] e820: reserve RAM buffer [mem 0x5ac4d9000-0x5afffffff]
[ 0.615784] e820: reserve RAM buffer [mem 0x6ac4d9000-0x6afffffff]
[ 0.615785] e820: reserve RAM buffer [mem 0x7ac4d9000-0x7afffffff]
0xac4d9000
所以我们实际上保留了从到 的空间0xac4d9fff
...
这是我们的0xac4d96c0
badram 地址,在下边界上对齐,然后在我们的微小位错误周围打出一个漂亮的 4KB 内核页面大小的洞。
(如果你愿意的话,想象一下,有人用炮弹在墙上打了一个洞,从而摆脱了墙上的蜘蛛。确实,显然解决了这个问题。)
...然后我们继续打孔,0x1ac4d9000
在, 0x2ac4d9000
, ...处预留相同大小的空间0x3ac4d9000
,直到我们用完系统内存。
(现在那看起来像一个加了一些喷雾的炮弹发射器!)
但所有这些都是小洞,而墙又大,所以确实一切都会好起来的。但是,如果我们的badram
图案实际上比本例中的要大得多怎么办?或者更糟糕的是,Memtester 给了我们一大堆需要避开的地方?那么这个问题就让我们的内存映射变成了一个筛子!
因此,不要badram
在 64 位系统上使用 GRUB,除非您知道自己在做什么。
相反,Linux 上一个完美的替代选项是使用memmap=
命令行参数。顺便说一句,这还允许您打出比 GRUB 生成的 4KB 块更小的孔,并且还可以与 EFIStub 等其他引导加载程序一起使用。 (另一种选择可能是以某种方式传递您自己的、修改过的内核,e820
内存映射——但如果你知道怎么做,你可能就不会读这篇文章了。)