Tock 内核外部依赖政策:从 2022-12-02 核心会议到 doc/ExternalDependencies.md 的落地 操作系统嵌入式嵌入式OS【免费下载链接】tockA secure embedded operating system for microcontrollers项目地址https://gitcode.com/gh_mirrors/to/tock点击查看免费下载导读本文以 Tock 操作系统 2022 年 12 月 2 日的核心开发者会议纪要doc/wg/core/notes/core-notes-2022-12-02.md为主体系统梳理 Tock 内核引入 Rust 外部 crate外部依赖的完整决策脉络与最终落地政策。你会看到为什么 Tock 长期拒绝外部依赖、PR #3312 提出的单一全局 crate 命名空间方案为何被否决、按域拆分 capsules 多 crate 的结构如何成为共识以及今天的仓库中capsules/aes_gcm如何通过ghash外部依赖实现 AES-GCM。读完本文你将掌握 Tock 外部依赖的准入标准、crate 分层规则、审批例外与 PR 提交流程并能对照 doc/ExternalDependencies.md 与源码验证每一项政策。一、会议背景与议程概览2022 年 12 月 2 日的 Tock 核心会议Core Notes由 11 位核心维护者出席包括 Hudson Ayers、Brad Campbell、Philip Levis、Amit Levy、Pat Pannuto、Leon Schuermann、Johnathan Van Why 等。会议主要包含两部分成员进度更新Updates涵盖 Google 团队对 MapCell 安全性与 grant/Tock 进程机制的探讨、许可证头检查工具、VirtIO 设备在 QEMU 板上的支持、tock-registers的matches_any修复、elf2tab重写、外部依赖 PR #3312 等。核心议题外部依赖政策PR #3312这是本次会议的重头戏最终演化为仓库中的 doc/ExternalDependencies.md 正式政策文档。二、会前状态更新Updates六项在途工作2.1 MapCell 安全性与 Tock 进程机制的新动议Philip Levis 报告正在与 Google 的另一个团队接洽对方有一批与MapCell 非安全性MapCell unsafety相关的 PR以及一些可能推动 grant 与 Tock 进程机制演进的新用例。会议计划在当月月底前形成详细的技术讨论。2.2 许可证头检查工具Johnathan Van Why 启动了license header checking tool许可证头检查工具的开发——即后来落地于 tools/ci/license-checker 的 CI 校验设施用于自动化核查仓库内每个文件是否携带正确的 SPDX 许可证头如 capsules/aes_gcm/Cargo.toml 顶部所示的三行Licensed under.../SPDX-License-Identifier注释。2.3 VirtIO 设备在 QEMU 板上的支持PR #3110Leon Schuermann 推进了让VirtIO 设备在 QEMU 板上工作的 PR #3110。他指出这是 Tock 建立Ethernet以太网支持的关键组件之一该 PR 引入了可用于 CI 测试基础设施的虚拟 RNGvirtual RNG并添加了虚拟网卡virtual network card——其工作方式类似于 Linux 在 QEMU 中通过网络通信的方式是 Tock 最终定义 Ethernet HIL硬件抽象层时会使用的少数设备之一。从当前仓库结构看这一方向已沉淀为独立的chips/virtiocratechips/virtio包含 21 个 Rust 源文件为 Tock 的 QEMU 与 x86 虚拟化测试提供 VirtIO 后端支持。2.4tock-registers的matches_any修复PR #3336Hudson Ayers 提交了 PR #3336修复tock-registers中matches_any对多 bit 字段不生效的问题。其根因在于原有接口通过把多个字段值相加的方式构造匹配值导致丢失了哪些字段被组合进来的信息因而无法正确实现多 bit 字段匹配。Hudson 的解决方案是新建一个接口略有不同的新函数将旧函数重命名为any_matching_bits_set该命名更贴合在一系列 bit 上进行匹配的高效语义。在今天的仓库中tock-registers已作为核心内核唯一的外部依赖例外被重导出到 kernel/src/utilities/mod.rs其中就包含tock_registers::fields::{Field, FieldValue}、register_bitfields、register_structs等宏与类型——这正对应会议中修复多 bit 字段匹配语义的讨论主题。2.5elf2tab重写Brad Campbell 正在重写elf2tab工具将 ELF 转换为 TBF 格式、打包 Tock 应用的构建工具。核心思路是去掉过去积累的大量自定义逻辑改为正确地解析 ELF。当前仓库中的实现见 tools/elf2tab。2.6 版权copyrightPRHudson 提到版权 PR 已达成一些良好结论只需整合反馈。这与 Johnathan 的许可证检查工具同属开源合规基础设施范畴。三、核心议题外部依赖政策PR #33123.1 为什么 Tock 长期以来排斥外部依赖会议围绕 PR #3312 展开但真正要回答的第一个问题是Tock 为什么默认不使用外部依赖Brad Campbell 在 OpenTitan 电话会上已讨论过此话题其要点在最终政策文档 doc/ExternalDependencies.md 中被明确固化审计成本Auditing限制外部库让审计 Tock 代码只需检查 Tock 仓库内的代码本身。Tock 对unsafe的使用极为克制且要求理由清晰而外部库的unsafe用法难以验证且会随外部库演进而变化传递依赖的隐性扩张外部 crate 通常自带依赖引入一个外部 crate 往往拖入多个截至 2023 年 5 月cargo 仍没有稳健的工具去审计并禁止依赖层级中的unsafe依赖链不可见外部 crate 的依赖链对使用者基本是隐藏的缺少自动化工具时只能靠人工管理。3.2 被否决的方案单一全局 crate tock_extern::命名空间Brad 最初提出了一个受控引入的机制设计在 Tock 仓库中设立一个全局 crate该 crate 是唯一被允许声明外部依赖的 crateboard crate 除外任何想用外部依赖的 crate 都依赖这个 crate。其动机来自 Rust 新版 edition 不再要求extern crate声明导致诸如ghash这样的模块来源不清晰显式 crate 后外部导入可写成tock_extern::ghash从而获得明确的命名空间。但这一方案在会议中被逐步否决理由如下审计复杂度不减反增Amit Levy若某些依赖被引入却未被使用判断哪些依赖需要审计反而更难——一个 capsule 可能自己不直接用该依赖却经由另一个 capsule 使用或在不明显的名字下被重导出HIL 化思路不可行Hudson / Leon / Brad为外部依赖定义 trait本质上是为外部依赖做 HIL 抽象困难重重。以ghash为例ghash使用自定义类型这些类型需要回传给其他函数调用宏也基本不可能。Leon 还指出即便ghash只服务 AES-GCM若某个板子只有硬件 hash 实现仍需要重写 AES-GCM 中大量使用ghash的部分抽象的对象应是功能而非库Amit我们不想为了 ghash 而暴露 ghash而是要验证应用头签名这类功能。不同板子可能用硬件实现、软件实现内部才用ghash因此应抽象功能而不是具体库。但与会者同时澄清了一个关键边界Brad、LeonAES 这类可能或不可能由硬件在不同平台暴露的功能确实应当通过公共抽象使用但这不能推广到所有引入外部依赖的动机如调试工具、app signing 等。Amit 的结论是为每个外部依赖都加一层 wrapper trait 成本非零不值得。3.3 达成的共识按域拆分 capsules crate会议最终收敛到一条清晰的路径由 Amit 提出、Hudson 赞同、Leon 细化核心 capsules cratecore capsules包含几乎所有板子都必需的基础设施与虚拟器virtualizers例如 console、time、alarm 等——绝不允许外部依赖其他 capsule crate可按领域任意划分如net、crypto、com允许按 case-by-case 引入外部依赖。按 Amit 的直觉大约 10 个分类即可如core、net、crypto、com直接依赖而非间接既然拆成了多个 crate外部依赖应当被直接依赖直接写在 Cargo.toml 中而非通过中间 crate 间接引入——引入一个外部依赖与引入许多外部依赖在审计上是不同的名单制禁止依赖清单而非允许清单Brad 问是否要维护允许外部依赖的 crate 清单Amit 纠正为维护不允许外部依赖的 crate 清单且每个外部依赖仍要逐案评估有的依赖会比别的引来更多反对比如某个仅调试用、只在需要的板子上启用的依赖完全没问题。会议当场敲定了初始禁止清单all list of crates disallowed to have any external dependencies, at least initially禁止引入外部依赖的 crate 类型说明kernel核心内核 cratecore capsules含 virtualizers几乎所有板子都依赖的基础 capsulelibrariesTock 仓库内的库 cratearch架构相关 crateHudson 补充既然kernelcrate 被禁止引入外部依赖Brad 最初担心的命名空间需求tock_extern::也就不再必要。3.4 拆分粒度的权衡从每个 capsule 一个 crate到分类 crateHudson 曾提议除 core 外每个 capsule 独立成 crate但 Brad 立即指出这不好会给每个 board 增加大量 crate 与文件。Amit 建议约 10 个分类core、net、crypto、com……也可以从最先想要外部依赖的那一个 capsule开始拆。Leon 给出了最小可行结构至少要有一个corecapsules crate再加一个大的contribcapsules crate 收纳所有不引入外部依赖的其余 capsule之后每新增一个依赖再逐步拆分。Hudson 总结会先按此结构实现这能让外部依赖问题最快推进。这一先拆 core 与 extra再按需增量拆分的路径正是今天仓库的实际形态。四、政策落地doc/ExternalDependencies.md 的完整内容PR #3312 的讨论成果最终固化为 doc/ExternalDependencies.md。其政策总纲是Tock 的总体政策是内核不包含不属于 Rust 标准库的外部依赖即tock/tock仓库之外的 rust crate。但在有限、逐案case-by-case的基础上并配以适当的保障措施Tock 内核可以使用外部依赖。该文档仅适用于 Tock 内核二进制本身不适用于用户态或其他工具/二进制。4.1 内部 crate 依赖结构假设政策文档明确描述了 Tock 内部各类 crate 的角色与依赖方向doc/ExternalDependencies.mdcrate 类型目录依赖关系规则kernel cratekernel/不依赖 arch/chip/board/capsule cratearch cratesarch/只依赖 kernel crate 与其他 arch cratechip crateschips/只被 board crate 或其他 chip crate 依赖board cratesboards/不被任何其他 Tock 内部 crate 依赖capsule cratescapsules/只被其他 capsule crate 或 board crate 依赖由此得出核心原则外部依赖加在反向依赖更少的 crate 上影响更小政策对这类 crate 更宽松——board crate无反向依赖最宽松kernel crate被一切依赖最严格。4.2 依赖选择三准则每个外部依赖须满足三条严格准则doc/ExternalDependencies.md提供重要功能Provide Important Functionality外部 crate 提供 Tock 开发者难以或无法自行实现的重大功能。典型如密码学库编写既正确又抗攻击的加密代码极具挑战采用经过验证的高质量加密库而非 Tock 自研加密代码能提升内核安全性过程宏支持syn、quote、proc-macro2事实上已成为 Rust 语言核心组成部分它们让tock-registers能向硬件外设暴露健全、可高度测试的接口。项目可理解性Project Understandabilitycrate 应聚焦于某一特定、可理解的操作或功能集代码质量高、易于自信地审计且只使用标准、常见的 Rust 生态机制。子依赖有限Limited Sub-dependenciescrate 引入的传递依赖越少越可能被接受没有固定阈值逐案评估。4.3 三类位置的差异化政策Board-Specific板级doc/ExternalDependencies.mdboard crate 被视为特定用例、由对应芯片/板维护者管理审计政策最灵活。典型场景是无线协议时序难以做对、认证昂贵。注意只有 board crate 自己能在Cargo.toml里包含该外部依赖若其他 crate 想间接使用可通过wrapper-trait抽象虽非必须但在某些场景有用。Capsule-Specificcapsule 级doc/ExternalDependencies.mdcapsule 提供半可信基础设施如非芯片特定的外设驱动。政策明确capsules/corecrate含几乎所有板子运行所必需的驱动、常用基础设施与虚拟器virtualizers不得有任何外部依赖capsules/extracrate收纳不适合其他 capsule crate 的杂项驱动与抽象不得有任何外部依赖其他 capsule crate可以按逐案评估引入外部依赖粒度可以从整个子系统如 TCP/IP 栈到单个提供隔离功能的模块。Core Kernel核心内核doc/ExternalDependencies.mdarch/、chips/、kernel/的 crate不允许任何外部依赖用户无法像 board/capsule 那样选择退出必须vendor 进 Tock 仓库。唯一例外是由 Tock 项目自身维护、对更广泛的 Rust/嵌入式社区有重大价值、必须在独立仓库中继续开发的 crate。4.4 两个已批准的核心内核例外政策目前批准了两个核心内核例外doc/ExternalDependencies.md① tock-registerstock/tock-registers提供在chips/中广泛使用的 MMIO 寄存器接口独立开发理由鼓励对外的向后兼容考虑、鼓励定期发布、便于外部用户参与问题报告与提案、鼓励外部贡献允许依赖syn、quote、proc-macro2过程宏需解析/生成非平凡的 Rust 代码quote硬依赖proc-macro2以及唯一传递依赖unicode-ident无依赖、小巧简单、crates.io 历史下载量前 30测试可用外部 dev-dependencies不进内核构建产物。在本次会议的语境下这个例外尤为相关Hudson 汇报的 PR #3336matches_any修复正是针对 tock-registers 这个例外 crate而仓库中 kernel/src/utilities/mod.rs 通过pub use tock_registers::...将其重导出为内核基础设施register_bitfields、register_structs等宏被整个chips/与arch/广泛使用。② flux-rs通过refinement types精化类型支持 Rust 代码形式化验证是可选依赖、仅测试期使用不影响构建产物因 cargo 将dev-dependencies与cfg(test)硬绑定而 flux 需要验证最终构建产物如架构相关的上下文切换逻辑而不能运行于cfg(test)下故列为optional 依赖会导致其及依赖进入Cargo.lockflux-attrs、flux-attrs-impl、flux-rs、proc-macro2、quote、syn、unicode-ident使用约定精化位于文件末尾独立模块、必须由#[cfg(feature flux)]门控、fluxfeature 不得用于其他任何地方。4.5 引入方式、文档义务与 PR 模板引入方式doc/ExternalDependencies.mdcapsule 级与 board 级外部依赖都直接写在各自Cargo.toml中直接使用文档义务doc/ExternalDependencies.md每个在Cargo.toml中包含外部依赖的 crate必须在 README 中写一节External Dependencies列出每个依赖及其依赖树依赖树用cargo tree生成依赖变更时须同步更新PR 模板doc/ExternalDependencies.md提交含外部依赖的 PR 时须在描述中粘贴以下模板并为每项写一句话说明#### External Dependency Requirements 1. **Provides Important Functionality**: 2. **Project Maturity**: 3. **Limited Sub-dependencies**: 4. **Included as a board or optional capsule**:4.6 设计目标与备选方案的取舍政策文档最后明确记录了本次会议及后续多轮讨论收敛出的设计目标doc/ExternalDependencies.md不需要该功能的板子能确保依赖不进内核构建、不必编译该依赖板子对自己的构建内容有裁量权外部依赖在 Tock 代码库中的所有使用都显式且明显外部依赖在代码树中的位置清晰一致有统一的文档格式添加外部依赖没有过度的样板开销。这些目标推导出两个关键设计决策其一crate 是 Rust 最小的编译单元外部依赖必须通过新增到 Tock 源码树的 crate引入从而可在特定构建中单独包含或排除同时 crate 也提供了标识正在引入外部依赖的命名空间其二避免为依赖做 trait/HIL 包装即核心 capsule/模块使用 Tock 定义的 trait由 wrapper 用外部依赖实现之——尽管架构上有优势但实现与维护 wrapper 的开销被认为远超收益故不采用。五、仓库现状验证政策如何落到代码里5.1capsules/aes_gcm会议中讨论的ghash用例会议中反复提及的ghash用例在今天的仓库中落地于独立的capsules/aes_gcmcratecapsules/aes_gcm/Cargo.toml 中直接声明外部依赖ghash 0.4.4同时仅依赖内部kernelcrate——这正是capsule 级外部依赖直接写在 Cargo.toml政策的实现capsules/aes_gcm/src/aes_gcm.rs 中use ghash::{GHash, Key}与ghash::universal_hash::{NewUniversalHash, UniversalHash}Aes128Gcm结构体持有OptionalCellGHash作为 GHASH 累加器aes_gcm.rs该 capsule 在底层 AES 之上实现 AES-GCM其 trait 约束要求底层同时支持AES AESCtr AESCBC AESECB AESCCMaes_gcm.rs内部通过GCMState状态机Idle → GenerateHashKey → CtrEncrypt管理 GHASH 密钥生成与 CTR 加密流程aes_gcm.rs。从源码结构看会议中把ghash放在我们已有的digestHIL 之后会很棘手、可能需要大改该 HIL的担忧最终没有走 HIL 包装路线而是采用独立 capsule crate 直接依赖的方式——与会议收敛的避免 trait 包装结论完全一致。5.2 core / extra 的零外部依赖纪律capsules/core/Cargo.toml仅依赖内部kernel与enum_primitivepath 依赖无任何外部依赖——对应政策中core capsules含 virtualizers禁止外部依赖capsules/extra/Cargo.toml仅依赖内部kernel、enum_primitive、tickv与capsules-core同样零外部依赖——对应政策中extra 禁止外部依赖。这正是会议中 Leon 提出的最小结构 core crate 一个大 contrib crate按依赖逐步拆分的最终形态。5.3 工作区成员按域拆分的多 capsule crate根 Cargo.toml 的工作区成员列表印证了按域拆分 capsules 多 crate的落地capsules/aes_gcm, capsules/ecdsa_sw, capsules/core, capsules/extra, capsules/system,其中capsules/ecdsa_swcapsules/ecdsa_sw提供纯软件实现的P-256 签名与验签p256_signer.rs、p256_verifier.rs含基于 p256 的测试 capsules/ecdsa_sw/src/test/p256.rs——这正是会议中讨论的app signing应用签名用例在无硬件加速的板子上用软件密码学验证应用头签名。5.4 板级引入按需引入capsules-aes-gcm的 OpenTitan会议中 Hudson 的担忧是ghash作为 capsules crate 的依赖会让每个板子都拉取并编译它及其传递依赖。政策落地后板子改为按需引入在 boards/opentitan/earlgrey-cw310/Cargo.toml 中capsules-aes-gcm与capsules-core、capsules-extra、capsules-system并列作为显式依赖列出其aes_test.rsboards/opentitan/earlgrey-cw310/src/tests/aes_test.rs对 AES-GCM capsule 进行了板级验证。不引用该 capsule 的板子则完全不会编译ghash及其传递依赖——满足政策板子不使用的依赖不必编译的核心目标。六、结论与启示2022-12-02 的 Tock 核心会议是一个从原则到机制的完整决策样本从Tock 为何拒绝外部依赖审计成本、传递依赖、unsafe 验证困难到否决单一全局 crate tock_extern::命名空间与为依赖做 HIL trait 包装两条备选路线最终收敛为核心内核零依赖 capsules 按域拆分 直接依赖 禁止清单 逐案审批的组合策略。这一策略在仓库中的可验证痕迹包括capsules/aes_gcm对ghash 0.4.4的直接依赖、capsules/core与capsules/extra的零外部依赖纪律、工作区中按域拆分的多 capsule crate、OpenTitan 板的按需引入以及 doc/ExternalDependencies.md 中完整的准则、例外与 PR 模板。对嵌入式内核开发者而言这份政策是如何在追求安全审计性的同时受控地复用 Rust 生态成熟库的一份可借鉴范本用 crate 边界做隔离用禁止清单做底线用逐案审批做弹性。赞分享操作系统嵌入式嵌入式OS【免费下载链接】tockA secure embedded operating system for microcontrollers项目地址https://gitcode.com/gh_mirrors/to/tock点击查看免费下载相关推荐Tock 内核工作组 2025-10-02 会议纪要解读SingleThreadValue 迁移与外部依赖策略落地Tock 内核工作组 2025 10 02 会议纪要解读SingleThreadValue 迁移与外部依赖策略落地 导读 本文基于 Tock 核心工作组Co操作系统嵌入式嵌入式OSTock 外部依赖策略演进从 2023-04-21 核心工作组会议到 AES-GCM 试点落地的源码实录Tock 外部依赖策略演进从 2023 04 21 核心工作组会议到 AES GCM 试点落地的源码实录 2023 年 4 月 21 日的 Tock 核心工作操作系统嵌入式嵌入式OSTock 2022-11-04 核心工作组合议纪要App ID 版本语义、Ethernet 支持与外部依赖/许可头政策Tock 2022 11 04 核心工作组合议纪要App ID 版本语义、Ethernet 支持与外部依赖/许可头政策 Tock 操作系统 README h操作系统嵌入式嵌入式OS上一篇Apache RocketMQ GC优化进阶G1与ZGC性能对比测试下一篇mini-swe-agent 本地环境 LocalEnvironment 实战指南在本机直接执行 Agent 命令的实现、配置与任务提交流程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考