二进制 blob
在支持多种架构和众多不同 IC 系列的操作系统语境中,如果没有以二进制形式分发的可执行代码,某些功能可能无法使用。二进制 blob(简称 blob)是包含专有机器码或二进制格式数据的文件,例如没有以 OSI 批准许可证发布的相应源代码。
Zephyr 通过其内置机制支持下载和使用第三方二进制 blob,但存在一些重要的注意事项,将在以下各节中说明。需要注意的是,本节中的所有信息仅适用于 上游(原版)Zephyr。
在 Zephyr 的分支或第三方发行版中,对二进制 blob 的支持没有任何限制(或许许可证兼容性除外)。事实上,Zephyr 的构建系统支持与 blob 相关的任意用例,包括链接库、向目标烧录镜像等。因此,如果用户无法满足本页所述的要求,他们可以自由创建使用二进制 blob 的基于 Zephyr 的下游软件。
软件许可证
大多数二进制 blob 以专有许可证分发,其性质和条件差异很大。供应商需在 blob 提交流程中指定许可证。当用户获取并安装 blob 时,blob 供应商可能会要求点击确认或其他类似 EULA 的流程。
托管
blob 必须托管在互联网上并由第三方基础设施管理。两个可能的例子是个别硬件供应商管理的 Git 仓库和 Web 服务器。
Zephyr 项目不在其 Git 仓库或任何其他地方托管二进制 blob。
获取 blob
blob 由 west blobs 命令从官方第三方来源获取。
blob 本身必须在 module.yml 文件中指定,这些文件包含在由各自供应商维护的独立 Zephyr 模块仓库 中。这意味着,要将二进制 blob 的引用纳入上游 Zephyr 发行版,必须先存在一个模块仓库,或作为提交流程的一部分创建它。
每个可能被获取的 blob 都必须在相应的 module.yml 文件中单独标识。blob 的规格说明必须包含:
blob 本身的抽象描述
版本信息
对供应商提供文档的引用
blob 的 类型,必须是允许的类型之一
blob 的校验和,
west blobs在下载后会对其进行校验。这是保证可复现性所必需的,也使得在使用 Git 和 west 时能够对随 blob 变化而出现的问题进行二分定位适用于该 blob 的许可证文本或对此类文本的引用,采用 SPDX 格式
请参阅 相应章节 以获取字段的更正式定义。
可以使用 west blobs 命令列出可用 blob 的元数据,并从用户选择的模块中获取 blob。
west blobs 命令只获取并存储二进制 blob 本身。任何随附的代码,包括 blob 的接口头文件,都必须存在于相应的模块仓库中。
污染(taint)
引入二进制 blob 会使 Zephyr 构建被污染。污染这一概念源自 Linux kernel;在 Zephyr 的语境中,被污染的镜像即包含二进制 blob 的镜像。
将以以下方式向用户告知污染状态:
一个或多个 Kconfig 选项
TAINT_BLOBS_*将被设置为yZephyr 构建系统会在配置阶段发出警告。可以使用 Kconfig 禁用该警告
west spdx命令会在其输出中包含污染状态内核的默认致命错误处理程序还会显式打印内核的污染状态
启动横幅会打印内核的污染状态
允许的类型
以下二进制 blob 类型在 Zephyr 中是可接受的:
预编译库:以预编译二进制形式分发的硬件使能库,通常用于 SoC 外设。例如,无线外设的使能库
固件镜像:包含辅助处理器或 CPU 可执行代码的镜像。它可以是完整的或部分的(通常是增量或补丁数据),一般由主 CPU 复制到 RAM 或闪存中。例如,运行 Bluetooth LE Controller 的内核固件
其他二进制数据文件。例如,预训练的神经网络模型数据
通过专有库提供的与硬件无关的功能是不被接受的。例如,以静态归档形式分发的专有且与硬件无关的 TCP/IP 协议栈会被拒绝。
请注意,某个 blob 具有可接受的类型并不意味着它会被项目无条件接受;任何 blob 都可能因其他原因被逐案拒绝(参见下文针对库的具体要求)。如有分歧,由 TSC 裁决某个 blob 是否属于上述类型之一。
预编译库的具体要求
本节包含针对预编译库 blob 的附加要求。
任何希望提交预编译库的人都必须声明其满足这些要求。如果日后发现某个 blob 不满足这些要求,项目可能会将其从上游发行版中移除。
接口头文件
预编译库必须附带一个或多个以非 copyleft 的 OSI 批准许可证分发的头文件,用于定义该库的接口。
允许的依赖
本节定义与库 blob 要求构建系统提供的外部符号相关的要求。
blob 不得直接依赖 Zephyr API。换言之,必须能够在完全不存在任何 Zephyr 源代码的情况下构建该二进制文件。这是松散耦合和可维护性的要求,因为 Zephyr API 可能会变化,而这类 blob 无法由所有项目维护者修改
相反,如果预编译库中的代码需要 Zephyr(或一般意义上的 RTOS)提供的功能,则可以在该库旁提供操作系统抽象层(又称移植层)的实现。该操作系统抽象层的实现必须为源代码形式,以 OSI 批准的许可证发布,并使用 Doxygen 编写文档。
工具链要求
预编译库 blob 必须采用与 Zephyr 项目支持的工具链兼容且可被其链接的数据格式。这是可维护性和可用性的要求。不过,使用此类库可能需要特殊的编译器和/或链接器标志。例如,移植层可能需要特殊标志,或者静态归档可能需要使用特定的链接器标志。
受限范围
允许任意库 blob 会带来降低上游 Zephyr 软件发行版开源程度的风险。举一个极端的例子,若某个目标的 zephyr 内核时钟驱动仅仅是围绕一个库 blob 的移植层,那么该目标将无法仅凭开源软件启动。
为降低这一风险,上游库 blob 的范围受到限制。项目维护者定义了一套开源测试套件,上游目标必须能够仅使用主线发行版及其模块中包含的开源软件通过该测试套件。该开源测试套件目前包括:
samples/philosopherstests/kernel
该测试套件的范围可能会随时间扩大。目标是为任何获得上游 Zephyr 支持的硬件目标规定一组最小功能集的测试,这些功能必须能够通过开源软件支持。
发布团队可自行决定,如果某个硬件目标无法通过该测试套件,项目可能会移除对该目标的支持。
支持与维护
Zephyr 项目不应负责所贡献二进制 blob 的维护和支持。因此,Zephyr 项目发布团队可逐案自行决定:
在 zephyr 仓库跟踪器上报告的、需要借助 blob 才能复现的 GitHub issue,可能不会被视为缺陷
此类 issue 可能会以超出 Zephyr 项目范围为理由被关闭
这并不意味着需要 blob 才能复现的 issue 会被不加调查地关闭。例如,该 issue 可能暴露了 Zephyr 代码路径中的一个缺陷,而该缺陷在没有 blob 的情况下很难或无法触发。项目维护者可能会接受并尝试解决此类 issue。
然而,也需要一定的灵活性,因为项目维护者可能无法确定某个 issue 是由 Zephyr 还是 blob 本身的缺陷导致的,也可能因缺少硬件等原因无法复现该缺陷。
blob 必须有指定的维护者,负责及时回应用户的问题报告并更新 blob 以解决问题。Zephyr 项目发布团队可自行决定,由于维护者缺乏响应或支持,引用 blob 的模块版本随时可能从 zephyr/west.yml 中移除。这是维持项目对代码腐化、安全问题等的控制所必需的。
集成二进制 blob 的提案提交者必须承诺在可预见的未来维护此类 blob 的集成。
关于持续集成,在项目用于构建并可选地执行测试和示例以防止回归和问题进入代码库的 CI 基础设施中,二进制 blob 不会 被获取。这既包括打开新的 GitHub 拉取请求时运行的 CI,也包括 CI 基础设施的任何其他定期执行。
提交与审查流程
要将二进制 blob 的引用纳入项目,应通过标准的拉取请求(PR)流程提交,无需技术指导委员会(TSC)批准。维护者和审查者负责确保所有与 blob 相关的提交符合 二进制 blob 中记录的既定标准。
首次集成二进制 blob 的 PR 应包含有关这些 blob 及其所提供功能的详细信息。该 PR 应包含以下信息以支持审查:
二进制 blob 的来源。
blob 类型(预编译库、固件镜像)。
引用该 blob 的 Zephyr 模块。
简要说明 blob 的作用。
blob 依赖哪些其他组件(如有)?
blob 分发的许可证。
如果初始集成 PR 获得相应批准,则可以集成二进制 blob。对于任何技术分歧,应适用标准的 PR 升级流程。
二进制 blob 的后续更新遵循 模块更新流程。