2026/10/15 20:42:44

coreboot 第三方归属声明(attribution)文件生成机制详解:从配置到 CBFS 的完整实战

coreboot 第三方归属声明(attribution)文件生成机制详解:从配置到 CBFS 的完整实战 固件嵌入式操作系统驱动开发【免费下载链接】corebootRead-only mirror of https://review.coreboot.org/coreboot.git. Synced every hour. We dont handle Pull Requests.项目地址https://gitcode.com/gh_mirrors/co/coreboot点击查看免费下载coreboot 镜像中通常包含来自众多第三方项目的代码——编译进镜像的开源组件、借用的源码片段以及 FSP、ME、microcode、payload 等二进制文件。util/attribution是 coreboot 官方提供的构建期工具负责根据本次构建实际启用的配置自动生成一份人类可读的第三方归属/声明notices文件并以名为attribution的 raw 文件存进 CBFS。读完本文你将掌握如何启用该功能、它如何从CONFIG_*选项推导出声明清单、三个分类 section 的语义、attribution.list清单格式与gen_attribution.sh渲染器的实现原理以及如何用cbfstool从最终镜像中取回并核验这份文件。功能定位人类可读的声明文件与 SBOM 互补coreboot 还提供另一项与之独立的软件物料清单功能——SBOMSoftware Bill of Materials见 Documentation/sbom/sbom.md。SBOM 由goswid工具生成输出的是机器可读的 uSWIDuSWID 是 CoSWID 的容器格式CoSWID 以 CBOR 二进制编码见 src/sbom/Kconfig文档适合自动化合规审计、依赖关系分析等场景。而util/attribution生成的是纯文本 notices 文件专门给人阅读。两者相互独立可以只启用其一、同时启用也可以都不启用。attribution文件的内容直接来源于当前构建启用的 Kconfig 配置因此它反映的是这一个镜像里实际包含的东西而不是一个笼统的全项目声明。从源码结构看这正是它最核心的设计声明清单与编译清单同源同门配置变了声明文件也会随之重新生成避免出现列了没编进去或编了没列上的失真。工作原理配置选项 → 清单 → 渲染 → CBFS整个生成链路由三个文件协作完成它们都位于 util/attribution文件职责Makefile.mk依据启用的CONFIG_*选项挑选本次构建涉及的键key决定渲染哪些条目attribution.list数据清单一行一个项目管分隔的元数据名称、许可证、上游 URL、版权行、分类gen_attribution.shPOSIX sh 渲染器把清单中被选中的行渲染成可读文本块Makefile.mk顶部的注释把分工概括得很清楚make 用与门控源码相同的CONFIG_*变量决定哪些项目属于本次构建gen_attribution.sh再从attribution.list渲染被选中键的摘要块。 也就是说绝大多数条目的门控符号就是门控该项目源码编译的那个 Kconfig 符号——一处配置两处生效天然保持同步。构建流程最终被挂在主构建系统中根目录 Makefile.mk 第 149 行通过subdirs-$(CONFIG_INCLUDE_ATTRIBUTION_FILE) util/attribution把该目录纳入构建因此只有启用对应配置时这个子目录才会被解析和构建。启用功能一个 Kconfig 选项在 src/Kconfig 中定义了开关config INCLUDE_ATTRIBUTION_FILE bool Include a third-party attribution/notices file into the ROM image help Generate a human-readable text file crediting the third-party projects whose code is compiled into this coreboot image, and store it in the (CBFS) ROM image as attribution. ... Saying Y here increases the image size by a couple of KB.启用方式在.config/ defconfig 中写入CONFIG_INCLUDE_ATTRIBUTION_FILEy或执行make menuconfig在General setup → Include a third-party attribution/notices file into the ROM image菜单项中勾选。代价是镜像体积增加数 KBKconfig 帮助文本与 README 均为此表述。文件在构建期生成并被加入COREBOOTCBFS 区域。条目的三种分类kind 字段清单中的每条记录都有一个可选的第六列kind决定它渲染在文件哪个 section 下编译进镜像的软件kind为空——从 coreboot 源码树构建出的库/组件例如 coreboot 自身、LZMA、LZ4、zstd、xxHash、vboot、EDK II、openSIL、AGESA 等。加入镜像的独立二进制kind binary——构建过程缝合进镜像、但并不由 coreboot 源码编译的二进制payloadSeaBIOS、GRUB2、depthcharge 等、厂商固件 blobIntel FSP/ME、AMD FSP/PSP、microcode以及单独构建的程序ARM Trusted Firmware、OpenSBI。借用的外部项目代码kind used——coreboot 从一个更大的项目中借用的单个文件而 coreboot 并不整体捆绑该项目Linux 内核、U-Boot、depthcharge、Etherboot、ChromiumOS EC、Sortix UBSan runtime 等。渲染器会为每个被选中条目输出一个摘要块包含项目名、许可证有 SPDX 标识符的用 SPDX id专有二进制 blob 则用自由文本例如Intel FSP EULA (binary)、上游 URL、版权/备注行。完整许可证文本不嵌入文件统一放在源码树的 LICENSES/ 目录下。数据清单 attribution.list字段格式与覆盖范围attribution.list 是唯一需要人工维护项目元数据的地方。每行一个项目格式为key | Project name | license | upstream URL | copyright/notes | kind规则要点文件头注释明确说明key必须与Makefile.mk中使用的键一致#开头行与空行被忽略字段内不得使用|字符license字段开源组件用 SPDX 标识符专有 blob 用自由文本第六列kind可选为空表示编译进镜像binary表示独立二进制used表示借用代码。实际清单覆盖的项目包括节选均为仓库内已确认的行编译进镜像corebootGPL-2.0-only、LZMALGPL-2.1-or-later OR CPL-1.0、LZ4BSD-2-Clause、zstdBSD-3-Clause OR GPL-2.0-only、xxHashBSD-2-Clause、WuffsApache-2.0 OR MIT、x86emu/YABELBSD-3-Clause、Google Sans Flex 字体OFL-1.1、vbootBSD-3-Clause、GNAT Ada runtimeGPL-3.0-or-later WITH GCC-exception-3.1、libhwbase/libgfxinitGPL-2.0-only、EDK IIBSD-2-Clause-Patent、openSILMIT、AGESABSD-3-Clause、MediaTek DRAM 校准、Cavium BDK、TCG Storage/Opal core 等二进制Intel FSP/ME/GBE/ACM、Intel/AMD microcode、AMD FSP/PSP、ARM Trusted Firmware、OpenSBI、VGA option ROM以及 SeaBIOS、GRUB2、depthcharge、edk2含 MrChromebox、Star Labs 分支、U-Boot、LinuxBoot、FILO、iPXE、coreinfo、nvramcui、Memtest86、coreDOOM、tint、CrabEFI、BOOTBOOT、skiboot、leanefi 等 payload借用代码Linux kernelconsole printk/vtxprintf、x86 MTRR、memmove、KASAN、ASPEED 显示驱动等、U-Bootsrc/lib/rtc.c 的 RTC 时间日期辅助、ARM SoC init、depthchargesrc/commonlib/device_tree.c、src/commonlib/list.c、src/lib/fit.c、Etherbootsrc/drivers/net/ne2k.c、ChromiumOS EC、Sortix UBSan runtimeISC。键的挑选逻辑Makefile.mk 的几种典型做法Makefile.mk 中挑选键的方式体现了与实际构建内容对齐的几个层次1. 恒在项。coreboot与xxhash无条件加入。xxHash 之所以总是列出是因为它总是被编译进镜像源码位于 src/commonlib/bsd/xxhash.c构建中为固定成员。2. 压缩解码器扫描源列表而非镜像 Kconfig。LZMA/LZ4/zstd 三个解码器是特例选择它们的 Kconfig 选项不止一个Makefile.mk不去镜像这些选项而是扫描聚合后的各阶段源列表decompressor、bootblock、verstage、romstage、postcar、ramstage、smm、smmstub检测对应源文件是否真的被链接进镜像attribution-decomp-srcs $(foreach c,decompressor bootblock verstage romstage \ postcar ramstage smm smmstub,$($(c)-srcs)) attribution-comp-keys \ $(if $(filter %/lzmadecode.c,$(attribution-decomp-srcs)),lzma) \ $(if $(filter %/lz4_wrapper.c,$(attribution-decomp-srcs)),lz4) \ $(if $(filter %/zstd_decompress.c,$(attribution-decomp-srcs)),zstd)注释解释了为什么必须惰性求值各阶段源列表要等完整解析后才齐全所以这个检测放到 recipe 运行时再展开。zstd 特别以zstd_decompress.c库本体为判定依据而不是恒存在的zstd_wrapper.c桩——后者未被使用时会被--gc-sections丢弃不能作为判据。源码位置对应为 src/lib/lzmadecode.c、src/commonlib/bsd/lz4_wrapper.c、src/commonlib/bsd/zstd/decompress/zstd_decompress.c。3. 直接以门控符号为门控。多数条目形如attribution-keys-$(CONFIG_XXX) key例如CONFIG_UBSAN → ubsan、CONFIG_BOOTSPLASH → wuffs、CONFIG_PCI_OPTION_ROM_RUN_YABEL → x86emu、CONFIG_VBOOT → vboot。4. 多符号 OR 用ifneq块。例如 GNAT runtime 与 libhwbase 只要CONFIG_RAMSTAGE_LIBHWBASE或CONFIG_ROMSTAGE_LIBHWBASE任一启用即列入EDK II 头文件只要 UEFI/UDK binding 系列选项任一启用即列入AGESA 在SOC_AMD_STONEYRIDGE或CPU_AMD_PI_00730F01启用时列入。5. 组合条件防止误报。注释与实现都体现了对实际有没有这个二进制的精细判断AMD microcode 必须CONFIG_USE_AMD_BLOBSy且CONFIG_SOC_AMD_COMMON_BLOCK_UCODEy后者才真正拉入 microcode避免非 AMD 板子误报FSP 必须确实缝合进镜像才声明FSP 2.0 看CONFIG_ADD_FSP_BINARIESFSP 1.1 看CONFIG_HAVE_FSP_BIN再依据CONFIG_SOC_AMD_COMMON区分amd_fsp与intel_fspSeaBIOS 与 GRUB2 以CONFIG_PAYLOAD_BUILD_SEABIOS/CONFIG_PAYLOAD_BUILD_GRUB2为 canonical 门控注释明确说明它们可能是主 payload、次 payload 或 SeaGRUB 的一部分PAYLOAD_BUILD_*只要实际构建就置位而单纯检查PAYLOAD_SEABIOS会漏掉 SeaGRUB 情形。6. 构建期才可知的信息用--extra注入。若CONFIG_EDK2_REPO_CUSTOM启用edk2 payload 来自一个静态清单无法预先命名的自定义仓库Makefile.mk会在构建期取出实际的CONFIG_EDK2_REPOSITORY与CONFIG_EDK2_TAG_OR_REV拼成一行追加到临时 extra 文件printf %s\n |edk2 UEFI payload - custom repository|BSD-2-Clause-Patent|$(attribution-edk2-custom-url)|Built from $(attribution-edk2-custom-rev); based on TianoCore EDK II|binary $.extra渲染器 gen_attribution.sh实现细节gen_attribution.sh 是纯 POSIX sh 脚本调用方式为$ gen_attribution.sh [--extra file] manifest key [key ...]关键行为--extra可选指向一个与清单同格式的文件其中的行无条件输出不按 key 门控用于注入构建期才知道的信息脚本对--extra作为最后一个参数的情形做了防御set -u下避免消费未绑定变量脚本把所有启用的 key 拼成一个 key1 key2 ... 查找集合用 shell case 模式匹配逐行比对解析清单时按|分割六个字段跳过空行与#注释行|| [ -n ${key} ]的处理确保最后一行没有结尾换行符时也不会被read静默丢弃条目按清单中的顺序输出而非按参数顺序保证输出稳定不受 make 对 key 排序的影响三个 section 的标题依次为This coreboot components includes software from the following projects:编译进镜像Code from the following projects has been used in coreboot:借用代码仅当存在此类条目时才输出标题The following payloads and binaries are added to the image, but are not compiled directly against coreboot source:独立二进制同样按需输出标题文件末尾固定输出Full license texts are provided with the coreboot source under LICENSES/.。渲染器对清单中没有对应行的 key静默忽略——这是刻意设计README 与 Makefile 注释均有说明意味着attribution.list与Makefile.mk可以独立更新不必担心临时的不一致导致构建失败。构建与 CBFS 注册Makefile.mk 末段的生成规则值得注意$(attribution-build-dir)/attribution.txt: $(attribution-tool-dir)/attribution.list \ $(attribution-tool-dir)/gen_attribution.sh \ $(DOTCONFIG)规则显式依赖$(DOTCONFIG)注释给出了原因选中的 key 完全来自CONFIG_*选项而不是其它先决条件没有这个依赖重新配置后文件就会过期。recipe 先清空 extra 文件、按需写入自定义 edk2 行再调用渲染器把结果写到临时文件后mv覆盖避免生成中途损坏。CBFS 注册部分cbfs-files-y attribution attribution-file : $(attribution-build-dir)/attribution.txt attribution-type : raw attribution-compression : $(CBFS_COMPRESS_FLAG)注意两点由于该 Makefile 只在CONFIG_INCLUDE_ATTRIBUTION_FILE置位时被解析subdirs-门控所以这里直接-y即可无需再次判断压缩方式复用构建自身的CBFS_COMPRESS_FLAG在根 Makefile.mk 中根据配置取none/LZMA/ZSTD/LZ4而不是强制某种压缩注释说明该文件只通过cbfstool离线读取压缩纯粹是主机侧体积取舍但保持与镜像一致。从镜像中读取与核验构建完成后可用cbfstool把文件提取出来extract是 cbfstool 的标准命令见 util/cbfstool/cbfstool.c 的用法说明$ cbfstool build/coreboot.rom extract -n attribution -f attribution.txt $ cat attribution.txt coreboot third-party attribution / notices This firmware image includes software from the following projects: * coreboot License: GPL-2.0-only Upstream: https://coreboot.org ...也可以在 CBFS 清单中直接看到该条目$ cbfstool build/coreboot.rom print | grep attribution attribution 0x40d80 raw 558 LZMA (1044 decompressed)上面的示例还顺带印证了两个机制类型为raw、压缩为 LZMA与CBFS_COMPRESS_FLAG复用逻辑一致以及压缩解码器检测——镜像中attribution采用 LZMA 压缩恰恰意味着 LZMA 解码器确实被链接了因而lzma条目会出现在文件里。添加一个新项目两步操作README 给出了明确的扩展步骤结合实现可以归纳为在 attribution.list 新增一行使用新的key并按实际情况设置第六列kind缝合进镜像的 payload/blob 用binary借用的单个文件用used编译进 coreboot 的源码留空。在 Makefile.mk 增加门控行attribution-keys-$(CONFIG_symbol) key若由多个符号的 OR 决定则改用ifneq (...)块。门控符号应尽量与门控该项目源码编译的符号一致。两个文件允许不同步——渲染器会静默忽略没有清单行的 key也自然跳过未被选中的行因此可以分别合入、独立演进。小结与使用建议util/attribution用一套轻量而精确的机制解决了固件合规声明中的一个实际问题声明必须与构建内容一一对应。它的经验值得借鉴——用门控源码的同一个符号来门控声明、用扫描实际链接的源文件来处理难以镜像的间接选择、用惰性求值 构建期注入来覆盖运行时才可知的信息。对使用 coreboot 的开发者而言合规审计时启用CONFIG_INCLUDE_ATTRIBUTION_FILE并提取attribution文件即可得到与镜像完全对应的人类可读声明需要机器可读的物料清单时可另行启用 SBOMCONFIG_SBOM与之互补。赞分享固件嵌入式操作系统驱动开发【免费下载链接】corebootRead-only mirror of https://review.coreboot.org/coreboot.git. Synced every hour. We dont handle Pull Requests.项目地址https://gitcode.com/gh_mirrors/co/coreboot点击查看免费下载相关推荐GitLens第三方声明文件详解ThirdPartyNotices.txt完整指南GitLens第三方声明文件详解ThirdPartyNotices.txt完整指南 GitLens作为Visual Studio Code中最强大的Git增强开发工具版本控制coreboot 构建系统详解从 Makefile.mk 的 class 机制到 CBFS/FMAP 镜像组装coreboot 构建系统详解从 Makefile.mk 的 class 机制到 CBFS/FMAP 镜像组装 coreboot 的构建系统以 GNU mak固件嵌入式操作系统驱动开发.NET Runtime 安装包第三方声明THIRD-PARTY-NOTICES的生成与分发机制详解.NET Runtime 安装包第三方声明THIRD PARTY NOTICES的生成与分发机制详解 本文围绕 dotnet/runtime 仓库中 src语言运行时标准库JIT编译编译器上一篇LeetCode 0190 颠倒二进制位从逐位提取到位运算分块对调的完整解法下一篇深度解析windows-defender-removerWindows安全组件的底层根除技术架构创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考