In efi_memprobe_internal(), there's this bit working around the 640kB - 1MB memory hole:
for (bm = bios_memmap; bm->type != BIOS_MAP_END; bm++) {
if (bm->addr < 0x0a0000) /* Below memory hole */
cnvmem = max(cnvmem, (bm->addr + bm->size) / 1024);
if (bm->addr >= 0x10000 /* Above the memory hole */ &&
bm->addr / 1024 == extmem + 1024)
extmem += bm->size / 1024;
}
The second address check is wrong; it should be 0x100000 (1MB), not
0x10000 (64kB). Diff attached.
Since this logic seems roughly equivalent to that in memprobe() from
libsa/memprobe.c, which uses the IOM_BEGIN and IOM_END defines, I also
used IOM_{BEGIN,END} instead of hardcoding the addresses.
This led me to diff libsa/memprobe.c between i386 & amd64, and I
noticed that the i386 one lacks the '&& (im->addr/1024) == (extmem +
1024)' part. It was apparently added to amd64 in this commit:
c75862c439a Sat May 28 05:47:33 2005 +0000 weingart *slightly drunk*
[Sorry, I'd find the CVS revision, but cvsweb is currently down for me.]
The i386 memprobe also lacks the limiting extmem to 4GB check (added
in the same commit), but I assume it's not needed there?
I'll leave deciding if either of those should be copied to i386 to
someone smarter... I know just enough to know that i386 memory mapping
is *weird*!
-Andrew
efiboot-mem-hole.diff
Description: Binary data
