2016-10-05 25 views
0

我目前正在開發一個簡單的內核,我想與ACPI表進行交互。但是,我的代碼似乎只適用於虛擬機,即Bochs,而在迄今爲止我嘗試過的所有實際硬件(硬件範圍從2003到2011)中,RSDP指向顯然無效的根系統描述符表。內核環境:RSDP指向無效的RSDT

這是來自Bochs的屏幕:注意找到所有描述符表。

enter image description here

的特別下面是一個無可否認的,而舊AMD的Athlon64平臺,但是BIOS從2003過時,所以就我而言,它應該有充分的支持ACPI V1修訂。

enter image description here

我也試過從2010年和2011年,兩者也給了我一個有效的根系統描述符指針在筆記本電腦上運行我的檢測程序,但指針指向爲null內存,內存充滿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

你確定你沒有絆倒A20?這最初不同於Bochs AFAIK – tofro

+3

中的真實情況。是的,我同意tofro。如果在BIOS調用引導扇區時未啓用A20(我知道大多數實際硬件都是這種情況),當您訪問的內存地址位於奇數兆字節區域時,您實際上正在讀取內存低一兆字節的數據。 0x3FFF3000在奇數兆字節範圍內,所以會從0x3FEF3000讀取。我認爲BOCHS在大多數版本中都啓用了A20,但如果您從源代碼重新編譯BOCHS,則可以將其關閉。從技術上講,大多數386將啓動啓用A20,但然後在將控制權交給引導加載程序之前,BIOS禁用它。 –

+0

大多數Linux發行版都有一個名爲'acpidump'的程序。要麼查看源代碼(GPL,所以你可能不希望出於法律原因)或者至少檢查表中的實際內容。我沒有那個時代的硬件(不管是更現代的還是更古老的)來檢查我自己,但是輸出看起來並不怎麼樣。 – deamentiaemundi

回答

2

你的問題可能是(顯然)未啓用A20。大多數real硬件以這種方式啓動,而不是標準的Bochs啓動。

如果未啓用A20,您將從其他地址閱讀的內容超出您的想象(請參閱Michael的評論)。