平台匯流排

說明

「平台匯流排」一詞是指特定的 Fuchsia 驅動程式庫,原始碼位於 //fuchsia/src/devices/bus/drivers/platform/。不過,這個術語也是指用於管理 Fuchsia 中較低層級驅動程式的架構。在本文件中,「平台匯流排驅動程式」是指特定驅動程式庫,而「平台匯流排」則是指一般架構。

整體平台匯流排包含多種驅動程式:

  • 月台匯流排驅動程式,用於管理平台匯流排。這是沒有硬體專屬功能的通用驅動程式庫。驅動程式管理器會在系統啟動時自動啟動平台匯流排驅動程式。

  • 主面板驅動程式,是平台匯流排驅動程式載入的第一個驅動程式庫。主面板驅動程式庫包含平台匯流排所需的所有平台專屬資訊,並控管平台匯流排載入的其他驅動程式。在 arm64 平台上,平台匯流排驅動程式會使用系統啟動載入程式或啟動輔助程式中的資訊,為執行平台的平台繫結正確的主面板驅動程式庫。在 x86 平台上,平台匯流排驅動程式一律會載入 x86 主機板驅動程式庫,並根據 ACPI 提供的資訊建立平台裝置。

  • 平台裝置驅動程式是 Fuchsia 中較高層級驅動程式的基礎。這些驅動程式提供對於特定功能 (例如 USB、eMMC 或 NAND 儲存空間等) 的最低支援等級,並在上方載入更高層級的驅動程式。

  • 通訊協定實作驅動程式是提供主機板驅動程式庫所需的通訊協定的驅動程式。其中一個常見的例子是 GPIO 驅動程式庫,通常用於釘地利用。過去,平台匯流排用於將這些驅動程式的通訊協定代理至平台裝置,但現在,我們會改用複合型裝置。我們可能隨著時間的推移逐步淘汰在平台匯流排中使用通訊協定實作驅動程式的新方法,並將其取代為不用等待驅動程式載入完成的新方法。

  • 最後,「平台 Proxy 驅動程式」是與平台匯流排驅動程式的隨附,可載入平台裝置驅動程式庫主機。此驅動程式庫支援從平台裝置驅動程式,透過 Proxy 將平台裝置通訊協定和其他資源通訊協定傳送至平台匯流排驅動程式和通訊協定實作驅動程式。之所以需要如此,是因為平台裝置驅動程式與平台匯流排驅動程式和通訊協定實作驅動程式不同。

Fuchsia 平台匯流排圖表 來源

Platform 匯流排初始化

驅動程式管理器會在啟動時自動啟動平台匯流排驅動程式,由於平台匯流排驅動程式是一般驅動程式庫,但其中不含任何執行平台的相關資訊,因此會先載入板球驅動程式庫,再由該驅動程式處理平台專屬的邏輯。為決定要載入的主面板驅動程式庫,平台匯流排驅動程式會從系統啟動載入程式傳遞的 ZBI 資料中讀取 ZBI_TYPE_PLATFORM_ID 記錄。然後新增具有通訊協定 ZX_PROTOCOL_PBUS 的裝置,並將 BIND_PLATFORM_DEV_VIDBIND_PLATFORM_DEV_PID 繫結變數設為 vid,並從平台資料記錄中完成。正確的主面板驅動程式庫會繫結至這部裝置,並繼續平台匯流排初始化程序。在 x86 平台上,系統會自動載入 x86 主機板驅動程式庫。

主機板驅動程式庫會使用平台匯流排通訊協定與平台匯流排驅動程式進行通訊。完成自己的初始化作業後,主面板驅動程式庫會使用平台匯流排通訊協定中的 ProtocolDeviceAdd() 呼叫,載入通訊協定實作驅動程式。通訊協定實作驅動程式庫載入後,必須呼叫平台匯流排 RegisterProtocol() API,向平台匯流排驅動程式庫註冊其通訊協定。ProtocolDeviceAdd() 會封鎖,直到驅動程式庫呼叫 RegisterProtocol() 為止,因此主面板驅動程式庫必須透過其本身的執行緒呼叫 RegisterProtocol(),而非驅動程式管理器回呼 (例如 Bind())。

新增通訊協定裝置後,主面板驅動程式庫會呼叫平台匯流排通訊協定中的 DeviceAdd() 呼叫來建立平台裝置,如此一來,平台裝置驅動程式就會分別載入各自的驅動程式代管程序。平台裝置建立後,平台匯流排初始化作業就完成。

複合平台裝置

平台匯流排也支援新增平台裝置,以做為複合裝置的元件。平台匯流排 CompositeDeviceAdd() 呼叫會新增複合裝置,其中零元件是由提供的 PBusDev 結構描述的平台裝置。其餘元件的繫結規則由 components 參數提供。primary_fragment 是用來指定建立複合式裝置的驅動程式代管程序。指定 NULL 會導致為複合式裝置建立新的驅動程式代管程序,而與其中一個片段名稱相等的有效字串則會將複合裝置新增至另一個片段的驅動程式代管程序。我們不希望將複合式裝置加入平台匯流排驅動程式的驅動程式代管程序,因此不允許傳遞「pdev」。

複合平台裝置的內部結構與非複合情況稍有不同。驅動程式管理器的元件元件 Proxy 驅動程式並非使用平台 Proxy 驅動驅動程式庫,而是改為 Proxy 平台裝置通訊協定。舉例來說,在上圖中,我們為音訊驅動程式庫程式有一個複合裝置,其中第一個元件是平台裝置,第二個為 I2C 管道。系統會在新的驅動程式代管程序中啟動音訊驅動程式庫,而驅動程式管理器元件和元件 Proxy 驅動程式會負責將 PDEV 和 I2C 通訊協定委託給音訊驅動程式庫。

平台裝置通訊協定

平台裝置通訊協定 (ZX_PROTOCOL_PDEV) 是平台匯流排提供平台裝置驅動程式的主要通訊協定。這個通訊協定可讓平台裝置驅動程式庫存取 MMIO 範圍、中斷、BTI 和 SMC 範圍等資源。這些資源是由零開始索引的要求,不會要求 MMIO 和實體位址或 IRQ 號碼中斷服務,因此,我們可具備適用於多個平台的特定 IP 平台裝置驅動程式,因為驅動程式庫不必知道確切的 MMIO 位址和中斷編號。而是在與 AddDevice() 傳遞的 PbusDev 結構中,設定 MMIO 位址和 IRQ 號碼。

平台裝置通訊協定也適用於通訊協定實作驅動程式。舉例來說,GPIO 驅動程式庫可能會使用平台裝置通訊協定來存取其 MMIO 和中斷情形。這樣做可讓通訊協定實作驅動程式在不同 SOC 變化版本之間共用,其中功能可能相同,但 MMIO 位址和中斷編號可能不同。

平台匯流排協定

平台匯流排通訊協定 (ZX_PROTOCOL_PBUS) 是由主機板驅動程式和通訊協定實作驅動程式與平台匯流排驅動程式進行通訊。只有在平台匯流排驅動程式主機中執行的驅動程式可以使用 (特別是,平台裝置驅動程式無法存取該驅動程式)。這個通訊協定的用途是為了讓棋盤驅動程式庫載入通訊協定實作驅動程式,以及啟動平台裝置驅動程式。通訊協定實作驅動程式也會使用這個欄位,向平台匯流排註冊其通訊協定,以便讓平台裝置驅動程式使用其通訊協定。