0

When I add the "badram" pattern that 64bit Memtest86+ v6.10/v6.20 gave me, GRUB 2 hangs completely on boot.

Q:

  • Why is the badram pattern address different from the "Error Address" displayed (0x0ac... vs 0x62c...)? What is the reason for this apparent offset?
  • Why does GRUB hang on passing a 64bit badram pattern?

This is my GRUB...

# grub-mkimage --version
grub-mkimage (GRUB) 2.06-3~deb11u5

sleeping on the job...

Beyond the "Welcome to GRUB!" message, nothing. No reboot, no reaction to key inputs, no rescue shell.
System completely "bricked" - I had to build a rescue USB UEFI boot stick to to recover from this. (Btw, no secure-boot hardware, no signed grub install, so no excuse.)

Anyway. I don't have too much knowledge about system memory and really can't tell much from Memtests' hex numbers.
But I don't think I can just trim the leading zeros and pass these like 32-bit numbers to GRUB, or can I? ...Some person on reddit seems to have done just that, but, like me, couldn't afterwards verify if those numbers actually worked as expected, and masked out the correct memory regions.

Why might GRUB crap itself on this? Is this a bad mem region to mask? Is the region too small, should it be a certain size (like 4K page size) or alignment?

Is GRUB badram just broken, perhaps? Or is the hardware? (I don't think so, but you never know with these ACPI tables, right?)

In any case, I dug up quite a few instances of other people reporting the same problem with GRUB + 64bit addresses (clearly my GRUB is not the only lazy worker out there):

Upon issuing this command (either via grub.cfg or interactively on the command line) my system hangs and becomes unresponsive. badram 0x000000008c4e0800,0xffffffffffffcfe0

(They got no response from GRUB devs)

GRUB_BADRAM="0x00000000b3a9feec,0xfffffffffffffffc"

And after that change, I don't even get to Grub boot screen. When it's supposed to show up, computer just hangs and shows the black screen.

(They didn't manage to fix it, either)

I did all that, but the Computer that is perfectly fine and has no errors refused to boot after that GRUB_BADRAM= line addition. it never boots and gives no menu at al.

(The GRUB badram argument failed on two different computers for them...)

... I can't tell if there might be any relation between these patterns that make them bad, or if GRUB badram just plain doesn't work with 64bit addresses, since I couldn't find any positive "works for me" reports.
(Those all boiled down to people using Linux memmap= format or Linux memtest= kernel parameters, instead.)

Finally, I found one more person who seems to have had success with badram... using 32bit address notations (on a 64bit machine) ?

So I'm going to try that next.

1 Answer 1

1

While I didn't really find an answer as to why, since I can't grok that GRUB source code, I'm quite certain now that GRUB 2's badram command is just broken for 64 bit address space.

So this information is for anyone else, who may be going down this rabbit hole.
(tl;dr: badram is unusable! Use Linux' memmap= kernel pattern instead.)

After applying a grub commandline of badram 0xac4d96c0,0xfffffff8, what I am seeing in Linux' e820 memory map is fragmentation like this (sorry, SE doesn't have colored diff hilighting):

--- 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

The big chunk of usable memory got fragmented by lots of small regions, which I guess means the passed address mask of 0xfffffff8 that we gave GRUB is, quite logically, 0x00000000fffffff8 in 64-bit space.

The kernel then goes on to log about mapping all these "unusable" holes out of system ram as RAM buffers, which should make the pattern even more obvious:

[    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]

So we actually reserved the space from 0xac4d9000 to 0xac4d9fff...
That's our 0xac4d96c0 badram address, aligned on the lower boundary and then punched out as a nice 4KB kernel-pagesize hole around our tiny bit error.
(Imagine, if you want, someone getting rid of a spider on the wall by putting a hole around it with a cannonball. Clearly takes care of the problem, indeed.)

...and then we went on to punch holes reserve space of the same size at 0x1ac4d9000, 0x2ac4d9000, 0x3ac4d9000... up until we run out of system ram.
(Now that looks like a cannonball launcher with some spray to it!)

But all these are small holes, and the wall is big, so everything could be fine, indeed. However, what if our badram pattern is actually a lot larger than in this case? Or worse, Memtester gives us a whole bunch of places to avoid? Then this issue just turns our memory map into a sieve!

So don't use GRUB badram on 64bit systems, unless you know what you're doing.

Instead, a perfectly good replacement option on Linux is using the memmap= commandline parameter. Incidentially, that also allows you to punch smaller holes than the 4KB blocks GRUB would generate, and also works with other bootloaders like EFIStub. (Another option could be to somehow pass the kernel your own, modified, e820 memory map -- but if you know how to do that you'll probably not be reading this.)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .