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



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

简单地说,你不能。

mem_lowermem_upper是过时的字段,指的是常规内存和扩展内存。
引用规格:

如果flags字中的位 0已设置,则mem_*字段有效。
mem_lowermem_upper分别表示下层和上层内存量,以千字节为单位。

下内存从地址 0 开始,上内存从地址 1兆字节mebibyte 开始。较低内存的最大可能值为 640KB千字节。

为上层内存返回的值最大为第一个上层内存孔的地址减去 1 兆字节兆字节。不保证是此值。

本摘录的两个关键方面是:

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

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

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

当1MiB屏障被打破(包括或不包括HMA(时,从640KiB到1MiB的范围不能用于向后兼容性。 这就创建了第一个孔:标准孔。
286只有一个24位地址总线,因此是一个16MiB地址空间。
同时,ISA总线已经战胜了MCA总线,并在IBM PC兼容硬件中进行。
一些ISA扩展卡附带扩展ROM,标准孔已耗尽,在16MiB地址空间的末尾保留了一个1MiB孔。
我称这个洞为ISA洞。
当从 32 位系统过渡到 64 位系统生成 PCI 漏洞时,PCI(e( 也发生了几乎相同的情况。

除了这些孔之外,还有一些可读/写的内存范围,但携带由 BIOS 布置的宝贵信息 - 即 ACPI 表。
操作系统不能粗心地覆盖此类范围,因此必须向其报告。

所有这些都在 e820 服务中达到高潮,它不返回内存大小(根据上面的讨论,这毫无意义(,而是返回由范围及其类型(可用、保留、可回收、坏、NVS(组成的内存映射

这也反映在 GRUBmultiboot_info_t结构字段中mmap_*您应该使用这些字段来代替 OSDev wiki 中指示的mem_lowermem_upper


1DIMM 可通过列号、列号和行号进行访问,但内存控制器通常使此寻址为线性和连续。

最新更新