memory - 使用 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吗?
解决方案
此 BIOS 调用在 INT 15h, AX=E820h - Query System Address Map中进行了充分描述,在“假设和限制”部分中对此进行了说明:
- BIOS 将返回描述基板内存和与该基板内存相邻的 ISA 或 PCI 内存的地址范围。
- BIOS 不会返回 PCI 设备、ISA Option ROM 和 ISA 即插即用卡的内存映射的范围描述。这是因为操作系统具有可用于检测它们的机制。
- BIOS 将返回未被设备使用的芯片组定义的地址空洞作为保留。
- 为基板内存映射的 I/O 设备(例如 APIC)定义的地址范围将作为保留返回。
- 所有出现的系统 BIOS 都将被映射为保留。这包括低于 1 MB、16 MB(如果存在)和地址空间末尾(4 gig)的区域。
- 不会报告标准 PC 地址范围。此函数将不描述 A0000 到 BFFFF 物理上的示例视频内存。从 E0000 到 EFFFF 的范围是特定于基板的,并将报告为适合 bas 板。
- 所有较低内存都报告为正常内存。操作系统负责处理为特定用途保留的标准 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 - 保留。
- 您的代码必须能够处理不在任何类型的“页面边界”上开始或结束的区域。
结论:在地图中找不到的范围是功能性的,可能被视频等设备内存占用。
推荐阅读
- r - 如何在ggplot2中自定义中间值和最大值的颜色?
- ms-access - 将多个CSV文件导入Access数据库并根据文件名将它们保存到不同的表中
- android - android 的 GeoCoder 类中的 Context 表示什么?地理编码器 coder = new Geocoder(context);
- angular - 如何在 Ionic 3(Ionic、Angular 5)上刷新页面
- excel - 使用 Documents.Open 的宏不返回文档,而是返回字符串。
- mysql - 在 MySQL 中动态制作复杂的折叠
- azure-devops - 构建或测试失败后的 vsts 详细通知
- ios - 金属着色器 3D 纹理查找
- c# - 从 C# 读取注册表项
- php - 我的浏览器返回我的 PHP 代码?