内核环境:RSDP 指向无效的 RSDT
Kernel environment: RSDP points to invalid RSDT
我目前正在开发一个我想与 ACPI 表交互的简单内核。
但是,我的代码似乎只能在虚拟机(即 Bochs)中运行,而在我迄今为止尝试过的所有真实硬件(从 2003 年到 2011 年的硬件)上,RSDP 指向显然无效的根系统描述符表。
这是来自 Bochs 的屏幕:注意找到了所有描述符表。
以下是公认的相当古老的 AMD Athlon64 平台,但 BIOS 的日期是 2003 年,所以据我所知,它应该完全支持 v1 ACPI 修订版。
我还在 2010 年和 2011 年的笔记本电脑上尝试了 运行 我的检测程序,这两个程序也给了我一个有效的 Root 系统描述符指针,但该指针指向空内存,内存填充 0xFF
或者只是垃圾。
第一个明显的可能性是未初始化的寄存器,因为 Bochs 在加电时将所有寄存器初始化为零,而对于真实硬件来说并不总是这样。但是,我已经多次检查这种可能性,以保证在这些论坛上发布问题。
我还发现了一些旧的 Linux 内核邮件列表消息,来自大约 2002 年,其中发帖者有一个与图像中的 PC 运行 相似的北桥。他们的RSDT地址与上面的PC相同,这进一步让我确信RSDP没有错。
校验和也有效(在低 eax (AX) 寄存器中总和为零),reader 可以额外检查。
我还怀疑我打印内存区域的例程可能使用了一个未初始化的值,而且 Bochs 倾向于初始化寄存器在那里工作,而不是在硬件上工作——然而,这意味着不稳定的、不可重现的行为可能被观察到,但在我测试的每台机器上,RSDP 指向的内存区域始终是相同的垃圾。
因为我什至不确定在哪里寻找问题,我将根据 reader 的要求填写额外的详细信息或源代码 - 简单地将所有内容转储在这里会很不方便并且让人不舒服阅读。
内核入口点:
void __kernel_entry() {
clear_scr(0x0000);
set_cur(0, 0);
print_str("Scanning RSDP header: 0xe0000 - 0xfffff", 39);
struct RSDP_descriptor* rd = __RSDP_find_address();
if(rd) {
set_cur(0, 1); // Set cursor position
__RSDP_print(rd); // Prints the RSDP location, OEM string and the contained RSDT pointer
}
struct ACPI_SDT_header* rsdt = (struct ACPI_SDT_header*)rd->RSDT_address;
memdump((void*)rd, 5, 15);
memdump((void*)rsdt, VH-8, VH); //VH: Console height
loop:;
goto loop;
}
您的问题可能是(显然)A20 未启用。大多数 真实 硬件以这种方式启动,而不是标准的 Bochs 启动。
在未启用 A20 的情况下,您将从其他地址读取信息(请参阅 Michael 的评论)。
我目前正在开发一个我想与 ACPI 表交互的简单内核。
但是,我的代码似乎只能在虚拟机(即 Bochs)中运行,而在我迄今为止尝试过的所有真实硬件(从 2003 年到 2011 年的硬件)上,RSDP 指向显然无效的根系统描述符表。
这是来自 Bochs 的屏幕:注意找到了所有描述符表。
以下是公认的相当古老的 AMD Athlon64 平台,但 BIOS 的日期是 2003 年,所以据我所知,它应该完全支持 v1 ACPI 修订版。
我还在 2010 年和 2011 年的笔记本电脑上尝试了 运行 我的检测程序,这两个程序也给了我一个有效的 Root 系统描述符指针,但该指针指向空内存,内存填充 0xFF
或者只是垃圾。
第一个明显的可能性是未初始化的寄存器,因为 Bochs 在加电时将所有寄存器初始化为零,而对于真实硬件来说并不总是这样。但是,我已经多次检查这种可能性,以保证在这些论坛上发布问题。
我还发现了一些旧的 Linux 内核邮件列表消息,来自大约 2002 年,其中发帖者有一个与图像中的 PC 运行 相似的北桥。他们的RSDT地址与上面的PC相同,这进一步让我确信RSDP没有错。
校验和也有效(在低 eax (AX) 寄存器中总和为零),reader 可以额外检查。
我还怀疑我打印内存区域的例程可能使用了一个未初始化的值,而且 Bochs 倾向于初始化寄存器在那里工作,而不是在硬件上工作——然而,这意味着不稳定的、不可重现的行为可能被观察到,但在我测试的每台机器上,RSDP 指向的内存区域始终是相同的垃圾。
因为我什至不确定在哪里寻找问题,我将根据 reader 的要求填写额外的详细信息或源代码 - 简单地将所有内容转储在这里会很不方便并且让人不舒服阅读。
内核入口点:
void __kernel_entry() {
clear_scr(0x0000);
set_cur(0, 0);
print_str("Scanning RSDP header: 0xe0000 - 0xfffff", 39);
struct RSDP_descriptor* rd = __RSDP_find_address();
if(rd) {
set_cur(0, 1); // Set cursor position
__RSDP_print(rd); // Prints the RSDP location, OEM string and the contained RSDT pointer
}
struct ACPI_SDT_header* rsdt = (struct ACPI_SDT_header*)rd->RSDT_address;
memdump((void*)rd, 5, 15);
memdump((void*)rsdt, VH-8, VH); //VH: Console height
loop:;
goto loop;
}
您的问题可能是(显然)A20 未启用。大多数 真实 硬件以这种方式启动,而不是标准的 Bochs 启动。
在未启用 A20 的情况下,您将从其他地址读取信息(请参阅 Michael 的评论)。