在 Fuchsia 中,駕駛和非駕駛人都會透過 FIDL 呼叫進行所有通訊。差別在於駕駛服務的方式以及連線的建立方式。
為了進行驅動程式庫之間的通訊,Fuchsia 使用節點拓撲將父項節點的功能放置在子項節點傳入的 FIDL 命名空間中 (也就是在 /svc
下做為目錄和檔案)。
這項設定可讓驅動程式庫 (繫結至子節點之後) 存取從父項節點指派給子項節點的 FIDL 服務。
不過,非驅動程式庫元件與驅動程式庫的通訊會分為兩個階段:
對於非驅動程式庫元件,第一項工作是找出系統中可用的驅動程式服務。這些服務是由目前繫結至系統中硬體或虛擬裝置的驅動程式提供。名為 devfs
的檔案系統提供了探索這些服務的機制。
非驅動程式庫與驅動程式庫通訊會發生下列事件:
- 為了探索系統中的驅動程式庫服務,非驅動程式庫元件會掃描
devfs
中的目錄和檔案。 - 非驅動程式庫元件會在
devfs
中尋找代表目標驅動程式庫提供的服務的檔案。 - 非驅動程式庫元件會開啟這個檔案,該檔案會與目標驅動程式庫建立連線。
- 首次聯絡後,非驅動程式庫元件和驅動程式庫之間就會建立 FIDL 連線。
- 從這時起,所有通訊都會透過 FIDL 管道進行。
服務探索 (使用 devfs)
驅動程式管理員會託管名為 devfs
的虛擬檔案系統 (如「裝置檔案系統」)。此虛擬檔案系統能夠統一存取 Fuchsia 系統中的所有驅動程式庫服務,存取 Fuchsia 的使用者空間服務 (即驅動程式外部的元件)。這些非驅動程式庫元件會探索 devfs
中的目標驅動程式服務,以便與驅動程式建立初步聯絡人。
嚴格來說,devfs
是驅動程式庫管理員公開的目錄能力。因此,依照慣例,想要存取驅動程式的元件,將 devfs
掛接在其命名空間的 /dev
目錄下 (雖然並未強制規定 devfs
一律掛接在 /dev
下)。
devfs
會代管虛擬檔案,讓 Fuchsia 元件將訊息轉送至在 Fuchsia 系統中執行的驅動程式實作的介面。換句話說,當用戶端 (即非驅動程式庫程式元件) 在 /dev
目錄下開啟檔案時,會接收一個管道,用於直接對對應該檔案的驅動程式庫進行 FIDL 呼叫。舉例來說,Fuchsia 元件可以開啟及寫入類似 /dev/class/input-report/000
的檔案,以連線至輸入裝置。在這種情況下,用戶端可能會取得說出 fuchsia.input.report
FIDL 的管道。
驅動程式在新增節點時,可以使用 DevfsAddArgs
資料表將自己匯出至 devfs
。
FIDL 通訊
使用 devfs
在非驅動程式庫和驅動程式庫元件之間首次聯絡後,元件可以交換 FIDL 控制代碼。從這時起,這些元件會使用 FIDL 呼叫進行通訊,就像 Fuchsia 中的其他元件一樣。
驅動程式為 Fuchsia 元件,在傳入的 FIDL 命名空間中具有駕駛人可使用的功能。其中部分功能可能會由其父項驅動程式提供給驅動程式庫 (例如 PCI 裝置其父項節點具有 fuchsia.hardware.PCI
能力)。驅動程式可透過這些功能對父項驅動程式進行 FIDL 呼叫。同樣地,其用戶端 (即非驅動程式庫元件) 也可以使用驅動程式接收的功能,向驅動程式發出 FIDL 呼叫。
根據預設,這些 FIDL 呼叫會透過 Zircon 核心轉送。不過,如果目標驅動程式庫位於相同程序 (也就是同一驅動程式代管程序中),驅動程式執行階段便可將 FIDL 呼叫轉送到程序中,無需進入及退出 Zircon 核心。