c - 内核环境 : RSDP points to invalid RSDT

标签 c assembly kernel acpi

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

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

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

enter image description here

特别是以下是一个公认的相当古老的 AMD Athlon64 平台,但是 BIOS 的日期是 2003 年,所以据我所知,它应该完全支持 v1 ACPI 修订版。

enter image description here

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


第一个明显的可能性是未初始化的寄存器,因为 Bochs 在加电时将所有寄存器初始化为零,而真实硬件并不总是这样。但是,我已经多次检查这种可能性以保证在这些论坛上发布问题。

我还发现了大约 2002 年的一些旧 Linux 内核邮件列表消息,其中发帖人与图片中运行的 PC 有类似的北桥。它们的 RSDT 地址与上面的 PC 相同,这进一步使我确信 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;
}

最佳答案

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

在未启用 A20 的情况下,您将从其他地址读取信息(请参阅 Michael 的评论)。

关于c - 内核环境 : RSDP points to invalid RSDT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39884089/

相关文章:

c - scanf: "%[^\n]"跳过第二个输入但 "%[^\n]"没有。为什么?

c - X11 如何使用 xcb 恢复/启动另一个应用程序窗口?

c - 使用 C 初始化、读写 linux 串口设备

linux - 在回收之前写入缓存页面

windows - 为 Microsoft Windows 编写内核的基本要求是什么

c++ - C扩展一个指针数组

macos - 插入 64 位英特尔 osx

gcc - GCC 内置向量化类型和 C 数组之间有什么区别?

assembly - intel机器码转汇编代码的问题

linux - 内核-网络, "private"结构的作用