破解黑盒:拆解 Intel 80386 微碼

數十年來,Intel 80386 是現代計算的基石,引入了支援受保護模式與記憶體分頁的 32 位元架構。然而,儘管其外部行為有完整文件記載,其內部微碼——告訴硬體如何執行複雜 x86 指令的低階指令——仍是一個完全的黑盒。

最近,一個由研究人員與愛好者共同參與的合作計畫成功拆解了 80386 微碼。此成就不僅是歷史上的好奇心,更是一堂逆向工程的大師課,結合影像處理、神經網路與 painstaking manual analysis,揭示了這顆傳奇處理器的內部運作。

從矽片到二進位:提取過程

與 8086 不同,後者的專利提供了拆解的路線圖,80386 卻沒有任何線索。此過程從 Ken Shirriff 提供的 80386 晶片高解析度影像開始。然而,將 ROM 的視覺表示轉換成二進位資料是一項艱巨任務。80386 的微碼 ROM 大約有 94,720 位元——是 8086 的近九倍。

為了克服這個挑戰,團隊採用了以下組合:

  • Image Processing: 從晶片影像中分離出 ROM 結構。
  • Neural Networks: 自動辨識矽片內的位元模式。
  • Human-Aided Automation: 交叉檢查與驗證提取出的二進位資料。

一旦二進位資料取得,真正的挑戰開始了:將位元序列轉換成可理解的微操作(\u03bc-ops)。

解碼微操作

拆解二進位資料需要辨識模式並推斷 \u03bc-ops 的結構。研究人員必須確定 \u03bc-ops 的軸向、讀取順序,以及位元如何被劃分為功能欄位。

幾個關鍵洞見指引了整個過程:

  • ALU Cycle Analysis: 知道 80386 可以在兩個週期內執行 ALU 運算,暗示了第二個 ALU 輸入的特定欄位,使得運算元能在第一個週期載入,結果在第二個週期儲存。
  • Register Mapping: 依據先前對 8086 的研究,團隊假設某些欄位對應來源與目的暫存器。
  • Instruction End-Markers: 團隊找到了重複出現的模式,標示特定指令例程的結束。
  • Hardware Tracing: Ken Shirriff 透過追蹤晶片上的實體邏輯線路,確認元件之間的互連方式。

架構洞見:硬體加速

最引人注目的發現之一是 8086 與 80386 在實作上的差異。8086 大量依賴微碼來實作演算法,而 80386 因為「硬體加速」許多這類流程而顯著更快。

在 80386 中,微碼往往充當控制器,設定專用硬體加速單元——例如 barrel shifter、乘除硬體與保護測試單元——而不是將演算法直接寫成類似軟體的微步驟。

從拆解中得到的關鍵發現

  • Instruction Volume: 微碼在解碼 ROM 中包含 215 個入口點,遠高於 8086 的 60 個。此增長來自新指令以及根據運算元類型(暫存器 vs 記憶體)與 CPU 模式(實模式 vs 受保護模式)所需的不同例程。
  • Universal Microcode: 令人驚訝的是,80386 的每一條指令皆由微碼處理。與現代 CPU 常有「快速路徑」繞過微碼的簡易指令不同,80386 總是執行一個 \u03bc-op。
  • Potential Security Flaw: 拆解過程揭露了 IO 權限位圖處理可能的漏洞。在 4 位元組埠存取時,微碼可能只檢查前三個位址的權限位元。如果存取發生在允許的 IO 埠空間邊緣,最後一個位元組可能錯誤通過,進而授予未授權的硬體暫存器存取權限。

386 的複雜性

從 8086 轉向 80386 代表了複雜度的飛躍。正如一位社群觀察者所說,8086 感覺像是一場「可親近的個人冒險」,而 80386 則像是一部「工業機器」,反映出虛擬 86 模式、浮點單元與記憶體分頁所帶來的複雜性爆炸。

此專案凸顯了低階架構知識的重要性。想深入探索這些發現的讀者,可在 x86 microcode repository on GitHub 取得拆解檔與支援檔(包括 fields.txtmicrocode_10.txt)。

"The black box analysis needed to decode this is incredibly hard but also incredibly fun and rewarding to pull off."

透過剝開 80386 的層層結構,研究人員不僅保存了一段計算歷史,也提供了一個具體範例,說明硬體與軟體最基礎層面的交互方式。

Sources