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