本文件是新增 Zircon 系統呼叫的簡短指南。目標對象是核心開發人員,或任何新增系統呼叫的人。
請注意,本指南僅涵蓋新增系統呼叫/物件的機制。這份文件並非樣式指南或評分標準,也不會提供任何建議,說明如何判斷 API 是否夠穩定或成熟,足以成為系統介面的一部分。
由於我們的系統會持續變更,因此這份指南可能已過時。抱歉,如果您在遵循本指南時發現錯誤或遺漏,請嘗試更新。感謝您!
如果您要變更現有 syscall 使用的結構,而不是新增 syscall,請參閱「建立 syscall 結構版本」。如果新的系統呼叫會採用或傳回 struct,請提供方法讓呼叫端指定 struct 版本 (例如 options 中的主題或版本位元),以便日後更新 struct。
總覽
您可以透過多種方式建構變更,新增 Zircon 系統呼叫 (或物件)。本指南將說明由四個 CL 組成的方法:虛設常式、實作、額外項目和註解。
我們將採用「重寫歷史記錄」方法。Zircon syscalls (目前) 不會遵循平台版本管理,因此我們會讓新的 syscall 看起來像是原本就存在。為此,我們需要更新凍結 API 級別的一些 SDK 記錄檔。
Stub CL:從 HEAD 的 Stub 開始
在這個 CL 中,您將定義 syscall 並提供虛設常式實作,只傳回 ZX_ERR_NOT_SUPPORTED。請務必在這個虛設常式 CL 中加入核心測試,確認呼叫端不會異常終止,且新呼叫會如預期傳回錯誤。
建構系統和 FIDL 編譯器會自動為您產生部分樣板。如要充分利用這項功能,請養成習慣,在變更 FIDL 檔案後執行預設建構作業 fx build,並執行 fx check-goldens。
為了說明,我們來看看虛設常式 CL,其中新增了 Zircon 物件 (counter) 和系統呼叫 (zx_counter_create)。
虛設常式 CL 有四個部分。
1. 使用 FIDL 定義 syscall
接著,在現有的 .fidl 檔案中定義新的系統呼叫,或視情況新增檔案。請務必新增註解排除的 @available(added=HEAD) 註解,指出新的 syscall (或物件,如果要新增 Zircon 物件) 已新增至 HEAD。
在較少見的情況下,如要新增 Zircon 物件,您需要採取一些額外步驟。
a. 教導 FIDL 編譯器新的物件類型。FIDL 工具鍊內建了物件類型的知識。雖然這個方法不夠精緻,但可避免部分循環相依。您必須更新部分 FIDL 工具鍊,才能瞭解新的物件類型。具體來說,請更新:
//tools/fidl/fidlc/src/properties.h中的HandleSubtype//tools/fidl/fidlc/src/names.cc中的NameHandleSubtype//tools/fidl/abi-compat/src/compare/handle.rs的HandleType//tools/fidl/fidlc/schema.json中的handle-subtypeGoodHandleSubtype(//tools/fidl/fidlc/tests/types_tests.cc)//tools/fidl/lib/fidlgen/types.go中的HandleSubtype和ObjectType常數//tools/fidl/fidlgen_rust/codegen/ir.go中的handleSubtypes、handleSubtypesFdomain和objectTypeConsts
b. 如要更新 fidlc 黃金檔案,請按照建構時未更新而出現的建構錯誤指示操作。
c. 將新的物件類型新增至 zircon/types.h。
d. 更新 //sdk/history/*/zx.api_summary.json 檔案。這些是公用 zx FIDL 程式庫,與 syscall 程式庫共用 zx_common.fidl。
e. 視需要擴充 docsgen。
2. 在核心中實作 syscall
在 zircon/kernel/lib/syscalls/ 的某處實作系統呼叫,並使用 sys_ 前置字元,而非 zx_。目前,實作應只會傳回 ZX_ERR_NOT_SUPPORTED。
3. 新增 lib/zx C++ 包裝函式
新增或擴充現有的 lib/zx 包裝函式,為新的系統呼叫提供 C++ API。請務必將 ZX_AVAILABLE_SINCE(HEAD) 註解套用至新的 C++ 方法 (如果是新的 Zircon 物件,則套用至類別)。雖然系統呼叫本身似乎從一開始就存在,但 C++ 包裝函式是在 HEAD 新增。
4. 新增核心測試
新增核心測試,驗證虛設常式是否傳回正確的錯誤值 (且不會導致系統異常終止)。在這項測試中使用新的 lib/zx 包裝函式,即可確保其運作正常。
建構虛設常式並通過 CQ 後,請將其提交。接著,請前往實作 CL。
5. 為新的 Zircon 物件新增 FIDL 語言繫結
如要在 C++ 和 Rust 語言繫結中啟用新的 Zircon 物件 (即 zx.Handle:COUNTER),您必須更新其他幾個部分。這些更新可讓語言繫結程式碼產生器瞭解如何處理新的 Zircon 物件。
如要更新 FIDL C++ 語言繫結,請更新:
//src/lib/fidl_codec/display_handle.cc中的ShortObjTypeName//src/lib/fidl_codec/printer.cc中的DisplayObjType- 將物件標頭新增至
//sdk/lib/fidl/hlcpp/include/lib/fidl/cpp/internal/header.h //tools/fidl/lib/fidlgen_cpp/handles.go中的handleSubtypeConsts//tools/fidl/lib/fidlgen_cpp/name_transforms.go中的zxNames
如要更新 FIDL Rust 語言繫結,請更新:
//sdk/rust/zx/src/handle.rs中的ObjectType//src/lib/fuchsia-async/src/handle/mod.rs中的invoke_for_handle_types
實作 CL:填入虛設常式
現在,請將虛設常式實作項目替換為實際項目,並新增實際測試和實際說明文件。建構、通過 CQ、提交,然後繼續。
Extras CL:新增其餘內容
使用 C/C++ 繫結完成實作後,即可新增 Rust 繫結,並更新 (fidl_codec (由 fidlcat 使用):
- display_handle.cc 中的 ShortObjTypeName
- printer.cc 中的 PrettyPrinter::DisplayObjType
上述「額外」清單可能不完整,因此建議您查看其他系統呼叫,確認是否有更多需要更新的項目 (工具?其他語言的繫結?)。提交額外 CL,然後繼續進行最後一個步驟。
註解 CL:將 HEAD 變更為 NEXT
實作和額外項目都已完成,請返回並將 @available 和 ZX_AVAILABLE_SINCE 註解中新增的值從 HEAD 變更為 NEXT,以便在下一個穩定 API 級別中使用系統呼叫。