私は現在、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;
}