RFC-0190:对系统调用的 FIDL 支持 | |
---|---|
状态 | 已接受 |
领域 |
|
说明 | 扩展 FIDL 以支持系统调用声明,并将接口的 FIDL 表示形式设为可信来源。 |
问题 | |
Gerrit 更改 | |
作者 | |
审核人 | |
提交日期(年-月-日) | 2022-07-08 |
审核日期(年-月-日) | 2022-09-22 |
总结
而系统调用(即“系统调用”)表示 Fuchsia 的基础平台接口,Fuchsia 接口定义语言 (FIDL) 目前还不能定义这些接口。但是,这种缺乏支持会导致比讽刺名称更重要的后果。“自带运行时”(以下称“自带运行时”)是我们核心的、宏伟的设计原则之一:它是指协助(并简化)使用任意应用框架和编程语言在 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 的真实性,并且 BY 类型的问题本身是 BY 接口本身的局限性。
开发 IDL 的动机
接口演变和偏移
如果系统调用接口发生更改,此信息的所有不同分支也必须更改。这些叉子包括
- 针对特定语言的系统调用封装容器。
- C 数据类型的专属类比。
- 不涉及发出系统调用,而是需要对系统调用接口进行更抽象的转换的用例。
- 我们的系统调用 Markdown 就是一个典型的例子;另一个是
fidlcat
的接口合成。
- 我们的系统调用 Markdown 就是一个典型的例子;另一个是
除了由 kazoo 赞助的几个异常外,系统调用接口和分支维护人员必须执行大量工作来保持这些功能同步并防止偏移:特别是,系统调用接口维护者必须知道所有分支的位置并记得更新它们,而分支维护者必须知道这些信息的机器可读表示形式,并且必须明确知道每个系统调用。
如果系统调用接口完全编码为 IDL,那么这些分支可以被重新想象为能够以编程方式生成所需信息的后端(因此不再成为真正的分支)。在预期的后端中,没有一个会考虑到特别复杂。在稳定之后,它们的“触摸”时间应该比目前的低得多,以便自动适应对系统调用 IDL 的大多数更改(正如目前的大多数 .fidl 文件更改都不需要更新任何后端一样)。
爬行
视图中只有 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 位。- 偏执:C++ 标准允许未初始化的
bool
既非 true 也非 false!
选择 FIDL 作为 IDL 的动机
之前来自不同 IDL 的课程
该平台之前引入了非 FIDL IDL (Banjo),用于表示驱动程序公开的接口。然而,后来被认为是错误的:被证明是维护负担超过其附加值的,驱动程序作者对其和 FIDL 之间的语法差异感到困惑,并且 FIDL 和 Banjo 之间共享数据类型的自然需求很难实现。从那时起,Banjo 已被废弃,并且我们一直在大规模地改进 FIDL,使其适用于驱动程序用例,并改用 FIDL 来取代它。假设系统调用规范的 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 范式的基本前提条件。在此之前,相关新工具将仅供在平台内部工作的开发者使用。
Syscall 规范使用纯 FIDL
最后(在此过程中可能会切换回去),应仅使用 FIDL 语言规范中的功能来定义系统调用接口。FIDL 后端不需要带外信息即可进行解读(确定是否包含在 SDK 中),而其他 FIDL 代码应可随意导入并使用其数据类型。
fidlc
会强制执行系统调用政策
这里的“系统调用政策”是指任何构成“正确”系统调用声明(纯粹是 FIDL 表示法中信息的函数)的检查。我们在上文中列举了一些政策(尽管使用 C 术语)。
系统调用政策的强制执行应在编译时执行。fidlc
已负责验证系统调用声明的语法是否正确,因此它自然也会判断其语义是否正确。我们希望确保在某个时间点执行后期验证,但将其推迟到稍后的任意验证后步骤,不仅会使工具集成变得复杂,而且会导致用户体验不佳,进而导致用户体验失败所需的时间。
Syscall 绑定
FIDL 语言后端应提供系统调用绑定:也就是说,以该后端的其他绑定的样式呈现接口惯用的系统调用封装容器函数。具体而言,这意味着这些函数签名具有库 zx
数据类型,因为它们已由这些绑定表示。这样可以为任何用户提供与内核的规范互操作,还可以解决将其他单独的绑定和系统调用发出逻辑保持一致的尴尬局面。
如果我们选择不提供系统调用绑定,那么随着 zx
数据类型的出现,可以像普通 FIDL 一样导入这类数据会带来新的尴尬状况。假设 FIDL 客户端从一个通道拉取一个“zx_port_packet_t
”,现在希望以某种方式用它调用“zx_port_queue()
”。如何实现这一目标?如果调用方可以访问将作为该数据包类型的现有绑定作为输入的系统调用封装容器,则这无关紧要;但是,如果封装容器的数据包类型不同,则会增加翻译负担。无论此转换逻辑位于何处,都会导致糟糕的用户体验和糟糕的相互依赖性。最好完全不进行翻译,并且从设计上来说相关代码可以相互理解。
鉴于特定内核对象的系统调用接口具有面向对象的暗示性质,因此对于表示该内核对象的类,系统调用绑定是一种自然的选择。但是,这由后端维护者自行决定。
只需极少的重复劳动即可实现 Syscall 演进
我们希望系统调用演进只需几个简单步骤(至少在常见情况下)即可基本发挥作用:
第 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)。还会出现大量新的系统版本控制问题。Syscall 绑定仅用于在 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 进行。
将生成系统调用 C 标头。
fidldoc
将扩展为从 FIDL 库zx
生成系统调用文档。将扩展语言后端以生成系统调用绑定;代码将迁移到使用它们。
FIDL 库
zx
将在 SDK 中导出。以不依赖于 FIDL 的方式提供系统调用封装容器和数据类型的独立库将被弃用。
性能
此提案没有固有的性能影响。它确实会将针对各种语言的现有系统调用发出逻辑的性能考虑因素移至其关联的 FIDL 语言后端。尽管在实践中,鉴于系统调用数据类型的表示与我们已维护的语言绑定之间的一致性(Rust 绑定已经使用 fuchsia-zircon-types crate,而 C++ libzx 的 LLCPP 绑定)
后续 RFC 将会在此工作的背景下提出具体更改建议;如果有,我们会在相应论坛中讨论相关的性能注意事项。
工效学设计
改进:
- 单一、完整记录的可信来源。
- 改用自带许可 (BYOR) 的方式,更加简洁、便捷。
- 更易于系统调用演进和维护
- 自动强制执行的系统调用政策。
- 依赖于系统调用的现有后端(例如 zxdb 和 fidlcat)更易于维护,并且大量有价值的新后端(例如,用于为模糊引擎(例如Syzkaller)或者用于生成系统调用 MSan(内存排错程序)检查的那个程序)。
- 语言绑定和系统调用封装容器之间不存在集成问题。
回归:
- Syscall 绑定被视为正常的 FIDL 生成的源代码,因此与目前的等效库相比,它们的可读性和模糊性可能会降低。但是,缺少关于生成的源代码或其可读性级别的文档并不是特定于系统调用的问题,我们应努力在更广义上解决,而不考虑这样做。
- 对现有语言绑定承担更多责任,并为发生问题提供更大的代码面。
向后兼容性
后续 RFC 将会在此工作的背景下提出具体更改建议;如果存在相关的向后兼容性注意事项,我们会在这些论坛中讨论相关事项。
安全注意事项
如上所述,此方案将为我们的排错程序和模糊测试基础架构中更易于维护的系统调用支持铺平道路。
在此工作的背景下,后续将有 RFC 提出具体更改建议;如果有相关的安全注意事项,我们会在这些论坛中讨论。
隐私注意事项
后续 RFC 将会在此工作的背景下提出具体更改建议;如果有相关的隐私权注意事项,我们会在这些论坛中讨论相关事项。
测试
在此工作中引入的大多数(如果不是全部)应该放入现有的子系统和测试机制中:
- 新的 FIDL 功能(例如现有的功能)将通过针对
fidlc
和每个相关后端的常规黄金测试进行测试 - 给定语言的系统调用绑定将取代我们目前手动维护的等效系统调用封装容器库,因此,任何我们认为适合后者的测试都可以更新为使用前者。具体而言,我们可以更新 Zircon 的核心测试以使用 C++ 系统调用绑定,还可以将 //src/lib/zircon/rust crate 中的单元测试更新为使用 Rust 系统调用绑定。
- 此外,在此过程中修改的任何其他后端(例如 fidldoc)或重写的后端都会扩展或移植其现有测试机制。
文档
新的 FIDL 功能的记录方式与目前的方式相同,扩展了语言的官方规范。此外,对语言绑定的预期将会更新,以包括系统调用绑定的配置。
缺点、替代方案和未知情况
现状(存在各种负担):它对于系统调用的维护负担过重,使这些系统调用不受我们在维护其他公共接口时认为必要的限制;它不利于任何将系统调用接口作为输入的软件,而这些软件(如果 Fuchsia 作为其基本功能,与 FI 作为其基本功能共享,则被视为其自身的 1 个非规范系统;zx_*
很多方面都没有问题,而且大部分情况根深蒂固,这意味着需要花费大量时间来解决问题。实现这一方案的目标并非易事FIDL 和内核/vDSO 维护人员需要持续进行大量投资,而且这些投资可能会对所有人造成干扰。如果不保持合理的节奏,可能会导致(另一种)拉伸过渡状态。对系统调用界面进行必要的更改可能会在后续操作中招致大量的小问题。
进入最终状态的成本应仅限于官方 FIDL 工具中持续的系统调用支持,这应该相对有限且接触性较低。有人可能会争论,fidlc
中的支持必然是沉浸的,因为我们最终需要一些东西来可靠地理解和执行整套系统调用语义(即使如此,这方面的冗余也很有价值)。此外,在语言后端中生成系统调用绑定的逻辑应该是从 IR 编码签名到源代码声明的简单机器翻译,一种有线编码应用,以及演练已维护的 FFI 层以调用 vDSO。
替代方案:
- 不进行任何操作。
- 我们已经处于非常不敢承受的状态,能够推动这一极具影响力的提案。如果不采取行动,当前的维护负担会持续增加,因为这种负担只会随着时间而加重(并且,随着新开发者尝试移植现有软件和运行时,受众群体会越来越多)。
- 我们投资了一种新的 IDL。
- 我们甚至可以接受与 FIDL 的互操作,而仅仅力求获得接口的静态、机器可读描述,这样我们仍然可以为平台带来可观的价值。
- 不过,Banjo 的历史具有指导意义,并且可能也是平台不希望重申的。
- 忘记尝试更改系统调用接口以便对其进行建模。
- 虽然可行,但这样会吸收上述许多设计目标和原则,并体现出它们打算解决的问题。
早期技术和参考资料
GNU Mach 微内核使用相同的 IDL 来定义其系统调用和进程间通信(请参阅此处的
.def
文件,参阅此处了解编译器 (MIG))。如今,达尔文仍在使用该系统。//zircon/vdso v1 表示法表示平台首次尝试对 FIDL 进行系统调用。
Banjo 是一个非 FIDL 平台 IDL。