从 GRUB2 多重引导信息结构中获取总可用 RAM

Get total avaiable RAM from the GRUB2 multiboot info structure

我设法访问了我的 i386 内核中的 GRUB 多重引导信息结构 (multiboot_info_t),其中有两个字段分别称为 mem_lowermem_upper。我如何使用它们来获取总可用 RAM(以字节为单位)?

简单地说,你不能。

mem_lowermem_upper是废弃字段,参考conventional memory and the extended memory
引用 specifications:

If bit 0 in the flags word is set, then the mem_* fields are valid.
mem_lower and mem_upper indicate the amount of lower and upper memory, respectively, in kilobytes kibibytes.

Lower memory starts at address 0, and upper memory starts at address 1 megabyte mebibyte. The maximum possible value for lower memory is 640 kilobytes kibibytes.

The value returned for upper memory is maximally the address of the first upper memory hole minus 1 megabyte mebibyte. It is not guaranteed to be this value.

这段摘录的两个关键方面是:

  1. 在访问mem_*字段之前需要测试flags字段。
  2. mem_lowermem_upper字段对内存空洞的处理非常糟糕。特别是 mem_upper 保存扩展内存的第一个连续块的大小,直到第一个孔。

第二点很重要,值得进一步讨论。
虽然可以访问内存本身,但在内存控制器级别 1,作为一个连续的块,它在内存子系统级别(曾经是 north-bridge and now is the uncore)是不连续的。
内存子系统在分配给内存的连续地址范围内创建 holes,方法是简单地不回收特定的子范围——从而浪费该内存——或者通过将子范围移动到更高的地址。

这种看似奇怪的行为背后的原因深深植根于 IBM PC 的历史演变。
完整的讨论超出了主题,但可以列出一个简短的版本。 最初,IBM 保留了 1MiB 地址 space 的前 640KiB 用于常规内存,其余 384KiB 用于映射 ROM - 包括 BIOS ROM。
请注意,内存控制器不得响应超过 640KiB 的 read/write 访问,以便它们访问 ROM。

当 1MiB 障碍被打破时(随意包括或不包括 HMA),从 640KiB 到 1MiB 的范围不能用于向后兼容。 这创建了第一个孔:标准孔。
286 只有一个 24 位地址总线,因此一个 16MiB 地址 space.
同时,ISA bus had already won against the MCA bus又发生在IBM PC兼容硬件上。
一些ISA扩展卡自带扩展ROM,标准孔用完了,16MiB地址末尾预留了1MiB孔space.
我称这个洞为 ISA hole.
从 32 位系统过渡到 64 位系统时,PCI(e) 发生了几乎相同的事情,生成了 PCI hole

除了这些漏洞之外,还有 read/writable 的内存范围,但携带了 BIOS 布置的宝贵信息 - 即 ACPI tables.
这样的范围不能被 OS 不小心覆盖,因此必须向它报告。

所有这一切都在 e820 service 中达到顶峰,而不是返回内存大小(根据上面的讨论,这是没有意义的)它 returns 一个 内存映射 由范围及其类型(可用、保留、可回收、不良、NVS)组成。

这也反映在 GRUB multiboot_info_t 结构字段 mmap_* 中,您应该使用它来代替 [=35] 中指示的 mem_lowermem_upper =].


1 DIMMs 是通过等级、库、列和行号访问的,但内存控制器通常使此寻址线性且连续。