2

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

4

1 回答 1

7

简单地说,你不能。

mem_lower和是过时的mem_upper字段,指的是常规内存扩展内存
引用规格

如果设置了字中的位 0flags,则mem_*字段有效。
mem_lowermem_upper分别以千字节千比字节表示低位和高位内存的数量。

低位存储器从地址 0 开始,高位存储器从地址 1兆字节开始。较低内存的最大可能值为 640 KB

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

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

  1. flags在访问字段之前需要对该字段进行测试mem_*
  2. mem_lowerand字段对内存漏洞的mem_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(e) 发生了几乎相同的事情,生成PCI 孔

除了这些漏洞之外,还有一些内存范围是可读/可写的,但会携带由 BIOS 布置的宝贵信息——即ACPI 表
此类范围不能被操作系统随意覆盖,因此必须向其报告。

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

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


1 DIMM使用rank、bank、列和行号进行访问,但内存控制器通常使这种寻址成为线性和连续的。

于 2017-08-07T14:44:20.270 回答