這段時間期時也沒啥好寫的,每天做的事情就是查 BIOS 服務 -> 實作 -> 測試 -> 爆掉 -> 再找哪裡實現錯誤。我在想目前最大的問題是對組語不夠熟練並且我沒有做測試。
當我在實作 BIOS 服務時,經常踩到相同的坑,舉例來說:
目前觀測也很被動:能看的訊息多半在 BIOS/Host 兩側留下,且必須經由 Host 才能刷新。
比如當我忘記 pop 時會發生兩個問題,暫存器沒有被正確恢復,ret 會跳到錯誤地址然後觸發 int 6h 的 UND 非法指令,但當錯誤發生到處發 int 6h 已經距離很遠了。或者有時候 BIOS 的返回信息沒給正確,導致 bootloader 在計算扇區調用 int 13h 去讀資料時意外的發生 int 0h 的除以零的錯誤。經常看著程式碼一天過去也沒多少進度,寫一段停一段,實在找不出問題沒想法就拿去問 ai 請他給我一些想法。坦白說,目前有不少 assembly 是經過 AI 重構,光靠我硬寫真的很多地方真得慘不忍睹。
總結下來最大的問題還是 1. 對 bios 的理解止於表面,實作功能時得回去看功能描述並且還經常做錯 2. 慘不忍睹的組語能力 3. 沒有實作測試模組驗證行為的正確性。
舉例來說若想保證行為正確,可以考慮差異測試。
qemu 是經過驗證非常可靠的模擬環境,以它作為基準我們無需去猜測 hv 是否有哪裡實現錯誤可能的原因是甚麼。比如我們可以同步 qemu 與 hv 並實作差異測試:
QEMU 執行 1 條指令 -> HV 也執行 1 條 → 比對兩邊狀態(暫存器) -> 第一個不一致處就是錯誤的發生點。
這樣就無須像現在一樣用通靈的方式去猜問題是甚麼。
不過這需要仰賴一條指令 INT 3h(1 byte),這是 x86 系統專門用於條是錯誤保留的指令入口,長度為 1 byte 可在任何位置插入命令而不影響周圍指令。我們甚至可以實作一個簡單的調適器,在需要的地方插入 0xCC (INT 3h),執行到目標指令時就:
這樣就不需通過通靈去猜問題發生在哪裡。
而對於那些非 hv 的錯誤比如 bootloader 或是 bios 的錯誤可透過延伸 int 3h 在 Host 內建簡易調適器解決。比如我們有註冊到 kvm 的 memory slot 與 struct struct kvm_regs 等,可以以此為基礎實作斷點、單步調適、暫存器、記憶體觀察與修改、差異輸出。