您當前的位置:首頁 > 舞蹈

用Rust寫作業系統(三)——問題彙總

作者:由 GMN23362 發表于 舞蹈時間:2020-12-19

1。 在CPU異常部分,剛剛加入lib和interrupts模組就編譯出錯。

用Rust寫作業系統(三)——問題彙總

錯誤原因:需要先完成Testing部分。

1) 在Rust中測試

• 當我們嘗試在我們的專案中執行cargo test,我們可以看到:

用Rust寫作業系統(三)——問題彙總

• 為了實現核心的自定義測試框架,我們在main。rs中添加了以下內容。

當我們現在執行cargo test時,我們看到它現在成功了。但是,我們仍然看到我們的“Hello World”,而不是來自test_runner的訊息。原因是我們的_start函式仍然用作入口點。自定義測試框架特性生成一個呼叫test_runner的主函式,但是這個函式被忽略了,因為我們使用了#[no_main]屬性並提供了我們自己的入口點。

• 要解決這個問題,我們首先需要透過reexport_test_harness_main屬性將生成的函式的名稱更改為與main不同的名稱。然後我們可以從_start函式中呼叫重新命名的函式。

• 現在執行cargotest時,我們會在螢幕上看到來自test_runner的“Running 0 tests”訊息。現在我們準備建立第一個測試函式。

• 現在執行cargo test時,我們看到以下輸出。

2) 退出QEMU

• QEMU支援一種特殊的isa-debug-exit,它提供了一種從客戶系統退出QEMU的簡單方法。要啟用它,我們需要向QEMU傳遞一個-device引數。我們可以透過新增package。metadata。bootimage來做到這一點。測試args配置鍵在我們的Cargo。toml。

• 我們使用x86_64包提供的抽象,而不是手動呼叫in和out組裝指令。要在這個包上新增一個依賴項,我們將它新增到我們的Cargo。toml中的依賴項部分。

• 現在我們可以使用包提供的埠型別來建立exit_qemu函式。

• 我們現在可以在所有測試執行後更新test_runner以退出QEMU:

• 現在執行cargo test時,我們會看到QEMU在執行測試後立即關閉。問題是cargo test解釋測試失敗,即使我們通過了我們的成功退出程式碼。

問題是,cargo test認為除了0以外的所有錯誤程式碼都是失敗的。

• 為了解決這個問題,bootimage提供了一個test-success-exit-code配置鍵,它將指定的退出程式碼對映到退出程式碼0。

3) 列印到控制檯

• 我們將使用uart_16550包來初始化UART並透過串列埠傳送資料。要將其作為依賴項新增,我們需要更新我們的Cargo。toml和main。rs。

• uart_16550 crate包含一個表示UART暫存器的SerialPort結構體,但是我們仍然需要自己構造它的例項。為此,我們建立一個新的串列埠模組,其內容如下。

• 為了使串列埠易於使用,我們新增serial_print!和serial_println !宏。

• 現在我們可以列印到串列埠,而不是在我們的測試程式碼中的VGA文字緩衝區。

• 要檢視QEMU的序列輸出,我們需要使用-serial引數將輸出重定向到stdout。

• 當我們現在執行cargo test時,我們可以在控制檯中直接看到測試輸出。

• 要退出QEMU並在panic狀態下出現錯誤訊息,我們可以使用條件編譯在測試模式下使用不同的panic處理器。

• 現在,如果測試失敗,QEMU也會退出,並在控制檯上列印一條有用的錯誤訊息。

• 由於我們使用isa-debug-exit裝置和串列埠報告完整的測試結果,所以我們不再需要QEMU視窗。我們可以透過傳遞-display none引數到QEMU來隱藏它。

• 您可以自己嘗試在trivial_assertion測試中新增loop{}語句。當您執行cargo test時,您會看到測試在5分鐘後被標記為超時。超時持續時間可透過Cargo。toml的測試超時鍵配置。

• trivial_assertion測試目前需要使用serial_print!/serial_println!列印它自己的狀態資訊。

• 為我們編寫的每個測試手動新增這些列印語句非常麻煩,所以讓我們更新test_runner以自動列印這些訊息。為此,我們需要建立一個新的可測試特性。

• 現在的技巧是為實現Fn()特徵的所有型別T實現這個特徵:

• 最後一步是更新test_runner以使用新的可測試特性。

• 我們現在可以從trivial_assertion測試中刪除列印語句,因為它們現在是自動列印的。

• cargo test輸出現在如下所示。

4) 測試VGA緩衝區

• 現在我們有了一個工作的測試框架,我們可以為VGA緩衝區實現建立一些測試。首先,我們建立一個非常簡單的測試來驗證println是否能正常工作而不會產生恐慌。

• 為了確保即使列印了許多行並將行移出螢幕,也不會發生恐慌,建立另一個測試。

• 我們還可以建立一個測試函式來驗證列印的行是否真的出現在螢幕上。

5) 整合測試

• 所有整合測試都是它們自己的可執行程式,並且完全獨立於main。rs。這意味著每個測試都需要定義自己的入口點函式。讓我們建立一個名為basic_boot的示例整合測試來詳細瞭解它是如何工作的。

• 為了使整合測試可用所需的函式,我們需要從main。rs中分離出一個庫,它可以包含在其他包和整合測試可執行檔案中。為此,我們建立一個新的src/lib。rs檔案。

• 為了使我們的庫與cargo test一起工作,我們還需要將測試函式和屬性從main。rs移到lib。rs。

• 我們也移過QemuExitCode列舉和exit_qemu函式,並使它們公開。

• 現在可執行程式和整合測試可以從庫中匯入這些函式,而不需要定義它們自己的實現。為了使println和serial_println可用,我們也移動模組宣告。

• 現在我們可以更新main。rs使用library了。

• 像我們的src /main。rs,tests/basic_boot。rs可執行檔案可以從我們的新庫中匯入型別。這允許我們匯入缺少的元件來完成我們的測試。

• 現在可以將測試新增到basic_boot。rs中。例如,我們可以測試println工作而不發生恐慌,就像我們在vga緩衝區測試那樣。

• 雖然我們不能在核心中使用#[should_panic]屬性,但我們可以透過建立一個從panic處理程式中退出並帶有成功錯誤程式碼的整合測試來獲得類似的行為。讓我們開始建立這樣一個名為should_panic的測試。

• 這個測試仍然不完整,因為它還沒有定義_start函式或任何自定義測試執行器屬性。讓我們新增缺失的部分。

• 現在我們可以建立一個應該失敗的測試。

• 讓我們為should_panic測試禁用這個harness標誌:

• 現在,透過刪除測試執行器相關的程式碼,我們極大地簡化了我們的should_panic測試。結果是這樣的。

2。 在CPU異常部分新增test_breakpoint_exception測試時,並沒有像希望的那樣打印出“test_breakpoint_exception… [ok]”。

用Rust寫作業系統(三)——問題彙總

錯誤原因:網站上面給的程式碼並不全面,需要自己額外新增列印函式。

用Rust寫作業系統(三)——問題彙總

3。 在實現硬體中斷部分的第一步時,報錯如下:

用Rust寫作業系統(三)——問題彙總

錯誤原因:在修改interrupts。rs的過程中,不小心刪掉了pub mod gdt;,加上後正確。

4。 在實現硬體中斷時,執行結果還是和雙重故障部分一樣。

用Rust寫作業系統(三)——問題彙總

錯誤原因:main。rs中上一步的stack_overflow函式沒有刪掉,否則還是會呼叫stack_overflow。

用Rust寫作業系統(三)——問題彙總

標簽: 測試  我們  test  rs  main