c-操作系统如何获得x86 PC的内存映射,尽管有几个芯片集



第一:这个问题在这里有重复:

像Windows或Linux这样的现代操作系统是如何知道芯片组特定的内存映射的?

但这个问题的答案是关于设备树和ACPI(对于传统pc),没有详细信息。我需要编写一个汇编或c代码来利用ACPI表中的信息,我现在正试图首先了解传统pc以及如何解码ACPI的表,我试着做了一些搜索,我发现最重要的表是DSDT,现在我的问题是如何解码表中的信息以获得详细的内存映射(范围),以及获取哪些设备连接到CPU,以及如何获取内存中DSDT的地址,我试着做了一些搜索,但我听不懂AML语言,我认为这与这个主题有关如果有人详细说明并为初学者提供理解ACPI表和解码它们的好材料,我会很有帮助,对我来说,问题是我脑子里没有一个标准的固定内存映射,因为我想知道同一个操作系统版本是如何在不同的芯片组上运行的,必须有一种动态的方法来检测整个映射,因此,获取整个地图的建议过程也是我的另一个问题

还请注意,这是我学习如何分别与裸金属硬件设备直接通信的第一步(这是第二步)

感谢

让我们把它分成3个不同的问题。

如何获取内存中DSDT的地址

固件提供指向(一个或两个)ACPI表的指针,ACPI表包含所有其他表的索引。这些表是RSDT(根系统描述符表)和XSDT(扩展根系统描述符表);它们之间唯一真正的区别是XSDT支持64位地址(如果可能的话应该使用),而较旧的RSDT不支持(应该被认为是"不推荐使用的",并且只用作现代64位操作系统的后备)。这些表主要提供所有其他表的标识符和地址;因此,如果你想找到一个特定的表(例如DSDT),你可以在索引中搜索标识符(例如4个ASCII字符"DSDT"),并找到包含表物理地址的条目。

指向索引的指针包含在一个称为RSDP(根系统描述指针)的特殊结构中;这对于不同类型的固件以不同的方式找到。对于BIOS,你必须搜索物理内存的几个特定区域,以寻找一个特殊的结构(具有特殊的签名和有效的校验和);对于UEFI,您只需询问固件(并避免"缓存冲击"搜索)。

这全部(相对清楚地)由ACPI规范描述,包括如何找到RSDT(例如"根系统描述指针(RSDP)"部分),包括所有结构和表格的格式,以及所有字段的含义和用途。

如何解码DSDT中的信息

因为启动后情况可能会发生变化(由于热插拔支持等);静态表不能用于某些事情,ACPI通过定义一种名为ASL(ACPI汇编语言)的特殊语言来解决这个问题(并产生更多问题),该语言被编译成一种名为AML(ACPI机器语言)的可移植字节码。

DSDT包含此AML。

为了理解这一点,您需要一名AML口译员来执行DSDT中包含的AML。

这是";非常具有挑战性"-你可能需要花费数月的时间来研究ACPI规范(以及数年的时间来解决不同计算机中的错误)。大多数人移植一个称为ACPICA的开源实现(最初由英特尔创建)(请参阅https://acpica.org/)。

可悲的是;能够执行AML只是第一步。你还需要了解ACPI的名称空间,AML提供了哪些函数/方法,以及它们应该做什么;ACPI的AML希望被告知操作系统是什么,然后启用/禁用各种功能并改变其行为以适应操作系统(取决于它被告知操作系统是谁);通常,AML识别的唯一操作系统是Windows版本,如果你告诉它其他东西,它会禁用各种功能,所以大多数操作系统只是撒谎说它们是Windows版本的,这样AML就不会提供其功能的一个子集。然而"每个版本的Windows所做的";(以及AML在每个特定版本的Windows中的表现)是一场可怕的未记录(根据ACPI的规范)的灾难。幸运地ACPICA也隐藏了这种痛苦的大部分(对于移植ACPICA的人来说)。

如何获取详细的内存映射(范围)以及哪些设备连接到CPU

大多数情况下你不会。具体来说,你不只是";得到一个详细的记忆图";一步到位。

相反;首先,您可以从固件(从BIOS的int 0x15, eax=0xE820或UEFI的GetMemoryMap())获取有关物理内存的一些最小信息。然后,您可以使用各种不同的源为该最小信息添加更多细节,包括但不限于CPUID指令(用于物理地址实际具有多少位)、ACPI";APIC/MADT";表(用于IO APIC和本地APIC地址);EDT/HPET";表(用于HPET地址);MCFG";表(用于PCI Express存储器映射的配置空间区域的地址)、ACPI";SRAT";表(用于存储区域的NUMA信息和"热插拔RAM"信息),以及可能的(可选的)SMBIOS表(如果您关心安装了什么类型的RAM等)。

在从静态/不变的来源获得您想要的所有信息之后;你切换到";阶段2";,这涉及到持续管理存储器映射,并在发现来自各种设备的信息时(并通过热插拔事件进行修改)尝试使其保持最新。这就是能够执行AML(从DSDT,使用AML翻译)变得重要的地方。它还涉及特定于总线的方法(例如,扫描PCI总线并从每个PCI设备的BAR/基本地址寄存器中提取信息)。

请注意,这不仅仅是为了填充内存映射的细节。最好将其视为发现设备使用的资源,包括IO端口、IRQ线路、DMA通道(而不仅仅是物理地址空间的区域)。

还要注意的是,只有当你有一个设备驱动程序能够使用信息";驱动器";设备。如果你不这样做,那么你拥有的记忆地图只会说";"保留";你不知道为什么,但你可能没有理由在乎为什么。

最终票据

这是";非常令人生畏的";乍一看。不要担心——你可以(也应该)从小处着手,忽略大部分,直到很久以后。仅从固件中,您就可以使用关于物理内存的最小信息做很多事情;并添加代码,以便在某一天对您的操作系统真正重要时执行几乎所有其他操作。

最新更新