添加新的 Zircon 系统调用(或新的 Zircon 对象类型)

本文档是有关添加新 Zircon 系统调用的简短指南。目标受众群体是内核开发者或任何添加新系统调用的人员。

请注意,本指南仅介绍添加系统调用/对象的机制。它不是样式指南或评分标准,也不会就如何判断 API 是否足够稳定或足够成熟以成为系统接口的一部分提供任何建议。

由于我们的系统在不断变化,因此本指南可能会过时。抱歉。如果您在遵循本指南时发现错误或遗漏,请尝试进行更新。谢谢!

如果您要更改现有系统调用使用的结构体,而不是添加新的系统调用,请参阅对系统调用结构体进行版本控制。如果您的新系统调用接受或返回结构体,请为调用方提供一种指定结构体版本的方法(例如 options 中的主题或版本位),以便结构体日后可以演进。

概览

您可以通过多种方式来构建更改,以添加新的 Zircon 系统调用(或对象)。本指南将介绍一种由四个 CL 组成的方法:桩、实现、额外内容和注解。

我们将采用“重写历史记录”方法。Zircon 系统调用(目前)不遵循平台版本控制,因此我们将让新系统调用看起来好像一直存在。为此,我们需要更新一些 SDK 历史记录文件,以反映冻结的 API 级别。

桩 CL:从 HEAD 处的桩开始

在此 CL 中,您将定义系统调用并提供一个仅返回 ZX_ERR_NOT_SUPPORTED 的桩实现。请务必在此桩 CL 中添加核心测试,以验证调用方不会崩溃,并且新调用会按预期返回错误。

构建系统和 FIDL 编译器会自动为您生成一些样板。为了充分利用这一优势,您需要养成在更改 FIDL 文件后执行默认构建 fx build 并运行 fx check-goldens 的习惯。

为了说明这一点,我们来看一个桩 CL,它同时添加了一个新的 Zircon 对象 (counter) 和一个新的系统调用 (zx_counter_create)。

桩 CL 包含四个部分。

1. 使用 FIDL 定义系统调用

接下来,在现有 .fidl 文件中定义新的系统调用,或根据需要添加新文件。请务必添加注释掉的 @available(added=HEAD) 注解,以指明新的系统调用(或对象,如果要添加新的 Zircon 对象)是在 HEAD 处添加的。

在极少数情况下,如果您需要添加新的 Zircon 对象,则需要执行一些额外的步骤。

a. 让 FIDL 编译器了解新的对象类型。FIDL 工具链内置了对象类型知识。这虽然不够优雅,但可以避免一些循环依赖项。您必须更新 FIDL 工具链的某些部分,才能理解新的对象类型。具体而言,请更新:

b. 按照在未更新 fidlc 黄金文件的情况下进行构建时收到的构建错误中提供的说明,更新这些黄金文件。

c. 将新的对象类型添加到 zircon/types.h。

d. 更新 //sdk/history/*/zx.api_summary.json 文件。这些文件适用于公共 zx FIDL 库,该库与 syscall 库共享 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. 添加核心测试

添加核心测试,以验证桩是否返回正确的错误值(并且不会导致系统崩溃)。通过在此测试中使用新的 lib/zx 封装容器,您可以确保它也能按预期运行。

在桩成功构建并通过 CQ 后,将其提交。接下来,继续查看实现 CL。

5. 为新的 Zircon 对象添加 FIDL 语言绑定

如需在 C++ 和 Rust 语言绑定中启用新的 Zircon 对象(即 zx.Handle:COUNTER),还必须更新其他几个方面。这些更新可让语言绑定代码生成器知道如何处理新的 Zircon 对象。

对于 FIDL C++ 语言绑定,请更新:

对于 FIDL Rust 语言绑定,请更新:

实现 CL:填充桩

现在,可以将桩实现替换为实际实现,并添加实际测试和实际文档。构建、通过 CQ、落地,然后继续。

Extras CL:添加其余内容

在通过 C/C++ 绑定实现正常运行后,您现在可以添加 Rust 绑定,并更新 (fidl_codec(由 fidlcat 使用): - display_handle.cc 中的 ShortObjTypeName - printer.cc 中的 PrettyPrinter::DisplayObjType

上述“额外”列表可能不完整,因此现在是时候查看其他系统调用,看看是否还有更多需要更新的内容(工具?其他语言的绑定?)。提交 extra CL 并继续执行最后一步。

Annotations CL: Change HEAD to NEXT

现在,实现和 extra 已落地,请返回并将您在 @available 和 ZX_AVAILABLE_SINCE 注解中添加的值从 HEAD 更改为 NEXT,以便在下一个稳定 API 级别中提供系统调用。