如何检测或探测或扫描 usable/accessible 物理内存?

How to detect or probe or scan usable/accessible physical memory?

如何彻底检测或探测或扫描 usable/accessible 物理内存?

我目前正在 NASM 中为 x86_64 自定义操作系统制作自定义引导加载程序。

为了分配哪个物理地址包含哪些数据,我想确保内存可以免费使用。我已经尝试过 BIOS interrupt int 0x15 eax 0xE820 并检查了设备管理器内存资源。 问题是其中 none 个完全涵盖。

例如, 它说 0x0000000000000000 ~ 0x000000000009FC00 可用。 但是严格来说,0x0000000000000000 ~ 0x0000000000000500是不能用的,因为它存储了IVT和BDA。

此外,到处都有 PCI 孔。

我的 objective 正在检测或探测或扫描我的硬件中可用的整个内存并制作内存映射,以便我可以区分哪个地址是哪个。 (示例地图如下)

0x0000000000000000 ~ 0x00000000000003FF : Real Mode IVT
0x0000000000000400 ~ 0x00000000000004FF : BDA
...
0x0000000000007C00 ~ 0x0000000000007DFF : MBR Load Address
...
0x00000000000B8000 ~ 0x00000000000B8FA0 : VGA Color Text Video Memory
...
0x00000000C0000000 ~ 0x00000000FFFFFFFF : PCI Space

我的处理器是 intel i7-8700K 8th gen.

你想要多少信息?

如果你只想知道哪些区域是可用的RAM;然后 "int 0x15, eax=0xE820"(限制 BDA 将被视为可用)或 UEFI 的 "get memory map" 功能,就是您所需要的。请注意,对于这两种情况,one/some 区域可能会报告为 "ACPI reclaimable",这意味着在您完成解析 ACPI table 之后(或者如果您不关心 ACPT tables) RAM 将可用。

如果你想要更多的信息,你需要做更多的工作,因为信息分散在各处。具体来说:

  • ACPI 的 SRAT table 描述了哪些事物(例如内存的哪些区域)在哪个 NUMA 域中; ACPI 的 SLIT table 描述了它对性能的影响。

  • ACPI 的 SRAT table 还描述了哪些东西(例如内存的哪些区域)是 "hot plug removable" 并为 "hot insert".

  • CPU的CPUID指令会告诉你"physical address size in bits"。这有助于了解 if/when 您正在尝试查找物理地址 space 的 suitable 区域以用于内存映射 PCI 设备的 BAR,因为您获得的内存映射是太傻了,没法告诉你 "not usable by memory mapped PCI devices"、"usable by memory mapped PCI devices" 和 "used by memory mapped PCI devices" 之间的区别。

  • 解析(或配置)PCI配置space(必要时结合IOMMUs)告诉你物理地址space的哪些区域当前被哪些PCI设备使用

  • 解析"System Management BIOS"tables可以(和"heuristical fumbling"做了大量的工作)告诉你物理地址space对应的是哪些区域主板上的哪些 RAM 芯片以及这些 RAM 芯片的详细信息(类型、速度等)。

  • 各种 ACPI tables(例如 MADT/APIC 和 HPET)可用于确定各种特殊设备(本地 APIC、IO APIC、HPET)的位置。

  • 您可以假设以物理地址 0xFFFFFFFF 结束的(部分)区域将是固件的 ROM;并且(还有一些 "heuristical fumbling" 从固件内存映射报告为 "reserved" 的区域中减去任何特殊设备)您可以确定该区域的大小。

如果您完成所有这些操作,您将拥有一个相当完整的地图,其中描述了物理地址 space 中的所有内容。