本文档简要介绍了如何添加新的 Zircon 系统调用。目标受众群体是内核开发者或添加新系统调用的任何人。
请注意,本指南仅介绍了添加系统调用/对象的机制。它不是样式指南或评分标准,也不会提供有关如何确定 API 何时足够稳定或成熟以成为系统接口一部分的任何建议。
由于我们的系统会不断变化,因此本指南可能会过时。抱歉。如果您在按照本指南操作时发现错误或遗漏,请尝试更新本指南。谢谢!
概览
您可以通过多种方式构建更改,以添加新的 Zircon 系统调用 (或对象)。本指南将介绍一种方法,其中包含四个 CL:桩、实现、extra 和注解。
我们将采用“重写历史记录”方法。Zircon 系统调用(目前)不遵循平台版本控制,因此我们将使其看起来像是新系统调用一直存在。为此,我们需要更新已冻结 API 级别的部分 SDK 历史文件。
桩 CL:从 HEAD 处的桩开始
在此 CL 中,您将定义系统调用并提供一个仅返回 ZX_ERR_NOT_SUPPORTED
的桩实现。请务必在此桩 CL 中添加一个核心测试,用于验证调用方是否会崩溃,以及新调用是否会按预期返回错误。
构建系统和 FIDL 编译器会自动为您生成一些样板代码。为了充分利用此功能,您应养成在对 FIDL 文件进行更改后执行默认 build fx build
并运行 fx check-goldens
的习惯。
为说明这一点,我们来看看一个同时添加了新的 Zircon 对象 (counter
) 和新的系统调用 (zx_counter_create
) 的桩 CL。
桩 CL 包含四个部分。
1. 使用 FIDL 定义系统调用
接下来,在现有 .fidl
文件中定义新的系统调用,或根据需要添加新文件。请务必添加注释掉的 @available(added=HEAD)
注解,指明在 HEAD 中添加了新的系统调用(如果添加了新的 Zircon 对象,则添加了对象)。
在极少数情况下,如果要添加新的 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-subtype
//tools/fidl/fidlc/tests/types_tests.cc
中的GoodHandleSubtype
//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 库的,该库与系统调用库共享 zx_common.fidl
。
e. 根据需要扩展 docsgen。
2. 在内核中实现系统调用
在 zircon/kernel/lib/syscalls/ 中的某个位置实现系统调用,前缀为 sys_
,而不是 zx_
。目前,实现只应返回 ZX_ERR_NOT_SUPPORTED
。
3. 添加 lib/zx C++ 封装容器
添加新的 lib/zx 封装容器或扩展现有 lib/zx 封装容器,以便为新系统调用提供 C++ API。请务必对新的 C++ 方法(如果是新的 Zircon 对象,则为类)应用 ZX_AVAILABLE_SINCE(HEAD)
注解。虽然系统调用本身似乎从一开始就存在,但 C++ 封装容器是在 HEAD 中添加的。
4. 添加 core-test
添加一个核心测试,用于验证桩是否返回正确的错误值(并且不会使系统崩溃)。通过在此测试中使用新的 lib/zx
封装容器,您可以确保它也按预期运行。
将桩构建并通过 CQ 后,将其提交。接下来,进入实现 CL。
实现 CL:填充桩
现在,是时候将桩实现替换为真实实现,添加真实测试和真实文档了。构建完成,通过 CQ 审核,发布,然后继续。
额外 CL:添加其余内容
获得使用 C/C++ 绑定的有效实现后,您现在可以添加 Rust 绑定并更新 (fidl_codec
(由 fidlcat
使用):
- display_handle.cc
中的 ShortObjTypeName
- printer.cc
中的 PrettyPrinter::DisplayObjType
上述“extras”列表可能不完整,因此现在是时候查看其他广告和系统调用,看看是否还有其他需要更新的内容(工具?其他语言的绑定?)。提交 extras CL,然后进入最后一步。
注释 CL:将 HEAD 更改为 NEXT
现在,实现和 extra 已到位,请返回并将您在 @available
和 ZX_AVAILABLE_SINCE
注解中添加的值从 HEAD
更改为 NEXT
,以便在下一个稳定 API 级别中提供该系统调用。