首页 > 解决方案 > 使用 BIOS int 0x15/E820 查看内存映射

问题描述

我在 x86 上做一些裸机编程。我处于 16 位模式并使用 qemu 进行模拟...我使用 int 0x15/ax = 0xE820 查看内存映射...使用 qemu 监视器(检查我编写映射的区域)我得到以下信息关于内存映射:

Start=0 Length= 0x9fc00 (type 1)
Start=0x9fc00 Length= 0x400 (type 2) 
Start=0xf0000 Length= 0x10000 (type 2)
Start=0x100000 Length= 0x7ee0000 (type 1)
Start=0x7fe0000 Length= 0x10000 (type 2)
Start=0xfffc0000 Length = 0x40000 (Type 2)

那么,不在此映射中的段(例如 0xA0000)是否属于 MMIO 之类的东西?我知道 BIOS 等使用类型 2 内存区域。(开始 = 0x9fc00 长度 = 0x400(类型 2)是 EDBA)当我写入这些区域时会发生什么?

注意:我没有类型 3(ACPI) 可能是因为我使用的是 qemu。在真正的硬件中,我很可能也应该获得类型 3 区域。那也是RAM吗?

标签: memorybiosmemory-managementacpix86

解决方案


此 BIOS 调用在 INT 15h, AX=E820h - Query System Address Map中进行了充分描述,在“假设和限制”部分中对此进行了说明:

  1. BIOS 将返回描述基板内存和与该基板内存相邻的 ISA 或 PCI 内存的地址范围。
  2. BIOS 不会返回 PCI 设备、ISA Option ROM 和 ISA 即插即用卡的内存映射的范围描述。这是因为操作系统具有可用于检测它们的机制。
  3. BIOS 将返回未被设备使用的芯片组定义的地址空洞作为保留。
  4. 为基板内存映射的 I/O 设备(例如 APIC)定义的地址范围将作为保留返回。
  5. 所有出现的系统 BIOS 都将被映射为保留。这包括低于 1 MB、16 MB(如果存在)和地址空间末尾(4 gig)的区域。
  6. 不会报告标准 PC 地址范围。此函数将不描述 A0000 到 BFFFF 物理上的示例视频内存。从 E0000 到 EFFFF 的范围是特定于基板的,并将报告为适合 bas 板。
  7. 所有较低内存都报告为正常内存。操作系统负责处理为特定用途保留的标准 RAM 位置,例如:中断向量表 (0:0) 和 BIOS 数据区 (40:0)。

Wikipedia 文章 Detecting Memory (x86) 在其“BIOS 功能:INT 0x15,EAX = 0xE820”部分添加了以下规则:

  • 获得列表后,可能需要:对列表进行排序,合并相同类型的相邻范围,将任何重叠区域更改为最严格的类型,并将任何无法识别的“类型”值更改为类型 2。
  • 类型 3“ACPI 可回收”内存区域可以像(并与)普通“可用 RAM”区域一样使用,只要您使用完存储在那里的 ACPI 表(即可以“回收”)。
  • 类型 2、4、5(保留、ACPI 非易失性、坏)标记分配物理内存时应避免的区域。
  • 将未列出的区域视为类型 2 - 保留。
  • 您的代码必须能够处理不在任何类型的“页面边界”上开始或结束的区域。

结论:在地图中找不到的范围是功能性的,可能被视频等设备内存占用。


推荐阅读