| 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 下已经存在 syscall 接口的 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 赞助的例外情况外,系统调用接口和分支维护人员都必须做大量工作才能保持这些内容同步并防止漂移:特别是,系统调用接口维护人员必须知道所有分支的位置并记得更新它们,而分支维护人员由于缺乏这种信息的可读机器表示法,必须知道每个系统调用并明确列出它们。
如果系统调用接口完全以 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 语言中表示系统调用接口的复杂性。如果使用支持多种语言的 IDL,则可以避免或最大限度地减少此类问题。
政策执行
我们希望针对系统调用和数据类型强制执行多项政策。通过 IDL 化,后端将能够访问这种信息的机器可解释表示形式,届时可以轻松编写和维护用于强制执行政策的工具。
下面列举了一些数据类型政策示例(以 C 表示),这些政策源自我们在内核和用户空间之间共享数据的方式:
- 固定大小的结构,或包含这些结构的动态大小数组
- 接受任何其他内容都会使数据共享和解读变得复杂。
- 无间接寻址
- 数据需要完全可
memcpy,并且可以在与构建时不同的地址空间内被理解;源地址空间中指向数据的编码引用/指针可能会悬空,变得无法理解。(zx_iovec_t是一个例外,会进行特殊处理。)
- 数据需要完全可
- 没有嵌入式句柄
- 嵌入在布局中的句柄很容易被忘记关闭(或被隐式“借用”)。
- 没有布尔值字段
bool在内存中占用 8 位,但仅提供 1 位信息。为了提高空间效率,我们更倾向于使用位字段来传递该 1 位。- Paranoia:C++ 标准允许未初始化的
bool既不是 true 也不是 false!
将 FIDL 用作该 IDL 的动机
来自不同 IDL 的之前课程
该平台之前引入了一种非 FIDL IDL:Banjo,用于表达驱动程序公开的接口。不过,后来人们意识到这是一个错误:它带来的维护负担超过了其附加价值,驱动程序作者对它与 FIDL 之间的语法差异感到困惑,并且难以实现 FIDL 和 Banjo 之间共享数据类型的自然愿望。自此之后,Banjo 便被废弃,并且我们一直在努力改进 FIDL,以用于驱动程序用例,并使用 FIDL 来取代 Banjo。假设系统调用规范的 IDL 有充分的动机,那么可以合理地预期,为此目的而设计的新 IDL 会遇到同样的陷阱。
绑定开发
FIDL 语言绑定依赖于进程间消息传递(例如,通过渠道),因此必须已经了解有助于实现该通信的系统调用子集。特别是,它们已经开始管理围绕这些系统调用的 FFI 封装器。如果这些系统调用以机器可读的形式呈现,绑定将能够更轻松地构建和维护 FFI 层;但是,如果对系统调用的理解不是源自 FIDL,绑定将需要更多信息,或者最终会解读两个不同的 IDL IR(中间表示)。
在数据类型方面,我们目前维护的库可单独表示这些类型,与 FIDL 语言绑定分开,但同时又希望实现一定程度的互操作性。也就是说,我们自然而然地希望两者在大致相同的方面都符合语言习惯,以便代码可以轻松地将它们一起使用,而无需处理不兼容的拼写或样式决策;对于内核对象句柄和“zx_status_t”,我们希望它们以相同的方式表示。最自然的方式是让绑定显式使用数据类型库,而这正是它们目前所做的。因此,将这些内容分开呈现在很大程度上是一种虚假的自由度,如果这些内容来自同一位置,肯定会对绑定维护人员和用户都有好处(更多相关信息请参阅下文)。
Polyglot 的性质
根据其与 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 工具中相关支持的熟悉程度,从而简化维护工作。
从长远来看,应避免 FIDL 语言对使用为系统调用数据类型引入的新声明类型的限制,原因如下:
- 如上文所述,我们希望规范使用“纯”FIDL,因此任何形式的降级都会在精神上甚至在实践中与此背道而驰;
- 这些类型将通过出现在库
zx中,被每个语言后端大规模使用; - 其
zx实例将以规范形式表示系统信息,此类信息应可通过任何传输方式自由流动; - 围绕系统调用数据类型建模的相关问题实际上并非特定于系统调用;它们更普遍地适用于内存格式的建模,并且可能具有更广泛的应用。
- 很大一部分
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 中描述每个布局,每种语言绑定也可以支持该格式,而无需进行新的特定于格式的工作。
基本 FIDL 类型的有线格式与其自然 C 类比物的布局一致,这绝非偶然(而且这种情况不太可能发生变化):目前,这些类型是整数和布尔值原语、枚举、位、数组和结构。为简单起见,并为了给系统调用绑定提供一种呈现预期 vDSO 输入的规范方式,我们建议将数据类型的建模限制为仅使用这些 FIDL 类型。这尤其禁止使用具有行外数据的类型,以及根据上述操作性无知约束的 FIDL 特定标头。
矢量在这里代表了一种有趣的情况,也可能是一种例外情况。系统调用接受动态大小的数据数组,这些数据数组以缓冲区形式提供,并单独提供长度。这种情况自然可以通过矢量绑定进行建模。不过,向量的线格式为 (length, pointer),而系统调用则需要将缓冲区参数指定为 (pointer, length)。(前者的指针也具有 void* 类型,而后者可以是特定类型的指针。)我们可以更新系统调用接口中的所有缓冲区参数,以便上述原则适用于向量,但将此情况作为定义异常保留似乎是合理且谨慎的做法。在所有位置交换这些形参所涉及的工作量非常大,而且风险相当高;这样做的好处是,可以避免因特殊处理向量的序列化来交换两个形参而造成的最低认知负担。(我们还有 zx_iovec_t,它本身就是一种类似向量的类型。)
实现
对于每项新功能,FIDL 和内核/vDSO 维护人员将协作制定 RFC。该功能获得批准并实现后,v1 表示法将更新为使用该功能。
v1 表示法的特异性将整合到一个自适应层中,更多后端可以基于该层编写,而无需考虑系统调用最初在 FIDL 中是如何编码的。实现此目的的一种简单方法是将 IR 转换为近似于最终 IR 的另一个 IR,当完成语言扩展时,
fidlc将产生该最终 IR;这也是一个低风险的试验场,可用于逐步确定后者的外观。随着 v1 表示法更新为使用新的 FIDL 功能,自适应层可以逐渐缩小,最终达到删除的程度。这样一来,各种后端就可以在系统调用声明实际可用之前继续进行相关支持。系统调用接口将根据需要谨慎更新,以满足新的 FIDL 建模方式。每项此类更改都将根据 RFC 进行。
系统将生成 syscall C 头文件。
fidldoc将扩展为从 FIDL 库zx生成系统调用文档。将扩展语言后端以生成系统调用绑定;代码将迁移到使用这些绑定。
FIDL 库
zx将在 SDK 中导出。以 FIDL 不可知方式提供系统调用封装容器和数据类型的独立库将被弃用。
性能
此提案本身不会带来任何效果方面的影响。它忠实地将各种语言的现有系统调用发布逻辑的性能考虑因素转移到其关联的 FIDL 语言后端。虽然在实践中,考虑到系统调用数据类型的表示形式与我们已维护的语言绑定之间的连贯性(Rust 绑定已使用 fuchsia-zircon-types crate,而 LLCPP 绑定已使用 C++ libzx),但为当前语言后端引入系统调用绑定很可能相当于生成当前已存在的代码,只需进行外观修改。
后续将有 RFC 提议在此次努力的背景下进行具体更改;如果存在,相关性能考虑因素将在这些论坛中讨论。
工效学设计
改进:
- 单一的、有完整文档记录的可靠来源。
- 更清晰、更轻松的 BYOR 迁移途径。
- 更易于进行系统调用演变和维护,
- 自动强制执行的系统调用政策。
- 现有依赖于系统调用的后端(例如 zxdb 和 fidlcat)变得更易于维护,并且可以轻松编写许多新的有价值的后端(例如,用于为模糊测试引擎(例如Syzkaller),或者一个用于生成系统调用 MSan(内存清理器)检查)。
- 语言绑定和系统调用封装容器之间没有集成问题。
回归:
- 系统调用绑定将视为正常的 FIDL 生成的源代码,因此与当前等效的库相比,它们可能会变得更难读懂,也更晦涩难懂。不过,生成的源代码缺乏文档或可读性较低并不是特定于系统调用的问题,我们应努力更普遍地解决此问题,而不论此工作是否完成。
- 现有语言绑定的责任更多,代码表面积更大,因此出错的可能性也更高。
向后兼容性
后续将有 RFC 提议在此工作背景下进行具体更改;如有,将在这些论坛中讨论相关的向后兼容性注意事项。
安全注意事项
如上所述,此提案将为我们的 Sanitizer 和模糊测试基础设施中更易于维护的系统调用支持铺平道路。
后续将有 RFC 提议在此工作背景下进行具体更改;如有,相关安全注意事项将在这些论坛中讨论。
隐私注意事项
后续将有 RFC 提议在此工作背景下进行具体更改;如果存在相关隐私权考虑因素,将在这些论坛中进行讨论。
测试
在此次努力中引入的大部分(如果不是全部)内容都应纳入现有的子系统和测试方案:
- 新的 FIDL 功能(与现有功能一样)将通过
fidlc和每个相关后端的常规全套黄金测试进行测试 - 给定语言的系统调用绑定将取代我们目前手动维护的等效系统调用封装容器库,因此,对于后者,任何被视为合适的测试都可以更新为使用前者。具体来说,我们可以更新 Zircon 的核心测试以使用我们的 C++ 系统调用绑定,并且可以更新 //src/lib/zircon/rust crate 中的单元测试以使用 Rust 系统调用绑定。
- 此外,在此次工作中修改(例如 fidldoc)或重写的任何其他后端都会扩展或移植其现有的测试方案。
文档
新 FIDL 功能的文档将与当前功能的文档相同,从而扩展该语言的官方规范。此外,我们还将更新对语言绑定的预期,以纳入系统调用绑定的提供。
缺点、替代方案和未知因素
现状存在诸多负担:它给系统调用的维护带来了过度的负担,使它们在维护其他公共接口时缺乏我们认为必要的安全措施;它对任何将系统调用接口作为输入的软件都不友好,而如果 Fuchsia 要取得成功,这类软件的数量将是无限的;它具有我们基本系统接口的无关联分支,包括其自己的文档;它与核心平台愿景 (BYOR) 相悖;并且它以规范形式阻碍了基本系统信息的跨进程共享(因为 zx_* 类型未在 FIDL 中表示)。
其中很多都是不尽如人意之处,而且很多问题都根深蒂固,这意味着需要付出很多努力才能解决问题。实现此提案的目标将是一条漫长而坎坷的道路。FIDL 和内核/vDSO 维护人员需要进行大量持续的投资,这些投资有时可能会对所有人造成干扰。如果无法保持合理的进度,可能会导致(再次)出现漫长的过渡状态。对系统调用接口的必要更改可能会导致后续操作出现一系列问题。
进入最终状态的费用应仅限于官方 FIDL 工具中的持续系统调用支持,这应该是相对有限且低接触的。有人可能会认为,fidlc 中的支持是必然的沉没成本,因为我们最终需要某种东西来可靠地理解和强制执行完整的系统调用语义(即使这样,这方面的冗余也是有价值的)。此外,在我们的语言后端中生成系统调用绑定的逻辑应相当于从 IR 编码的签名到源代码声明的直接机器翻译、有线编码的应用,以及调用到 vDSO 的已维护 FFI 层的练习。
替代选项:
- 不执行任何操作。
- 我们已经处于一种令人难以忍受的状态,这促使我们提出了这项影响深远的提案。如果不采取行动,当前的维护负担将会继续存在,并且随着时间的推移只会加剧(随着新开发者尝试移植现有软件和运行时,受影响的受众群体也会越来越大)。
- 我们投资于新的 IDL。
- 我们甚至可以考虑与 FIDL 的互操作性,并仅以接口的静态、机器可读描述为目标,这仍然可以为平台带来相当大的价值。
- 不过,Banjo 的历史经验值得借鉴,而且平台可能也不希望重蹈覆辙。
- 放弃尝试更改系统调用接口以对其进行建模。
- 虽然可以这样做,但会放弃上述许多设计目标和原则,并使它们旨在解决的问题根深蒂固。
在先技术和参考资料
GNU Mach 微内核使用相同的 IDL 来定义其系统调用和进程间通信(请参阅此处的
.def文件,并参阅此处了解编译器 [MIG])。该系统至今仍在达尔文使用。//zircon/vdso v1 表示平台首次尝试将系统调用 FIDL 化。
Banjo 是非 FIDL 平台 IDL。