之前介绍过在 Shell 下面查看 ACPI Table 的工具,例如【参考1】提到的:ACPIView。
接下来的问题就是:上面的这个 DSDT 是从哪里来的?
首先,在代码中找了一圈,竟然一无所获;接下来在Debug Log中查找,发现如下信息,其中的一个 Table 长度是 0x1772(6002)非常接近我们在 Shell 下看到的 6009。
ProcessCmdAllocate: File="etc/acpi/tables" Alignment=0x40 Zone=1 Size=0x20000 Address=0x7BDE000
ProcessCmdAddChecksum: File="etc/acpi/tables" ResultOffset=0x49 Start=0x40 Length=0x1772
ProcessCmdAddPointer: PointerFile="etc/acpi/tables" PointeeFile="etc/acpi/tables" PointerOffset=0x17D6 PointerSize=4
ProcessCmdAddPointer: PointerFile="etc/acpi/tables" PointeeFile="etc/acpi/tables" PointerOffset=0x17DA PointerSize=4
ProcessCmdAddChecksum: File="etc/acpi/tables" ResultOffset=0x17BB Start=0x17B2 Length=0x74
ProcessCmdAddChecksum: File="etc/acpi/tables" ResultOffset=0x182F Start=0x1826 Length=0x78
……………….
Process2ndPassCmdAddPointer: checking for ACPI header in "etc/acpi/tables" at 0x7BDE000 (remaining: 0x20000): found "FACS" size 0x40
Process2ndPassCmdAddPointer: checking for ACPI header in "etc/acpi/tables" at 0x7BDE040 (remaining: 0x1FFC0): found "DSDT" size 0x1772
Process2ndPassCmdAddPointer: checking for ACPI header in "etc/acpi/tables" at 0x7BDF7B2 (remaining: 0x1E84E): found "FACP" size 0x74
Process2ndPassCmdAddPointer: checking for ACPI header in "etc/acpi/tables" at 0x7BDF826 (remaining: 0x1E7DA): found "APIC" size 0x78
Process2ndPassCmdAddPointer: checking for ACPI header in "etc/acpi/tables" at 0x7BDF89E (remaining: 0x1E762): found "HPET" size 0x38
Process2ndPassCmdAddPointer: checking for ACPI header in "etc/acpi/tables" at 0x7BDF8D6 (remaining: 0x1E72A): found "WAET" size 0x28
这一段 Log 对应的代码在\OvmfPkg\AcpiPlatformDxe\QemuFwCfgAcpi.c 中。
为了验证猜想,在对应代码中加入调试信息,输出读取到QEMU 的 ACPI DSDT,具体在OvmfPkg\AcpiPlatformDxe\QemuFwCfgAcpi.c,修改如下:
Blob2Remaining -= (UINTN) PointerValue;
DEBUG ((DEBUG_INFO, "%a: checking for ACPI header in \"%a\" at 0x%Lx "
"(remaining: 0x%Lx): ", __FUNCTION__, AddPointer->PointeeFile,
PointerValue, (UINT64)Blob2Remaining));
TableSize = 0;
//
// To make our job simple, the FACS has a custom header. Sigh.
//
if (sizeof *Facs <= Blob2Remaining) {
Facs = (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)PointerValue;
//LABZDebug_Start
if ((Facs->Signature==EFI_ACPI_1_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)) {
DEBUG ((DEBUG_INFO,"DSDt found\n"));
p = (CHAR8*)(Facs);
//p=p+sizeof(EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE);
for (i=0;i<32;i++) {
DEBUG ((DEBUG_INFO,"%x ",p[i]&0xFF));
}
}
// LABZDebug_End
if (Facs->Length >= sizeof *Facs &&
Facs->Length <= Blob2Remaining &&
Facs->Signature ==
EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {
DEBUG ((DEBUG_INFO, "found \"%-4.4a\" size 0x%x\n",
(CONST CHAR8 *)&Facs->Signature, Facs->Length));
TableSize = Facs->Length;
}
}
输出结果如下:
Process2ndPassCmdAddPointer: checking for ACPI header in "etc/acpi/tables" at 0x7BDE000 (remaining: 0x20000): found "FACS" size 0x40
Process2ndPassCmdAddPointer: checking for ACPI header in "etc/acpi/tables" at 0x7BDE040 (remaining: 0x1FFC0): DSDt found
44 53 44 54 72 17 0 0 1 9E 42 4F 43 48 53 20 42 58 50 43 20 20 20 20 1 0 0 0 42 58 50 43 Process2ndPassCmdAddPointer: checking for ACPI header in "etc/acpi/tables" at 0x7BDF7B2 (remaining: 0x1E84E): Process2ndPassCmdAddPointer: checking for ACPI header in "etc/acpi/tables" at 0x7BDF826 (remaining: 0x1E7DA): Process2ndPassCmdAddPointer: checking for ACPI header in "etc/acpi/tables" at 0x7BDF89E (remaining: 0x1E762): Process2ndPassCmdAddPointer: checking for ACPI header in "etc/acpi/tables" at 0x7BDF8D6 (remaining: 0x1E72A): Process2ndPassCmdAddPointer: checking for ACPI header in "etc/acpi/tables" at 0x7BDF8FE (remaining: 0x1E702): InstallQemuFwCfgTables: installed 6 tables
PcRtc: Write 0x20 to CMOS location 0x32
可以看到这个结果和ACPIViewApp Dump 出来的 DSDT 结果是相同的:
就是说:QEMU的 ACPI 来自虚拟机内部。
参考: