驅動程式架構 (DFv2)

Fuchsia 的驅動程式庫架構是一組程式庫、工具、中繼資料和元件,可讓開發人員為 Fuchsia 系統建立、執行、測試及發布驅動程式。驅動程式庫架構旨在提供穩定的 ABI,讓開發人員一次編寫驅動程式庫,並在多個版本的 Fuchsia 平台上部署。(不過,Fuchsia 的驅動程式庫架構不斷演進,尚未達到 ABI 穩定性。)

驅動程式庫架構包含下列實體,可在 Fuchsia 系統中執行驅動程式:

驅動程式管理員

Fuchsia 的驅動程式管理器會以 Fuchsia 元件 (driver_manager.cm) 的形式執行,是 Fuchsia 系統啟動時要啟動的初始程序之一。驅動程式管理器會在 Fuchsia 系統中啟動及停止驅動程式,並為驅動程式轉送 FIDL 功能。

驅動程式管理器會維護 Fuchsia 系統中所有已知裝置 (或nodes) 的拓樸結構。當驅動程式管理器看到代表系統中新裝置的節點時,會要求驅動程式索引 (Fuchsia 元件) 找出正確的驅動程式庫,以便將該節點繫結。當驅動程式庫與節點相符時,驅動程式管理器會建立新的驅動程式主機 (或重複使用現有的驅動程式代管程序),並以元件形式執行。驅動程式代管程序會啟動驅動程式庫例項,並開始向系統中的其他 Fuchsia 元件提供裝置服務。

驅動程式代管程序

每個驅動程式庫都位於驅動程式代管程序中,並以 Fuchsia 元件 (driver_host.cm) 的形式執行。驅動程式主機可在 Fuchsia 系統中提供驅動程式間的隔離。每個驅動程式代管程序都是一個程序,也就是說,它有自己的位址空間,並管理自己的執行緒集合。

驅動程式管理器將驅動程式庫繫結至節點後,會要求驅動程式代管程序建立驅動程式庫的例項。驅動程式代管程序接著會初始化驅動程式庫。驅動程式庫初始化作業包括呼叫驅動程式庫的啟動鉤子 (驅動程式程式碼中的 Start() 函式),並將驅動程式庫控制權交給所綁定的節點。

單一驅動程式代管程序中可以同時放置多個驅動程式庫。驅動程式庫繫結至節點後,通常會放置於新的驅動程式庫主機中。不過,驅動程式庫也可以選擇與父項驅動程式庫放在同一個驅動程式庫主機中。當驅動程式位於同一個驅動程式代管程序時,就會共用相同的位址空間。

alt_text

圖表 1:代表已連上 PCI 匯流排的 USB 裝置的驅動程式主機。

驅動程式索引

驅動程式庫索引會以 Fuchsia 元件 (driver-index.cm) 的形式執行,負責執行下列工作:

  • 追蹤系統中可用的所有驅動程式,其中每個驅動程式庫都會與中繼資料 (例如元件網址和繫結規則) 一併儲存。
  • 將所有已知的驅動程式與目標「節點」 (也就是系統中的裝置) 進行比對。

驅動程式索引會在 Fuchsia 系統中追蹤下列類型的驅動程式:

  • 啟動驅動程式:位於 Zircon 開機映像檔 (ZBI) 中,且系統引導時需要的驅動程式 (例如儲存空間驅動程式)。相較於基礎驅動程式,ZBI 的空間有限。
  • 基本驅動程式:Fuchsia 映像檔中提供的驅動程式,對系統引導並非必要。這些驅動程式會從系統的儲存空間載入,因此需要在啟動驅動程式啟用儲存空間後載入 (例如 USB 驅動程式、網路驅動程式)。這些驅動程式類似 Fuchsia 的基礎套件
  • Universe 驅動程式:在系統初始啟動後手動註冊的驅動程式 (例如使用 ffx driver registerbazel run 指令),會使用 Universe 套件解析器載入,類似 Fuchsia 的 Universe 套件。不過,註冊 Universe 驅動程式僅供驅動程式庫開發用途。

當驅動程式管理器需要在節點拓撲中為未綁定的節點尋找驅動程式庫時,會使用 MatchDriver Fidl 通訊協定,將比對要求傳送至驅動程式庫索引。驅動程式庫索引會根據每個追蹤驅動程式庫的繫結規則,評估節點屬性 (包含在比對要求中)。在相符的情況下,驅動程式庫索引會將相符的驅動程式中繼資料傳回給驅動程式管理器。但如果沒有相符項目,驅動程式庫索引會回應 Not Found 錯誤代碼。(如要進一步瞭解繫結規則和繫結程序,請參閱「Driver binding」)。

驅動程式執行階段

大致來說,驅動程式庫會與 Fuchsia 系統中的下列三個群組通訊:驅動程式庫架構、其他驅動程式和非驅動程式庫元件。大部分的通訊都會透過 Zircon 管道使用 FIDL 呼叫,不過,在驅動程式庫執行階段中,同一個程序中的同地點驅動程式可以避免進出 Zircon 核心。換句話說,驅動程式庫執行階段提供的機制可讓位於同一位置的驅動程式在本機彼此通訊,這比使用核心管道通訊更有效率。驅動程式執行階段是模擬 Zircon 核心的程序內執行階段。驅動程式庫執行階段提供與 Zircon 管道和通訊埠相似的原始元素,並在這個執行階段上建構新的 FIDL 傳輸機制。(詳情請參閱驅動程式庫執行階段的 RFC)。

FIDL 介面

驅動程式庫程式架構中的 FIDL 介面會參照下列兩個 FIDL 通訊協定:

這兩種通訊協定的組合,構成了驅動程式與驅動程式庫程式架構之間通訊方式的基礎。架構支援的其他通訊協定,主要用於各種驅動程式庫架構實體 (也就是驅動程式管理器、驅動程式庫索引、驅動程式庫主機等) 之間的內部通訊。

在非驅動程式庫元件和驅動程式庫程式架構之間,也有一些輔助的 FIDL 通訊協定。舉例來說,我們在 fuchsia.driver.development FIDL 程式庫中提供多個偵錯通訊協定,供偵錯工具使用。我們也提供一些用於註冊新驅動程式和處理關機的通訊協定。不過,這些內容對驅動程式庫開發人員來說並沒有太大吸引力。