0

私は現在、ACPI テーブルと接続したい単純なカーネルを開発しています。

ただし、私のコードは仮想マシン、つまり Bochs でのみ機能するようですが、これまでに試したすべての実際のハードウェア (2003 年から 2011 年までのハードウェア) では、RSDP は明らかに無効なルート システム記述子テーブルを指しています。

Bochs の画面は次のとおりです。すべての記述子テーブルが見つかったことに注意してください。

ここに画像の説明を入力

特に以下はかなり古い AMD Athlon64 プラットフォームですが、BIOS は 2003 年のものなので、v1 ACPI リビジョンを完全にサポートする必要があります。

ここに画像の説明を入力

また、2010 年と 2011 年のラップトップで検出プログラムを実行しようとしましたが、どちらも有効なルート システム記述子ポインターを提供しましたが、ポインターはヌル メモリ、メモリがいっぱい、0xFFまたは単にジャンクのいずれかを指していました。


最初の明らかな可能性は、初期化されていないレジスタの可能性です。これは、電源投入時に Bochs がすべてのレジスタをゼロに初期化するためですが、実際のハードウェアでは常に同じことが言えるとは限りません。ただし、これらのフォーラムに質問を投稿するのに十分な回数、この可能性を確認しました。

また、2002 年頃の古い Linux カーネル メーリング リスト メッセージをいくつか見つけました。ポスターには、画像で実行されている PC と同様のノースブリッジがありました。それらは上記の PC と同じ RSDT アドレスを持っていました。これにより、RSDP が間違っていないことがさらに保証されます。

チェックサムも有効で (下位 eax (AX) レジスタで合計が 0 になります)、リーダーはこれを追加でチェックできます。

また、おそらくメモリ領域を印刷する私のルーチンは初期化されていない値で動作し、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 に答える