RFC-0190:支援 Syscalls 的 FIDL | |
---|---|
狀態 | 已接受 |
區域 |
|
說明 | 擴充 FIDL 以支援系統呼叫宣告,並將介面的 FIDL 表示法設為我們的基準真相。 |
問題 | |
Gerrit 變更 | |
作者 | |
審查人員 | |
提交日期 (年-月-日) | 2022-07-08 |
審查日期 (年-月-日) | 2022-09-22 |
摘要
在系統呼叫 (例如 「系統呼叫」) 代表 Fuchsia 的基本平台介面,而 Fuchsia 介面定義語言 (FIDL) 目前無法定義這些項目。不過,除了這個諷刺的名稱之外,缺乏支援也帶來了更嚴重的後果。「自備執行階段」 (以下簡稱「BYOR」) 是我們核心的理想設計原則之一:指的是方便 (並簡化) 使用任意應用程式架構和程式設計語言,以便在 Fuchsia 上進行開發。其中一個重要層面,就是讓執行階段能夠與外部的使用者端系統進行無縫互動;這項功能已由 FIDL 的語言中立 IPC 架構提供,可提供穩健的服務。事實上,FIDL 是 Fuchsia 實現 BYOR 的工具,這並非巧合。不過,啟用執行階段的目的不僅是為了能夠與其他程序通訊。為了讓任何執行階段都能真正「執行」,必須啟用與核心通訊的功能,也就是發出系統呼叫。因此,FIDL 在根本上有所不足。
這份 RFC 解決了這個差距,讓我們朝著實現 BYOR 的目標邁進。具體來說,討論內容包括:
- 擴充 FIDL,以完整指定系統呼叫介面,並以第一類方式進行編碼
- 讓 syscall 介面符合正式模型時,對 FIDL 和 syscall 介面本身的影響;
- 預期 FIDL 語言繫結會如何使用這項資訊,以及這些繫結會向使用者提供哪些新設施。
- 在維護系統呼叫介面和依附於此的工具時,可提供大幅提升的使用者體驗。
這份文件是意向聲明,而非完整提案。我們希望在解決較小設計問題的過程中 (在後續 RFC 中),能提出更大型的設計,為後續的實驗和審慎思考留出空間。我們將在此說明預期的結果、實現這些結果的大致路線,以及沿途遵循的原則和限制。
提振精神
事實上,在 //zircon/vdso 底下,已經有系統呼叫介面的 FIDL 表示法;這是 FIDL 程式庫 zx
,我們將從此稱之為「v1 (FIDL) 表示法」。不過,此表示法並非一流,且會向嘗試解讀該表示法的繫結提供大量特異性:也就是大量自訂註解和特殊名稱與註解的頻外信號,以及假設會從中產生 C 類程式碼的架構。這些特徵足以讓您只在 kazoo
等單一後端中解讀這些特徵。根據目前的定義,kazoo 會為核心和 vDSO 產生基本邏輯,以及 Rust 系統呼叫外部函式介面 (即包裝函式,這是標準程式庫中執行階段的 Go 系統呼叫 FFI 包裝函式,以及系統呼叫說明文件 Markdown 的各部分。
因此,我們目前處於過渡狀態,其中的系統呼叫的 quasi-FIDL 表示法是負載關鍵,但無法用於實際的 FIDL (除了目前匯出的某些基本列舉和類型別名),這也是任何工具嘗試解讀的維護負擔。雖然「我們已經開始做 X,而且已經完成一半」並非「讓我們完成 X」的合理論點,但這確實是同理心態的動機,尤其是考量到目前狀態的以下問題。
不過,第 1 版 FIDL 表示法僅部分符合真實情況,雖然包含系統呼叫定義,但無法完整計算介面中的資料類型。資料類型的可靠來源 (含有相當多重複內容) 則位於一組 C 標頭中 (即 <zircon/types.h>、<zircon/syscalls.h> 和 <zircon/syscalls/*>)。由於能解讀 v1 表示法的內容有限,且資料類型是在 C 中定義,因此在實現 BYOR 和維護介面本身時,都會出現許多問題。
使用 IDL 的動機
介面演進和偏移
如果系統呼叫介面有所變更,則所有與此資訊相關的不同分支也必須變更。這些分支包括:
- 語言專屬的系統呼叫包裝函式。
- 與 C 資料類型相關的語言專屬類型。
- 不處理發出系統呼叫的用途,但需要對系統呼叫介面進行更多抽象轉換。
- 我們的系統呼叫 Markdown 就是這方面的最佳範例;
fidlcat
的介面合成也是另一個例子。
- 我們的系統呼叫 Markdown 就是這方面的最佳範例;
針對幾個 kazoo 支援的例外狀況,系統呼叫介面和分支維護者都必須進行大量工作,才能保持這些項目同步並防止偏移:特別是,系統呼叫介面維護者必須知道所有分支的位置,並記得更新這些分支;而分支維護者由於缺乏機器可讀取的這類資訊,因此必須瞭解每個系統呼叫並明確列舉這些項目。
如果系統呼叫介面已在 IDL 中完整編碼,則這些分支可以重新設想為可透過程式碼產生所需資訊的後端 (因此不再是實際的分支)。在預期的後端中,沒有任何一個後端特別複雜。一旦穩定後,相較於現狀,這些變更應會「觸碰」得更少,自動調整以因應 syscall IDL 的大部分變更 (就像目前大多數 .fidl 檔案變更不需要更新任何特定後端一樣)。
C 蠕動
只使用 C 的觀點 (無論是在 C 標頭,還是在 v1 FIDL 表示法的 C 轉寫拼寫法中),很容易引入在 C 中合理的系統呼叫簽章和型別定義,但在其他語言中難以模擬。以下是一些值得注意的例子:
- 緩衝區為獨立的指標和長度
- 許多語言都有用於表示緩衝區的單一型別,因此不一定能以這種方式分解緩衝區。針對這類語言的繫結也需要進一步的信號,才能將 (指標、長度) 組合解讀為組合緩衝區,而不是不相關的引數。
- 如果緩衝區的指標和長度在系統呼叫簽章中並未彼此相鄰 (如
zx_vmo_read()
的情況),模擬作業就會變得更加困難。
- 未標記的聯集
- C 聯集稱為「未標記的聯集」,因為它代表由其他類型組成的不連續類型,但沒有標準方法可判斷特定例項實際持有的類型 (即「標記」)。標記的聯集在其他語言中自然更為常見 (且實用),且更有可能以單一概念呈現。
- 資料類型中的大部分 (但非全部) C 聯集例項可模擬為標記聯集,因為這些例項在結構體中具有可做為標記的鄰近欄位。不過,與上述緩衝區案例相似,沒有任何信號表示這些是相關的,而且我們有非相鄰標記的範例。
- 透過型別消除進行多工處理
- 我們有許多系統呼叫可利用
void*
的彈性型別特性,有條件地接受或傳回不同類型,有效地將多個函式簽名多路復用。zx_object_get_info(..., uint32_t topic, void* buffer, ...)
就是一個很好的例子,視topic
而定,它會將buffer
解讀為任意類型。在非 C 的語言中模擬這項功能可能相當困難:特別是,繫結需要進一步提供某種信號,以便精確瞭解如何為簽章設定參數,而且可能需要依據每個可能的例項化,非正式產生個別函式。
- 我們有許多系統呼叫可利用
這類 C 語言特徵可能會大幅增加以非 C 語言呈現 syscall 介面的複雜度。如果您在以多語言友善為前提的 IDL 中工作,那麼這種架構就會避開或盡量減少這類問題。
政策實施
我們希望針對系統呼叫和資料類型強制執行多項政策。透過 IDL 化,後端可存取機器可解讀的資訊表示法,此時就能直接編寫及維護政策執行工具。
以下是一些資料類型政策的範例,以 C 語言表示,這些政策源自於我們在核心和使用者空間之間共用資料的方式:
- 固定大小的結構體,或動態大小的陣列
- 接受其他任何內容都會使資料的分享和解讀變得複雜。
- 無間接路徑
- 資料必須完全可
memcpy
,並在建構資料的不同位址空間中加以理解;對來源位址空間中資料的編碼參照/指標可能會懸空,並導致無法解讀。(zx_iovec_t
代表此例外狀況,並會特別處理)。
- 資料必須完全可
- 沒有內嵌的句柄
- 嵌入版面配置中的句柄是忘記關閉該句柄 (或隱含「借用」) 的最佳方法。
- 沒有布林欄位
bool
會佔用 8 位元記憶體,但只提供 1 位元資訊。為了提高空間效率,我們建議使用位元欄位來傳達 1 位元。- 過度謹慎:C++ 標準允許未初始化的
bool
為真或假!
使用 FIDL 做為 IDL 的動機
來自不同 IDL 的先前課程
此平台先前已推出非 Fidl IDL:Banjo,用於表示驅動程式公開的介面。不過,後來我們發現這項做法是錯誤的:維護負擔重於附加價值,驅動程式庫程式作者對 Banjo 與 FIDL 之間的語法差異感到困惑,而且我們也無法實現在 FIDL 和 Banjo 之間共用資料類型的自然需求。自此之後,Banjo 已淘汰,我們也正在進行大規模的努力,以便針對驅動程式庫用途改進 FIDL,並取代 Banjo。假設系統呼叫規格 IDL 的動機充分,那麼我們有理由預期,針對該用途的新 IDL 也會遭遇相同的陷阱。
繫結開發
FIDL 語言繫結功能仰賴進程間訊息傳遞 (例如透過管道),因此您必須已瞭解有助於進行通訊的子集系統呼叫。特別是,他們已經在管理這些系統呼叫的 FFI 包裝函式。如果這些系統呼叫以機器可讀的形式呈現,則繫結就能更輕鬆地建構及維護 FFI 層;不過,如果系統呼叫的理解方式並未衍生自 FIDL,則繫結會分叉更多資訊,或最終會解讀兩種不同的 IDL IR (中間表示法)。
在資料類型方面,我們目前維護的程式庫會以與 FIDL 語言繫結分開的方式呈現這些類型,但同時也預期會有一定程度的互通性。也就是說,我們自然會預期兩者大致以相同的方式使用慣用法,讓程式碼可以輕鬆搭配使用,而不必面對不相容的拼字或樣式決定。在核心物件句柄和「zx_status_t
」的情況下,我們預期這些項目會以相同的方式呈現。最自然的方式是讓繫結明確使用資料類型程式庫,這也是目前的做法。因此,將這些項目分開呈現,大多是一種虛假的自由,而且如果這些項目來自同一個地方,對繫結維護者和使用者來說,肯定會更有益 (詳情請參閱下文)。
多語通性質
根據與 BYOR 的關係,FIDL 會盡量使用可合理對應至任何可能的目標語言的抽象概念。這項架構可避免系統誤將 syscall 介面偏向特定語言 (例如 C)。
平台版本管理
FIDL 內建平台版本支援功能,可進一步簡化系統呼叫演進過程,以便有效地簡化軟性轉換,這與 FIDL 的其他部分相同。
相關人員
協助人員:
hjfreyer@google.com
審查者:
abarth@google.com、brettw@google.com、mcgrathr@google.com、surajmalhotra@google.com
諮詢:
azaslavsky@google.com、bprosnitz@google.com、mcgrathr@google.com、yifeit@google.com
社會化:
這份 RFC 包含的高階構想已與 FIDL 和核心/vDSO 維護者進行交流。
設計
如上所述,這份文件並未提供適當的設計。我們會在此提出設計目標、原則和限制,供您參考。
目標
FIDL 程式庫 zx
是系統呼叫的唯一可靠資料來源
本 RFC 中概略說明的許多問題,都與系統呼叫的形狀、定義和說明文件的真實來源競爭有關。確保所有系統呼叫資訊直接從單一可靠資料來源的下游,透過簡單的機器翻譯,直接解決這個問題。
在 SDK 中匯出 FIDL 程式庫 zx
這是實現本 RFC 中提出的 BYOR 模式的基本前提。在達成這項目標之前,只有在平台上工作的開發人員可以使用相關的新設施。
Syscall 規格使用純粹的 FIDL
最後,您可能會在過程中切換回來,但請務必只使用 FIDL 語言規格中的功能定義系統呼叫介面。FIDL 後端不應需要額外資訊才能解讀,尤其是如果要將其放在 SDK 中,其他 FIDL 程式碼應可自由匯入及使用其資料類型。
fidlc
會強制執行系統呼叫政策
這裡所謂的「系統呼叫政策」是指任何形式的檢查,這些檢查可構成「正確」的系統呼叫宣告,而這項檢查純粹是 FIDL 表示法中資訊的函式。我們在上方列出了一些政策 (雖然是以 C 語言的形式)。
系統應在編譯期間強制執行 syscall 政策。fidlc
負責驗證系統呼叫宣告的語法是否正確,因此自然也會判斷其語意是否正確。我們希望確保後者驗證會在某個時間點發生,但將其延後至後續任意後續驗證步驟,會使工具整合變得複雜,並導致使用者體驗不佳,因為延遲時間會導致失敗。
Syscall 繫結
FIDL 語言後端應提供 系統呼叫繫結:也就是以後端其他繫結的風格,呈現慣用語的系統呼叫包裝函式介面。具體來說,這表示這些函式簽章會採用程式庫 zx
資料類型,因為這些綁定已代表這些類型。這可為任何使用者提供與核心的標準互通作業,並解決設計其他分離綁定和 syscall 發布邏輯以便協調的尷尬情況。
如果我們選擇不提供系統呼叫繫結,那麼 zx
資料類型會以一般 FIDL 可匯入的方式出現,這會帶來新的不便。假設 FIDL 用戶從管道中拉出「zx_port_packet_t
」,現在希望以某種方式呼叫「zx_port_queue()
」。如何達成這項目標?如果呼叫端可以存取系統呼叫包裝函式,並將該封包類型的現有繫結做為輸入內容,則這項作業就很簡單;不過,如果包裝函式的封包類型不同,則需要額外的轉譯負擔。無論翻譯邏輯位於何處,都會導致使用者體驗不佳,並產生許多不自然的相互依賴關係。最好完全不翻譯,讓問題中的程式碼在設計上能互相理解。
由於 syscall 介面具有特定核心物件的建議導向物件特性,因此 syscall 繫結的自然選擇,就是在代表該核心物件的類別上使用方法。不過,這項權限由後端維護者自行決定。
以最少的辛勞實現 Syscall 演進
系統呼叫進化功能的目標,是讓系統呼叫進化功能在幾個簡單的步驟中運作 (至少在常見情況下):
步驟 1:變更 FIDL 系統呼叫宣告,限制在達到平台 API 級別 X 時新增或移除任何內容;更新核心和 vDSO 以追蹤變更。
非步驟:請勿更新任何後端 (例如用於產生 Markdown 的 fidldoc),因為每個後端都應在任何平台層級自動產生正確的系統呼叫繫結。
步驟 2:針對每個「codebase」,將目標平台 API 級別提升至 >= X,並更新其中包含的程式碼,以便使用新的 syscall 繫結 (或要求下游專案自行執行此操作)。
可能的步驟 3:如果在步驟 1 中淘汰了任何系統呼叫宣告,一旦支援的最低平台 API 級別大於等於 X,請返回並移除這些宣告。
原則
盡可能使用一般 FIDL 公用程式
隨著新類型、語法和語義的引入,應優先考量 FIDL 的一般實用性,或至少仔細考量。需要大量新功能,並與非系統呼叫相關的用途產生協同效應 (未來肯定會有更多實例)。重疊程度越高,系統呼叫宣告的可讀性就越高。這麼做也許有助於您熟悉 FIDL 工具內的相關支援,並簡化維護作業。
長期來說,請避免使用 FIDL 語言限制,以便使用為系統呼叫資料類型引入的新宣告類型,原因如下:
- 如上文所述,我們希望規格使用「純」FIDL,因此任何形式的這些新結構降級都會違背其精神,也可能在實務上造成影響。
- 這些類型會出現在程式庫
zx
中,因此每種語言的後端都會大量使用這些類型。 - 其
zx
例項會以標準格式呈現系統資訊,且這類資訊應可在任何傳輸中自由流動; - 與系統呼叫資料類型模擬相關的問題,其實並非系統呼叫專屬,而是更廣泛地適用於記憶體格式的模擬,且可能有更廣泛的應用。
zx
資料類型的大部分內容都會是無聊的版面配置,因為這些內容使用了現有的基礎無限制宣告;如果這些類型的子集合看似任意,但在使用上有特殊限制,就會很奇怪。
盡量減少口譯負擔
系統呼叫宣告 IR 應盡可能簡單 (且不能再簡單),而後端在解讀時應盡可能採用統一邏輯 (並盡量減少特殊情況)。我們應努力讓後端作者 (數量不確定) 能輕鬆解讀,並減少他們可能需要瀏覽的尖銳角數量。
願意變更系統呼叫介面
我們會盡力模擬 syscall 介面。不過,某些事物可能非常難以建模。在這些情況下,我們應秉持「盡量減少解釋負擔」的原則,小心處理過度擬合的問題,並開放調整介面,讓介面更適合建模。
限制
持續對 vDSO 和核心的 FIDL 作業一無所知。
所謂「營運」是指在系統呼叫簽章或其實作考量中,表達 FIDL 知識。這會排除在實作 vDSO 和核心時使用 FIDL 產生的程式碼的可能性,而這項做法將 (持續) 具有極大價值。
vDSO 的內部運作方式應對 FIDL 保持不透明。我們嘗試模擬其介面,但這項任務與提供模型建立工具的相關知識無關。讓系統呼叫在運作時能辨識 FIDL 可說是一種抽象違規,這會讓這些系統互相依賴,但至少這也是一種奇怪的展望,因為在沒有 FIDL 的情況下,仍有可能發出系統呼叫 (更不用說執行 Fuchsia)。這也會帶來許多新的系統版本問題。Syscall 繫結只是為了在 FIDL 和 vDSO 之間建立橋樑。他們可以將系統呼叫呈現給使用者,以便與任何其他 FIDL 端點進行通訊,但這是個別後端的前端選擇。
完整規格
系統呼叫規格應為「完整」,因為它會編碼介面的完整語意,且通常包含系統呼叫相關後端通常需要的所有機器可讀資訊 (包括產生說明文件的後端)。
網路上的 Syscall 資料類型與 C 表示法相符
假設您想將記憶體格式編碼至 FIDL。這項考量不限於系統呼叫參數,因為 C vDSO API 會預期這些參數,但也可能包含從註冊版面配置到網路封包標頭,再到 ZBI 格式的任何內容。這類資料的使用者自然會預期以定義格式使用這些資料,因此如果有方法可將繫結轉譯回適當的格式,FIDL 編碼才能在特定語言中可用。語言繫結已支援對任何可在 FIDL 中定義的類型,進行 FIDL 線路格式的編碼和解碼。如果該記憶體格式的特定位元配置與 FIDL 線路格式完全相符,只要在 FIDL 中說明每個版面配置,每個語言繫結也能支援該格式,而無需進行任何特定格式的工作。
基本 FIDL 類型的線路格式與其自然 C 類似項目的版面配置相符 (且不太可能變更),這並非偶然:目前這些類型是整數和布林原始類型、列舉、位元、陣列和結構體。為簡化操作,並讓系統呼叫繫結有標準方法來算繪預期的 vDSO 輸入內容,我們建議將資料類型的模擬限制在這些 FIDL 類型。這項限制特別禁止使用含有離線資料的類型,以及依據上述作業無知限制的 FIDL 專屬標頭。
向量代表了這裡的有趣案例和可能的例外狀況。Syscalls 會接受以緩衝區形式提供的動態大小資料陣列,並另外提供長度。這種情況自然會以向量繫結模擬。不過,向量線格格式會以 (長度、指標) 的形式提供,而系統呼叫則會預期緩衝區參數為 (指標、長度)。(前者的指標也具有 void*
類型,而後者的指標可以是指向特定類型的指標)。我們可以在 syscall 介面中更新所有緩衝區參數,以便上述原則適用於向量,但將此情況保留為定義例外狀況似乎是合理且明智的做法。在所有地方交換這些參數的工作量相當龐大且風險較高;換句話說,這樣做可避免在序列化向量時,為交換兩個參數而特別指定大小寫的認知負擔。(我們也有 zx_iovec_t
,它本身就是類似向量的類型)。
實作
針對每項新功能,FIDL 和核心/vDSO 維護者會合作並產生 RFC。這項功能獲得核准並導入後,v1 表示法就會更新為使用這項功能。
版本 1 表示法的特殊性將整合至可讓更多後端寫入的適應層,但不考慮系統呼叫原本是在 FIDL 中編碼。要達成這一點,最簡單的方法就是將其 IR 轉換為另一個近似於
fidlc
在擴充語言後產生的最終 IR,這也是逐步找出後續 IR 應有的樣貌的低風險測試環境。隨著 v1 表示法更新為使用新的 FIDL 功能,可適應層就會逐漸減少,最終會刪除。這可讓各種後端在系統實際提供 syscall 宣告支援功能前,先行處理。系統會謹慎更新系統呼叫介面,以便在適當情況下採用新的 FIDL 建模方式。每項變更都會以 RFC 為依據。
系統會產生 syscall C 標頭。
fidldoc
將擴充,以便從 Fidl 程式庫zx
產生系統呼叫說明文件。語言後端將擴充以產生系統呼叫繫結;程式碼將遷移至使用這些繫結。
SDK 會匯出 FIDL 程式庫
zx
。以 FidL 無關方式提供系統呼叫包裝函式和資料類型的獨立程式庫將會淘汰。
成效
這項提案不會對效能造成任何影響。它忠實地將各種語言現有系統呼叫發出邏輯的成效考量,轉移至相關聯的 FIDL 語言後端。雖然在實際情況下,考量到系統呼叫資料類型表示法與我們已維護的語言繫結之間的一致性,Rust 繫結已使用 fuchsia-zircon 類型 crate,以及 C++ libzx 的 LLCPP 繫結,因此針對現今語言後端引入系統呼叫繫結,很可能會產生現有程式碼,只需進行外觀修改。
我們會提出後續 RFC,針對這項計畫提出具體變更建議;如果有,我們會在這些論壇中討論相關效能考量。
人體工學
改善項目:
- 單一可靠資料來源,且有完整的文件。
- 更簡單、更清晰的 BYOR 途徑。
- 更容易進行系統呼叫的演進和維護
- 自動強制執行的系統呼叫政策。
- 現有的系統呼叫相關後端更容易維護 (例如 zxdb 和 fidlcat),而許多新的有價值後端也變得容易編寫 (例如用於為模糊測試引擎產生系統呼叫說明的後端,例如Syzkaller),或用於產生系統呼叫 MSan (記憶體淨化器) 檢查的系統呼叫。
- 語言繫結和系統呼叫包裝函式之間沒有整合問題。
迴歸:
- Syscall 繫結會視為一般由 FIDL 產生的來源,因此相較於目前的等同程式庫,可能會變得較難讀且較不透明。不過,產生來源缺乏說明文件或其可讀性,並非系統呼叫專屬問題,我們應努力以更廣泛的方式解決這項問題,不受這項努力影響。
- 現有語言繫結的責任更重,程式碼面積更大,因此出錯的機率也更高。
回溯相容性
我們將發布後續的 RFC,針對這項計畫提出具體變更;如果有相關的回溯相容性考量,我們會在這些論壇中討論。
安全性考量
如上所述,這項提案將為在我們的消毒劑和模糊測試基礎結構中,更輕鬆地維護系統呼叫支援鋪路。
我們會陸續發布 RFC,針對這項計畫提出具體變更建議;如果有相關安全性考量,我們會在這些論壇中討論。
隱私權注意事項
我們會提出後續 RFC,針對這項計畫提出具體變更建議;如果有相關隱私權考量,我們會在這些論壇中討論。
測試
在這個計畫期間,我們會引入的大部分 (如果不是全部) 內容都應納入現有的子系統和測試機制:
- 新的 FIDL 功能 (例如現有的功能) 會透過
fidlc
和各個相關後端的常規黃金測試進行測試 - 特定語言的系統呼叫繫結會取代我們目前手動維護的等同系統呼叫包裝函式程式庫,因此任何視為適合後者的測試,都可以更新為使用前者。具體來說,我們可以更新 Zircon 的核心測試,以便使用 C++ 系統呼叫繫結,而我們在 //src/lib/zircon/rust crate 中的單元測試也可以更新為使用 Rust 系統呼叫繫結。
- 此外,在本次計畫中修改或重寫的任何其他後端,都會延長或移植現有的測試體系。
說明文件
新的 FIDL 功能將與目前的功能一樣記錄,擴充該語言的官方規格。此外,我們會更新語言繫結的預期值,納入系統呼叫繫結的供應項目。
缺點、替代方案和未知事項
現況充滿負擔:系統呼叫的維護工作負擔過重,沒有我們認為維護其他公開介面時所需的防護措施;對於任何將系統呼叫介面視為輸入內容的軟體,都會造成負擔,如果 Fuchsia 要成功,這類軟體將會變成無窮無盡的數字;它採用了基礎系統介面的未綁定分支,其中包含自己的文件;它與核心平台的期望 (BYOR) 背道而馳;而且會妨礙以標準形式分享基本系統資訊的跨程序。zx_*
其中許多內容都令人不悅,而且大多根深蒂固,因此需要花費大量心力才能解決問題。實現這項提案的目標將是一條漫長而崎嶇的道路。FIDL 和核心/vDSO 維護者需要進行大量且持續性的投資,這些投資可能會對所有人造成干擾。如果沒有維持合理的速度,可能會導致(另一個)長期的過渡狀態。對系統呼叫介面進行必要變更,可能會導致後續作業出現許多問題。
轉移至最終狀態的成本應限於官方 FIDL 工具中持續的系統呼叫支援,這應相對有限且不需太多互動。有人認為 fidlc
中的支援功能必然會失敗,因為我們最終需要某種功能,才能確實瞭解並強制執行完整的系統呼叫語意 (即使如此,在該方面提供冗餘功能仍有其價值)。此外,在我們的語言後端中產生系統呼叫繫結的邏輯,應等同於從 IR 編碼簽名到來源宣告的簡單機器翻譯、應用程式電線編碼,以及執行已維護的 FFI 層,以便呼叫 vDSO。
替代方案:
- 不採取任何行動。
- 我們已處於一個相當難以忍受的狀態,因此才會提出這項影響深遠的提案。不採取行動只會讓目前的維護負擔持續存在,而且隨著時間推移只會越來越嚴重 (隨著新開發人員嘗試移植現有軟體和執行階段,使用者群也會越來越龐大)。
- 我們投入新 IDL 的開發。
- 我們甚至可以放棄與 FIDL 的互通性,只追求介面的靜態、機器可讀說明,這仍可為平台帶來極大價值。
- 不過,Banjo 的歷史記錄很有參考價值,平台可能不希望重蹈覆轍。
- 請勿嘗試變更系統呼叫介面,以便模擬系統呼叫。
- 雖然可行,但這會讓上述設計目標和原則失效,並讓這些原則無法解決的問題持續存在。
既有技術與參考資料
GNU Mach 微核心採用相同的 IDL 定義 syscall 和進程間通訊 (請參閱
.def
檔案這裡,並參閱這裡的編譯器 (MIG)。這個系統目前仍在 Darwin 中使用。//zircon/vdso v1 表示法代表平台首次嘗試將系統呼叫轉換為 FIDL。
Banjo 是一種非 FIDL 平台的 IDL。