RSDP
RSDP (根系统描述指针-Root System Description Pointer) 是 ACPI 编程接口中使用的数据结构。
在ACPI版本1.0中,它具有以下结构:
struct RSDPDescriptor {
char Signature[8];
uint8_t Checksum;
char OEMID[6];
uint8_t Revision;
uint32_t RsdtAddress;
} __attribute__ ((packed));
从2.0版开始,对其进行了扩展,并添加了以下新字段:
struct RSDPDescriptor20 {
RSDPDescriptor firstPart;
uint32_t Length;
uint64_t XsdtAddress;
uint8_t ExtendedChecksum;
uint8_t reserved[3];
} __attribute__ ((packed));
检测RSDP
RSDP位于EBDA(扩展BIOS数据区-Extended BIOS Data Area)的前1KB内(指向它的2字节实模式段指针位于0x40E), 或在0x000E0000到0x000FFFFF的内存区域(主BIOS区域低于1 MB)中。 要查找表,操作系统必须在两个区域之一中找到 “RSD PTR” 字符串 (注意最后一个空格字符)。 此签名始终位于16字节边界上。
如果您使用的是UEFI,您可以在EFI_SYSTEM_TABLE中的某个地方找到它。 因此,没有必要搜索内存。
注意: 查找RSDP的标准方法在UEFI系统上可能不起作用。 因此,在EFI_SYSTEM_TABLE中找到它是正确且可靠的方法 (请参阅ACPI 6.2 5.2.5.2节 “在启用UEFI的系统上查找RSDP”)。
当使用符合multiboot2的加载程序引导时,RSDP的副本分别包含在ACPI new RSDP或ACPI old RSDP标记中。
验证RSDP
找到RSDP表后,您必须查看BIOS使用的ACPI版本,然后必须检查校验和是否有效。
检测ACPI版本
可以使用RSDP中的修订字段来检测ACPI版本。 如果此字段包含0,则使用ACPI版本1.0。 对于后续版本(ACPI版本2.0至6.1),使用值2[1]. 可以通过FADT表推导出ACPI的确切版本。
校验和验证
在依赖RSDP之前,您应该检查校验和是否有效。 对于ACPI1.0(第一个结构),将结构中的每个字节相加,并确保结果的最低字节等于零。 对于ACPI 2.0及以后,您将对第二个结构的原始 (ACPI 1.0) 部分执行完全相同的操作,然后对属于ACPI 2.0扩展的部分的字段再次执行此操作。
字段解释
总是存在
签名(Signature)
此8字节字符串(非NULL终止!)必须包含“RSD PTR”。它位于16字节边界上。
校验和(Checksum)
要添加到 (版本1.0表的) 所有其他字节的值,以计算表的校验和。 如果该值加在所有其他值上并强制转换为字节不等于0,则必须忽略该表。
OEMID
规范说:“OEM提供的标识OEM的字符串”。
修订版(Revision)
ACPI的修订。较大的修订编号向后兼容较低的修订编号。有关更多信息,请参见 检测ACPI版本。
Rsdt地址
RSDT表的32位物理(重复一遍:物理)地址。
从2.0版开始
长度(Length)
从偏移0到末尾的整个表的大小。
Xsdt地址
XSDT表的64位物理地址。如果检测到ACPI 2.0版,即使在IA-32上,也应该使用此表而不是RSDT,将地址强制转换为uint32_t。
扩展校验和(Extended Checksum)
This field is used to calculate the checksum of the entire table, including both checksum fields.
保留
3 bytes to be ignored in reading and that must not be written.