0

我目前正在开发一个简单的内核,我想与 ACPI 表交互。

但是,我的代码似乎只能在虚拟机中工作,即 Bochs,而在我迄今为止尝试过的所有真实硬件(从 2003 年到 2011 年的硬件)上,RSDP 指向明显无效的根系统描述符表。

这是来自 Bochs 的屏幕:注意所有描述符表都已找到。

在此处输入图像描述

以下是一个公认的相当老的 AMD Athlon64 平台,但是 BIOS 是 2003 年的,所以就我而言,它应该完全支持 v1 ACPI 修订版。

在此处输入图像描述

从 2010 年到 2011 年,我还尝试在笔记本电脑上运行我的检测程序,两者都给了我一个有效的 Root 系统描述符指针,但该指针指向空内存、内存填充0xFF或只是垃圾。


第一个也是显而易见的可能性是未初始化的寄存器,因为 Bochs 在上电时会将所有寄存器初始化为零,而对于真实硬件而言并非总是如此。但是,我已经检查了足够多的时间来保证在这些论坛上发布问题。

我还发现了大约 2002 年的一些旧的 Linux 内核邮件列表消息,其中海报的北桥与图像中运行的 PC 相似。它们与上面的 PC 具有相同的 RSDT 地址,这进一步向我保证 RSDP 没有错。

校验和也是有效的(低 eax (AX) 寄存器中的总和为零),读者可以另外检查。

我还怀疑,也许我打印内存区域的例程使用未初始化的值,并且由于 Bochs 初始化寄存器的倾向在那里工作,而不是在硬件上 - 然而,这意味着可以观察到不稳定的、不可重现的行为,但在我测试 RSDP 指向的内存区域的每台机器始终是相同的垃圾。


由于我什至不确定在哪里寻找问题,我将应读者的要求填写其他详细信息或源代码 - 简单地将所有内容转储到这里会很不方便,并且会使阅读变得不舒服。

内核入口点:

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;
}
4

1 回答 1

2

您的问题可能是(显然是)A20 ​​未启用。大多数真正的硬件都是这样启动的,而不是标准的 Bochs 启动。

在未启用 A20 的情况下,您将从其他地址读取而不是您认为的(参见 Michael 的评论)。

于 2016-10-06T05:50:34.160 回答