- 引言 — "ASIL D 认证 Rust 编译器"这句话里的陷阱
- 工具资格认定和软件认证是两码事
- 从 2025 年 12 月到 2026 年 5 月 —— 实际发生了什么
- 为什么只认证子集,而不是整个 core
- 如何强制执行子集 —— 从 cfg hack 到调用图 lint
- ASIL B 天花板的真相 —— 厂商自己写下来的东西
- 你的芯片大概率不在名单上
- 那么,依然留给你的是什么
- 什么时候不该用它
- 结语
- 参考资料
引言 — "ASIL D 认证 Rust 编译器"这句话里的陷阱
只要聊到嵌入式 Rust,就总会反复出现这样一句话:"Ferrocene 已经通过了 ISO 26262 ASIL D 认证。"这句话本身没有错 —— Ferrous Systems 的公开文档就是这么写的。
问题出在人们从这句话里得出的结论上。"那我现在就可以用 Rust 写 ASIL D 软件了吧。"不对。这里其实揉进了两个本应分开的主张,而 2026 年上半年真正发生变化的,不是被揉在一起的那一半,而是它底下的那部分 —— core 库。
本文讲的就是这件事。Ferrocene 从 2025 年 12 月到 2026 年 5 月究竟认证了什么,为什么编译器是 ASIL D 而库却止步于 ASIL B,这道天花板从何而来,以及依然留给你的是什么。先说结论:这个故事里最有价值的部分,不是厂商藏起来的东西,而是厂商自己写下来的东西。
工具资格认定和软件认证是两码事
先理清术语。这是整篇文章的骨架。
Ferrocene 编译器(rustc) 是作为一款 工具 通过资格认定(qualification)的。Ferrocene 资格认定报告(Qualification Report)的第一句话就是这么写的 —— 本文档是为了针对汽车 ISO 26262:2018(ASIL D / TCL 3)、工业 IEC 61508:2010(class T3)、医疗 IEC 62304:2006 + AMD 1:2015 标准的认证而开发的资格认定材料报告。
这里的关键缩写是 TCL,即 Tool Confidence Level(工具置信水平)。ISO 26262 part 8 第 11 条处理的是"对软件工具使用的信心",而不是工具吐出来的代码的完整性水平。以 TCL 3 通过 ASIL D 资格认定,意思是"可以在 ASIL D 开发中使用这个编译器",而不是"编译出来的产物就是 ASIL D"。
core 库子集 完全是另一回事。它不是工具,而是一个 软件组件,并且是作为软件通过了 认证(certification)。同一份资格认定报告接着写道 —— 本文档的部分内容可能被 Core Library Certification 引用,而后者是为了针对汽车 ISO 26262:2018(ASIL B)和工业 IEC 61508:2010(SIL 2)软件标准的认证而开发的。
这两个数字不是营销话术,而是以机器可读的形式写进了文档构建系统的配置文件里。打开 Ferrocene 仓库里的 ferrocene/doc/sphinx-substitutions.toml,看到的是这样:
iso_26262_ferrocene_asil = "ASIL D"
iso_26262_core_asil = "ASIL B"
iso_26262_ferrocene_tcl = "TCL 3"
iso_26262_ferrocene_tql = "class T3"
iec_61508_core_sil = "SIL 2"
编译器是 ASIL D / TCL 3,core 是 ASIL B。26.02.0 分支和 26.05.0 分支里这份文件一字不差 —— 也就是说,ASIL B 这道天花板在最新版本里依然原封不动。
而安全手册(Safety Manual)的"Qualification scope"一章,把用户的责任钉得很死 —— 依据 ISO 26262:2018 part 8 clause 11.4.2,用户在把这款软件工具用于安全相关开发之前,必须验证预先确定的 TCL 是否有效。依据 clause 11.4.3,用户必须确保这款工具的使用方式、环境、功能约束符合其评估标准或资格认定。
细读就会发现,这句话不是"我们都替你做好了,拿去用吧",而是"我们资格认定的有效范围,由你来验证"。
从 2025 年 12 月到 2026 年 5 月 —— 实际发生了什么
按时间顺序整理如下。
2025 年 12 月 3 日 —— 第一个 core 子集,IEC 61508 SIL 2。 Ferrous Systems 通过一份新闻稿宣布了这件事。TÜV SÜD 把 Rust core 库的第一个子集认证为 IEC 61508(SIL 2),这个子集随 Ferrocene 25.11.0 一起发布。认证适用于在 Ferrocene 工具链和已获资格认定的目标(包括 Armv7E-M、Armv8-A)上的使用。这项工作始于 2023 年,Cryspen 和 Thoughtworks 提供了工具和时间上的支持。用 Ferrous 董事总经理 Florian Gilcher 的原话说 —— "离开 core,Rust 在嵌入式或安全攸关环境里运行是不现实的,而 core 如果不经过像 Ferrocene 这样的工具链严格验证,就不可能通过认证。"
同一份资料还举了两个真实落地的例子。Sonair 把它用在了自主机器人的 3D 超声波传感器 ADAR 上(运行在四核 Armv8-A 之上,同时带一个 Armv7E-M 子系统),Kiteshield 把它用在了地下矿山有人/自主设备的防碰撞系统上,其中一些组件最终要求达到 IEC 61508 SIL 3。
2026 年 2 月 15 日 —— 加入 ASIL B,子集扩大。 这是 26.02.0 版本。已认证的 core 子集加入了 ISO 26262(ASIL B),SIL 2 子集本身也大幅扩展。按厂商公布的数字,已认证函数的数量从 2,903 个增加到 5,169 个,core::slice、core::iter、core::ffi、core::result 等模块得到扩展,还加入了一个最小化的已认证 panic 钩子。仓库里的 ferrocene/version 文件确认这个版本的 rustc 是 1.92。eeNews Europe 也独立做了报道 —— 在 embedded world 2026 上公布,要点是认证已经越过编译器工具链,下沉到了库这一层。
2026 年 5 月 —— core::fmt 通过认证,强制方式也随之更换。 从这里开始变得有意思了。26.05.0 没有配发布公告博客。ferrous-systems.com/blog/ferrocene-26-05-0/ 是 404,博客索引里最新的 Ferrocene 版本公告依然停留在 26.02.0。但这个版本确实发布了 —— 仓库的 release/1.95 分支里,ferrocene/version 记录的是 26.05.0,发布说明里的 :upcoming-release: 标记已被移除(相比之下,release/1.97 上的 26.08 仍然带着这个标记)。内容如下。
core::fmt模块通过了 ISO 26262(ASIL B)和 IEC 61508(SIL 2)认证 —— 这是把 Rust 数据结构格式化为人类可读输出的代码。- 由此,"已认证 panic 运行时"这些目标(
aarch64-ferrocene-none、thumbv7em-ferrocene-none-eabi等)被淘汰了。它们本是为了在不认证格式化代码的前提下单独认证 panic 而存在的,现在已经没有必要了。 - 引入了
ferrocene::unvalidatedlint,"子集目标"随之被淘汰。后面会详细说明。 - 新增了一个已获资格认定的目标
aarch64-rhivos2-linux-gnu(仅在aarch64-unknown-linux-gnu主机上编译时适用),并且允许了proc_macrocrate 类型。 thumbv7em-m4-none-eabihf和aarch64-a53-none被移除。这两个目标是 26.02.0 里新加的,现在在基础目标上使用-C target-cpu=cortex-m4/-C target-cpu=cortex-a53就能达到同样的效果。
26.05.0 的 core::fmt 认证在用户手册里也留下了痕迹。26.02.0 版的 core/using.rst 里有这样一条警告 —— 在使用已认证目标时,core 库的行为会有所不同,尤其是 panic! 宏只支持静态字符串,而不支持任意的 format_args!,因此 panic 信息可能不够有用。到了 26.05.0 的同一份文件里,这整段话彻底消失了。
独立验证。 仓库里以 CSV 形式提供了一份权威的已认证符号清单(ferrocene/doc/symbol-report.csv,core-certification 文档的 Safety Report 一章直接内嵌了这份文件)。从两个发布分支拉取并统计,结果如下。
release/1.92 (26.02.0): 5,235 unique symbols core::fmt 符号: 0
release/1.95 (26.05.0): 8,790 unique symbols core::fmt 符号: 535
(新增 3,597 / 移除 42)
这个数字独立于发布说明,证实了 core::fmt 认证确实落地了。不过老实说,26.02.0 CSV 里的 5,235 这个数字,和厂商公布的"5,169 个已认证函数"并不精确吻合。正如文件名所示,这是一份 符号(symbol) 报告,而公告数的是 函数(function),统计口径很可能不同。所以 5,169 这个数字,不妨当作厂商自己的统计来读;可以确定的是数量级和方向 —— 一个版本里子集大约变成了原来的 1.7 倍。
被移除的那 42 个也很有意思。大部分是像 core::panicking::PanicArguments::as_str 这样的旧版已认证 panic 运行时部件,以及 derive 内部的标记(assert_receiver_is_total_eq)。子集不只是在增长,也会收缩。
2026 年 8 月(预定)。 release/1.97 上的 26.08 仍然带着 upcoming 标记,预告了三个新的资格认定目标 —— aarch64-unknown-qnx、armv7r-none-eabihf、x86_64-pc-qnx。flip-link 将升级为 quality managed。
为什么只认证子集,而不是整个 core
Ferrous 编译器工程师 Jynn 撰写的《Callgraph analysis》(2026 年 4 月 1 日)把原因说得很直白。认证目标是 IEC 61508(SIL 2),而这套标准里有一项要求会随代码库规模成比例增长,那就是 Annex A.9"Software verification"。Ferrous 采用的是方法 3 和方法 4(静态分析、动态分析)。文档记录的做法是,在每一个存在已认证 core 的目标平台上运行测试,并收集代码覆盖率来验证每个函数都被测试过。
也就是说,代码越多,需要的测试就越多。原文的说法照搬过来是 —— 为了避免在产品发布之前花上好几年的工夫,他们决定只验证 core 的一个子集。把函数标记为 validated,针对每一个都跑测试来收集覆盖率,然后告诉客户只使用那些已验证的函数。
认证的正式路径也写在文档里。根据 core-certification 文档的 Certification scope 一章,IEC 61508 一侧走的是 section 7.4.2.12 的 Route 3S —— "对不合规开发的评估(Assessment of non-compliant development)" —— 而 ISO 26262 一侧则是把 part 2/6/8 裁剪之后的 SEooC(Safety Element out of Context)软件开发路径。
如果 Route 3S 这个词本身不太好理解,可以这样想:Rust 的 core 从一开始就不是按照 IEC 61508 开发的。Route 3S 就是这样一条路径 —— 把一个原本没有按标准开发出来的东西,事后拿去评估它是否可用。而在 ISO 26262 的适用条款清单里,有一项很有意思 —— "8-12 软件组件的资格认定"被标记为 不适用,理由是"不采用资格认定,而是按新开发处理"。也就是说,他们没有走既有的软件资格认定路径,而是像对待全新开发一样一点点积累证据。
如何强制执行子集 —— 从 cfg hack 到调用图 lint
这是整个故事里工程味最浓的部分。
问题是这样的:说"只用已认证的函数"很容易,但用户根本没有办法知道自己实际在用 core 的哪一部分。《Callgraph》那篇文章精准地指出了这一点 —— core 不是一个普通的库,它和编译器、语言本身有着广泛的深度集成。像 do_io()? 这种看起来人畜无害的写法,实际上会发出对 core::ops::try_trait::Try::branch 的调用。要知道哪个函数调用了哪个函数,需要真正的编译器集成。
第一次尝试(25.11、26.02):cfg fork + 假的子集目标。 做法是 fork 标准库,给整个 panic 机制贴满 cfg。但这样一来,所有用户都会受到影响,不只是关心认证的那部分人,于是为了避免破坏性变更,他们干脆整套新建了 aarch64-unknown-ferrocene.subset 这样的目标。Ferrous 自己给出的评价很冷静 —— 构建脚本解析不了目标名称,libtest 用到了被 cfg 掉的那部分 core,导致在这个目标上根本编译不了,实际操作中不得不告诉大家"可以跑 cargo check --target aarch64-unknown-none.subset,但不要用它来做完整构建" —— 这是一次非常糟糕的用户体验。
安全手册也在一个警告框里写了同样的话 —— 子集目标 只能 用于验证子集合规性,不能 在运行时当作已认证目标使用。
第二次尝试(26.05):基于定制 rustc driver 的 lint。 也就是 26.05.0 引入的 ferrocene::unvalidated lint。按照安全手册的说法,现在证明合规性的流程已经短到这个地步。
// 1. 在每个 crate 根启用该 lint
#![warn(ferrocene::unvalidated)]
// 2. 用 -D warnings 编译。如果成功,说明子集守住了。
//
// 如果失败,从以下四种方式中选一种:
// a) 如果该函数属于自己的 crate,加上 #[ferrocene::prevalidated]
// b) 如果是 core 的函数,联系 Ferrous 讨论把它加入子集
// c) 删掉这次调用,改写成语义相同的写法
// d) 继续使用,但自己证明其安全性,并加上 #[allow(ferrocene::unvalidated)]
这个 lint 维护的不变式可以归结为一句话 —— core 中 validated 函数的集合,对函数调用这个运算必须是封闭的。也就是说,如果在一个 validated 函数内部出现了调用,被调用的一方也必须是 validated。反过来则无所谓 —— 一个未认证的 core::async_iter::from_iter 去调用已认证的 usize::checked_add,完全没有问题。
实现分成两个 pass。
- pre-mono pass(基于 THIR)。 它在
cargo check里给出快速反馈,运行得足够晚,能够把?这类内置语法脱糖(desugar)。它能捕捉到从函数类型到函数指针的 unsizing 转换,从而挡住"把未认证的函数指针传给已认证函数"这种绕过方式,也能捕捉到向dyn Trait对象的转换(连 supertrait 和 dyn-to-dyn 强制转换都考虑在内)。 - post-mono pass(基于 MIR)。 认证真正依赖的其实是这一个 pass。在泛型被实例化之前,根本无法知道
x.clone()具体调用的是哪个clone,所以这个 pass 从单态化(monomorphized)之后的根节点出发,一边代入类型一边沿着调用图往下走。相应地,它不在cargo check里运行,只在cargo build里运行(对于带公开泛型函数的库,它甚至可能出现得更晚)。
设计原则也写得很明确 —— 宁可假阳性,也不要假阴性。误拒有效代码,好过让无效代码通过认证。作为一款安全工具,这个方向是对的;而在实际使用中,这也意味着"明明没问题的代码被 lint 拦住,最后不得不写一份安全论证再加上 #[allow]"。
这次转变本身就是一个信号。认证的强制机制从"fork 标准库 + 一个名字古怪的假目标",升级成了"一个编译器 pass"。前者是 hack,后者是工程。
ASIL B 天花板的真相 —— 厂商自己写下来的东西
现在到了本文的核心问题。编译器已经作为 ASIL D 工具通过了资格认定,那库为什么止步于 ASIL B?
答案不需要靠猜。Ferrous 把一份名为 ISO 26262 6-Method Tables 的文档,原封不动地放进了它那个 MIT/Apache-2.0 许可的公开仓库里。针对 ISO 26262 part 6 里的每一张方法表,它都逐行记录了"在 ASIL B 下推荐到什么程度 / 在 ASIL D 下推荐到什么程度 / 我们是否应用了"。
Table 9,软件单元层面的结构覆盖率指标,是这样的。
No. Method ASIL B ASIL D Justification
1a Statement coverage ++ + Applied, 100% line coverage with
explanations for any coverage gaps
1b Branch coverage ++ ++ Not applied, 1a applied instead
1c MC/DC + ++ Not applied, 1a applied instead
答案全在这里了。真正应用的只有语句覆盖率(statement coverage)一项,分支覆盖率和 MC/DC 都是"未应用,改用 1a 代替"。但表格也显示,分支覆盖率在 ASIL B 和 ASIL D 下都是强烈推荐(++),MC/DC 在 ASIL D 下也是强烈推荐。反倒是语句覆盖率,在 ASIL D 下只降级成了一般推荐(+)。
换句话说,ASIL B 并不是一道硬性上限,而是 目前积累的证据只能支撑到 ASIL B。要主张 ASIL D,就得把 Table 9 里的 1b、1c 补上,也就是说要为整个 core 子集重新建立分支覆盖率和 MC/DC。公开文档里没有任何地方给出这样的计划。
同一份文档里还有几处格子,是嵌入式工程师尤其应该留意的。
- Table 7,1m 资源使用评估(Resource usage evaluation)。 ASIL D 强烈推荐。判定是"未应用 —— 这只是一个库,属于集成方的责任"。翻译成嵌入式语境,就是栈深度分析和 WCET。用了已认证的 core,并不会附带告诉你它会吃掉多少栈空间、最坏情况下的执行时间是多少。这是你自己的活。
- Table 6,1j 禁止递归。 ASIL D 强烈推荐。判定是"未应用"。原话是 —— 无条件递归被禁止(编译器会替换函数体的
#[lang_item]除外),但允许条件递归。在栈预算紧张的 MCU 上,这句话不是能随手带过的。 - Table 7,1g 数据流分析。 ASIL D 强烈推荐。"未应用 —— 没有需要分析的内部数据流,没有全局状态,一切都只通过明确定义的接口。"
- Table 1,建模与编码指南。 这里的判定索性写成 —— 已认证的 core 库没有编码标准。理由是,直接沿用上游 Rust 自己的 lint 和测试,能减少和上游的偏离,而偏离越大,维护负担和 bug 来源就越多。对习惯了 MISRA 的人来说,这是个陌生的答案,但这套逻辑本身是站得住脚的。
- Table 2/3/4,软件架构设计。 全部标记为"不适用,因为不存在架构"。core-certification 的需求文档也说了同样的话 —— core 库规模太小,不需要软件架构。
- Table 8,1b/1c 等价类生成/分析与边界值分析。 ASIL B、D 都强烈推荐。判定是"部分应用"。原文相当坦诚 —— coretests 的测试用例做得非常用心,但 Ferrous Systems 并没有对边界值和极端值是否始终被测试到做过全面审查。紧随其后的论据是,达到 100% 的行覆盖率就能保证每一条代码路径都被执行过,不存在因为缺少针对某个输入的测试而遗留下来的未测试代码。
而需求管理方式本身也颇具争议。core-certification 的 Requirements Management 一章开篇就是 —— 需求是以 doc-comment 的形式实现的。 一个函数的 doc-comment 就是这个函数的需求,一个模块的 doc-comment 就是模块设计,需求标识符是"Ferrocene 版本 + 函数的模块路径"。至于需求如何追溯到测试 —— 由于一个函数的需求就是那个函数上方的 doc-comment,所以需求是通过函数来追溯的;认证依赖代码覆盖率来保证每个函数都被充分测试;因此,只要每个函数都被测试覆盖,每一条需求也就都被覆盖了;所以不需要手动把测试追溯到需求上。
这套论证是否站得住脚,由你自己判断。但它为什么是个聪明的选择,倒是很清楚 —— 相比之下,Rust core 的 doc-comment 写得异常好,还被强制当作 doctest 执行,因此很难和代码脱节。与其凭空发明一套原本不存在的需求规范,不如把这些已经存在、已经被验证的文档直接升格为需求,后者显然更划算。
有一点值得强调。 上面这些"未应用"的格子,并不是我挖出来的厂商的软肋。它们是 Ferrous 自己动手写下来、放进开源仓库里的。安全攸关工具厂商的 norm mapping 通常都藏在 NDA 后面,想看评估报告往往得先签合同。这些表格只需要 git clone 一次就能读到,这件事本身,或许就是这个项目里最好的部分。而且这些表格没有把天花板藏起来,它们 在解释 天花板。想知道 ASIL B 从何而来,看 Table 9 就够了。
你的芯片大概率不在名单上
在讨论认证之前,有一件事得先确认:你的目标平台到底在不在名单上。
26.05.0 安全手册的资格认定范围,被限定在以下这些组合里。
Host Target Certified Uncertified Qualified
aarch64-unknown-linux-gnu aarch64-rhivos2-linux-gnu core alloc
x86_64-unknown-linux-gnu aarch64-unknown-none core alloc
x86_64-unknown-linux-gnu aarch64-unknown-nto-qnx710 core alloc, std, test proc_macro
x86_64-unknown-linux-gnu thumbv7em-none-eabi core alloc
x86_64-unknown-linux-gnu thumbv7em-none-eabihf core alloc
x86_64-unknown-linux-gnu x86_64-unknown-linux-gnu core alloc, std, test proc_macro
x86_64-unknown-linux-gnu x86_64-pc-nto-qnx710 core alloc, std, test proc_macro
从这张表里应该读出这些信息。
唯一通过认证的库只有 core。 alloc、std、test 全部未经认证。用文档自己的话说 —— 所提供的未认证库,仅出于编译器使用的目的,在 Ferrocene 的资格认定范围内被评估和测试过;终端用户代码使用这些库,目前不在 Ferrocene 资格认定的范围之内;如果使用,认证责任由终端用户承担。如果你的设计需要堆分配,那从 alloc 开始就是你自己的作业了。
MCU 一侧已获资格认定的目标只有两个,就是 thumbv7em 那一对。 也就是 Cortex-M4/M7。那么缺了什么呢?Ferrocene 的目标支持等级文档里,列在 Supported(支持)等级下的有 —— riscv64gc-unknown-linux-gnu、thumbv6m-none-eabi(Cortex-M0/M0+)、thumbv8m.base-none-eabi、thumbv8m.main-none-eabi、thumbv8m.main-none-eabihf(Cortex-M23/M33)、armv7r-none-eabihf、armv8r-none-eabihf、wasm32-unknown-unknown、x86_64-pc-windows-msvc(主机),以及其他。26.05.0 又往这份清单里加上了 s390x 和 powerpc64le。
也就是说,如今新款安全 MCU 里有一半在用的 Cortex-M33,以及 RISC-V,都不在资格认定名单上。26.08 计划把 armv7r-none-eabihf 提升为已认证,方向是对的,但就今天而言,"Rust 通过了认证"并不等于"我的芯片上能用经认证的 Rust"。
Supported 和 Qualified 的区别,文档也用表格整理了出来。Qualified 每次合并前都会跑完整测试套件,追踪并提供已知问题,还有两年的支持窗口和 LTS。Supported 的测试是"尽力而为",已知问题"仅作记录",支持补丁"仅限致命问题"。文档写道,如果提出要求,可以把一个目标升级为已认证或 quality managed —— 这其实就是在说,这是一场合同层面的对话。Ferrous 把自己的开发模式称为"contract-driven",并且明说了可以花钱让公司把注意力集中在对你最重要的功能上。
主机只有一个,就是 x86-64 Linux。 macOS(aarch64-apple-darwin)是 quality managed,Windows(x86_64-pc-windows-msvc)是 supported —— 两者都不是已认证。生成认证目标构建产物的机器,必须是 x86-64 Linux。只有 RHIVOS 那一行是例外,用的是 aarch64-unknown-linux-gnu 主机。
那么,依然留给你的是什么
安全手册的约束(Constraints)清单里,每一项都带着一个标识符。只挑出和 core 相关的:
CORE_CSTR_0020_PANIC_ABORT—— 用户必须始终给 rustc 传入-C panic=abort。CORE_CSTR_0030_SUBSET_ONLY_STABLE—— 已认证子集里的实验性函数不能使用。nightly 特性更是完全排除在外。CORE_CSTR_0060_VERIFY_MACROS—— 用户必须验证所有由宏生成的代码是否正确。对于大量依赖宏的 Rust 代码库来说,这不是一句轻松的话。CORE_CSTR_0060_VERIFY_ARCH—— 架构相关代码必须在应用上下文中被推理和测试。原文说得很直白 —— 我们只保证编译器正确地吐出了你要求的指令,不保证这些指令在上下文里是有意义的。适用范围是整个core::arch模块以及core::hint::spin_loop。CORE_CSTR_0070_VERIFY_FLOATS—— 浮点代码依赖于外部条件,比如用的是哪种 FPU、哪些运算是用硬件实现的。用户必须在自己的应用和硬件上下文中彻底测试浮点计算,不能仅凭编译器和库的资格认定作为唯一的正确性论据。CORE_CSTR_0040_MATCHING_VERSION—— 必须验证 core 和 rustc 的版本是否一致。
在此之上,还要加上 rustc 一侧安全手册的"Handling Unsafety"一章。使用 unsafe 时的最低义务是这样的 —— 尽可能把不安全性的使用局部化,绝不能越过模块边界;该模块必须只做一件事;在不安全代码及其调用方两侧都使用断言、前置条件、后置条件和不变式;两侧都要写上与安全相关的注释。验证时的最低义务更重 —— 至少两名资深工程师做代码评审,或者引入第三方评审;必须评审含有不安全代码的 整个模块;必须对不安全代码及其调用方执行单元测试和集成测试。还要制定缓解策略。
运营层面也有义务。已知问题(Known Problems)数据库只有持有有效订阅的客户才能访问(problems.ferrocene.dev 位于登录墙之后)。安全手册对此毫不含糊 —— 察觉到新发现的问题,并按照新 DB 条目中描述的流程去处理,是客户自己的责任,可以通过订阅通知或者定期监控来完成。买了一款已认证的编译器并不是终点,你还得在组织内部建立一套监控该编译器缺陷公告的流程。
最后是环境。Degraded Environment 一章把 RUST_TARGET_PATH 和 RUSTC_BOOTSTRAP 列为潜在的错误来源,并写明用户必须确认这些变量没有被设置。RUSTC_BOOTSTRAP 是在稳定版编译器上强行打开 nightly 特性的后门,这一点并不意外。
什么时候不该用它
诚实地整理一下,大致是这样。
不要用,如果
- 你的应用是 ASIL D 或 SIL 3,却指望靠 core 来兜底。 库只有 ASIL B / SIL 2。编译器是 ASIL D 工具这个事实,填补不了这道缺口。要填上它,得靠你自己去论证,而 Table 9 会准确地告诉你缺的是什么。
- 你的目标平台不在名单上。 在 RISC-V、Cortex-M0/M23/M33 上,你能拿到的是一个能正常运行的编译器,而不是一份认证论据。虽说可以通过合同升级,但那是预算和排期的问题。
- 你的设计需要堆。
alloc在认证范围之外,文档也明确写了这是终端用户的责任。 - 你必须在 Linux 以外的地方构建认证目标产物。 主机资格认定只有 x86-64 Linux 一种。
- 这本来就不是一个安全攸关项目。 这大概是最常见的情况。从认证里得不到任何好处,却要为订阅费(按厂商自己的公告,每用户每月 25 欧元,或每年 240 欧元,截至 2026 年 2 月)和子集纪律买单。用上游 Rust 就好。如果你是第一次接触嵌入式 Rust,no_std 实战指南会对你更有帮助。
用了值回票价的情况
- 产品落在 ASIL B / SIL 2 / IEC 62304 Class C 的范围内,目标平台是 Cortex-M4/M7 或 Armv8-A(或者 QNX 7.1),并且能按
no_std来设计。Sonair 和 Kiteshield 正好站在这个位置上。 - 你需要的与其说是认证本身,不如说是认证材料。Ferrocene 的安全手册、资格认定报告、norm mapping 都是开源的,这意味着你手上有东西可以拿给审核员看 —— 这一点的分量,比听起来要大得多。
- 你所在的组织能够承受子集纪律。每次 lint 报错,都意味着要做一次决定 —— 重写、找 Ferrous 商量,还是自己写一份安全论证再加上
#[allow]。你需要一套能吸收这些决定的评审流程。
结语
一句话概括就是这样:编译器是一款 ASIL D 工具,而库是 ASIL B 软件。 这是两句不同的话,两句都是真的,一旦把它们揉成一句,得出的计划就是错的。
2026 年真正的新闻不是"Rust 通过了认证" —— 那已经是好几年前的旧闻,而且只对了一半。真正的新闻有三件事。第一,已认证子集确实在成长 —— 一个版本里符号数从 5.2 千涨到 8.8 千,随着 core::fmt 落地,"已认证目标上 panic 信息只能是静态字符串"这条约束也消失了。第二,强制机制从标准库 fork 升级成了编译器 pass。第三,厂商把自己证据链上的漏洞写进了公开仓库。
接下来该盯着看的地方也很明确:Table 9 里的分支覆盖率或 MC/DC 什么时候会变成"Applied"。那是通往 ASIL D core 的关卡,而今天公开的任何文档都没说它会到来。在那之前,如果你在为一个嵌入式安全攸关项目评估 Rust,请先读 sphinx-substitutions.toml 的那五行和 method table 的那三行,再去看那一句营销文案。答案全在那里。
参考资料
- Ferrocene 26.02.0 now available! (Ferrous Systems, 2026 年 2 月 15 日) —— 加入 ASIL B,已认证函数 2,903 → 5,169(厂商自计)
- Ferrous Systems Achieves IEC 61508 (SIL 2) Certification for Rust Core Library Subset (2025 年 12 月 3 日) —— 第一个 core 子集认证,Sonair、Kiteshield 案例
- Callgraph analysis (Jynn, 2026 年 4 月 1 日) —— 为何以及如何用
ferrocene::unvalidatedlint 取代子集目标 - ferrocene/ferrocene —— 开源仓库(MIT OR Apache-2.0)
- 26.05.0 发布说明原文(release/1.95) —— core::fmt 认证、lint 引入、目标变更
- 26.02.0 发布说明原文(release/1.92)
- ISO 26262 6-Method Tables —— core 认证按方法逐项标注的应用/未应用表
- Core Certification scope —— Route 3S / SEooC,认证目标的界定
- Core Certification requirements —— "需求是以 doc-comment 的形式实现的"
- Safety Manual qualification scope —— 已获资格认定的目标/库对照表,用户责任
- Safety Manual core constraints —— 用户约束清单
- 目标支持等级文档 —— Qualified / Quality managed / Supported / Experimental
- Ferrocene 公开文档站点(开发分支预览版 —— 警告文档本身可能不准确)
- Ferrocene 26.02.0 adds automotive core certification (eeNews Europe, 2026 年 3 月 19 日) —— 独立报道
- 嵌入式 Rust no_std 实战指南(相关文章)
현재 단락 (1/132)
只要聊到嵌入式 Rust,就总会反复出现这样一句话:"Ferrocene 已经通过了 ISO 26262 ASIL D 认证。"这句话本身没有错 —— Ferrous Systems 的公开文档就是这...