Fuchsia 系統介面

總覽

Fuchsia 系統介面是 Fuchsia 作業系統向其執行的軟體呈現的二進位檔介面。這個介面的基礎是 vDSO,可提供系統呼叫存取權。程式不得直接發出系統呼叫 (例如陷入核心)。相反地,程式會使用 vDSO 與核心介接。

系統介面的主要部分是透過跨程序通訊協定提供,通常會使用 FIDL 定義。這些通訊協定會透過各種核心原始碼 (包括管道和通訊端) 進行。

fuchsia.io FIDL 程式庫提供檔案和目錄作業的通訊協定。Fuchsia 會使用 fuchsia.io 通訊協定,為元件提供命名空間,讓元件可以存取系統服務和資源。這些命名空間中的名稱會遵循特定慣例,而這些慣例是系統 ABI 的一部分。詳情請參閱「namespaces」。

套件本身也會提供目錄結構和檔案格式的系統介面。系統會使用這項資訊,在執行儲存在這些套件中的元件時,初始化程序。

術語

系統的應用程式設計介面 (API) 是系統的來源層級介面。您通常會編寫直接使用此介面的軟體。系統 API 變更後,您可能需要更新原始碼,以便因應 API 的變更。

系統的應用程式二進位檔介面 (ABI) 是系統的二進位層級介面。通常您不會編寫直接使用系統 ABI 的軟體。而是針對系統 API 編寫軟體。編譯軟體時,編譯器建立的二進位檔案會透過 ABI 與系統介接。系統 ABI 變更可能需要重新編譯原始碼,以便考量 ABI 的變更。

ABI 途徑

本節將說明 Fuchsia 元件的各種 ABI 途徑。

vDSO

vDSO 是提供核心存取權的虛擬共用程式庫。具體來說,vDSO 是名為 libzircon.so 的 ELF 共用程式庫,可透過 C 呼叫慣例匯出多個符號。這些符號的可靠來源是 //zircon/vdso。其語意請參閱說明文件

FIDL 通訊協定

大部分的系統介面都是在 Fuchsia 介面定義語言 (FIDL) 中定義。FIDL 編譯器會針對各種目標語言產生語言專屬 API 和執行階段程式庫,也就是 FIDL 繫結。這些繫結可提供慣用介面,透過 Zircon 管道 (和其他基本元素) 傳送及接收處理序間通訊訊息。

線路格式

FIDL 通訊協定定義本身和編譯器產生的語言專屬繫結是系統 API 的一部分,但不是系統 ABI 的一部分。相反地,ABI 是由稱為「線路格式」的序列化訊息格式所組成。FIDL 線路格式是由規格定義。

使用者信號

除了傳送的訊息之外,部分 FIDL 通訊協定會在基礎核心物件上使用使用者信號。目前,這些信號並未在 Fidl 中宣告。通常,任何相關使用者信號的語意都會以文字形式記錄在 FIDL 定義的註解中。

命名空間慣例

執行時,系統會為元件提供 命名空間和傳出目錄中的名稱會遵循特定慣例,這些慣例是系統 ABI 的一部分。

命名空間

元件的

例如,元件可以探索 FIDL 的實作。/svc同樣地,依照慣例,pkg 命名空間項目會對應至元件解析的來源套件。

傳出目錄

元件會提供

例如,元件會公開 FIDL 檔案。/svc

資料格式

部分命名空間包含含有資料的檔案。這些檔案使用的資料格式也是系統 ABI 的一部分。舉例來說,元件會透過包含 certs.pem 檔案的命名空間項目存取根憑證。因此,pem 資料格式是系統 ABI 的一部分。

套件慣例

Fuchsia 套件具有依循特定命名慣例的目錄結構。這些慣例也是系統 ABI 的一部分。本節將舉出兩個重要的包裝慣例範例。

Meta

依慣例,套件中的 meta 目錄會包含描述套件的中繼資料檔案。此中繼資料的結構,包括這些檔案使用的資料格式,例如

lib

依慣例,套件中的 lib 目錄會包含套件中元件使用的共用程式庫。當系統執行套件中的可執行檔時,系統會根據這個 lib 目錄解析共用程式庫的要求。

Fuchsia 與其他作業系統之間的一個重要差異,是共用程式庫本身是由套件建立者提供,而非系統本身。因此,共用程式庫本身 (包括 libc) 並非系統 ABI 的一部分。

系統提供兩個共用程式庫:vDSOVulkan ICD。詳情請參閱相關章節。

程序結構

Fuchsia 上的程序相當靈活,且大多受程序中執行的執行檔控制,但程序的部分初始結構由系統和系統 ABI 的部分控制。

詳情請參閱「程式載入」。

ELF 載入程式

Fuchsia 會將 ELF 資料格式用於可執行檔。將可執行檔載入程序時,載入器會將可執行檔的內容解析為 ELF。載入器會從執行檔讀取 INTERP 指令,並將該名稱解析為包含執行檔的套件 lib 目錄中的檔案。接著,載入器會將 INTERP 檔案的內容剖析為 ELF 共用程式庫,重新安置程式庫,並將程式庫對應至新建立的程序。

啟動訊息

在啟動程序的過程中,程序的建立者會為程序提供訊息,其中包含指令列引數、environ、初始句柄和程序的命名空間。(傳出目錄包含在程序的初始句柄集合中)。

此訊息的格式 (包括指令列引數和 environ 等欄位的長度限制) 是系統 ABI 的一部分,而訊息內容的慣例也是如此。舉例來說,依照慣例,PWD 環境變數是創作者建議的程序名稱,可做為目前的工作目錄。

初始句柄與數字 ID 相關聯。這些 ID 的慣例是系統 ABI 的一部分。舉例來說,依照慣例,PA_PROC_SELF 控制代碼是新建立程序的程序物件控制代碼。除了這些句柄的類型之外,與這些句柄相關聯的權利也是系統 ABI 的一部分。

VMAR 結構

在開始程序之前,創作者會修改程序的根 VMAR。舉例來說,創作者會對應 vDSO,並為初始執行緒分配堆疊。啟動程序時,VMAR 的結構是系統 ABI 的一部分。

工作政策

程序會在工作中執行,而工作可以將政策套用至所含的程序和工作。套用至程序的工作政策是系統 ABI 的一部分。舉例來說,元件會在 ZX_POL_NEW_PROCESS 設為 ZX_POL_ACTION_DENY 的程序中執行。這會強制要求元件使用 fuchsia.process.Launcher 通訊協定建立程序,而非直接發出 zx_process_create 系統呼叫。

Vulkan ICD

使用 Vulkan API 的元件會針對 libvulkan.so 連結硬體加速圖形,並在其資訊清單中指定 vulkan 功能。這個程式庫是由包含元件的套件提供,因此不屬於系統 ABI 的一部分。不過,libvulkan.so 會載入另一個共用程式庫,稱為 Vulkan 可安裝用戶端驅動程式 (Vulkan ICD)。Vulkan ICD 會使用 fuchsia.vulkan.loader.Loader 載入,這表示程式庫是由系統本身提供,而非包含元件的套件。因此,Vulkan ICD 是系統 ABI 的一部分。

Vulkan ICD 是會匯出三個符號的 ELF 共用程式庫。這些符號是預留給 Vulkan ICD 使用的,因此不應直接使用。

  • vk_icdGetInstanceProcAddr
  • vk_icdNegotiateLoaderICDInterfaceVersion
  • vk_icdInitializeOpenInNamespaceCallback

此外,Vulkan ICD 共用程式庫有 NEEDED 區段,列出幾個 Vulkan ICD 依附的共用程式庫。包含元件的套件必須提供這些共用程式庫。

Vulkan ICD 也會匯入多個符號。這些匯入符號的慣例 (例如參數和語義) 是系統 ABI 的一部分。

目前,NEEDED 部分和 Vulkan ICD 的匯入符號清單都比我們預期的還要大。希望我們能盡量減少系統 ABI 的這些層面。

通訊端

資料單元格式設定

用於網路連線的資料包通訊端包括一個資料格式,可指定與資料包相關聯的網路位址。這個影格也是系統 ABI 的一部分。

終端機通訊協定

在終端機中執行的程式會使用 Fuchsia 終端機通訊協定與終端機通訊,這是類似 vt100 的文字型通訊協定。這個通訊協定也會透過 ssh 在網路上公開,包括預期傳入 ssh 連線支援此通訊協定的用戶端,以及預期傳出 ssh 連線支援此通訊協定的伺服器。