Rust告别实验标签:Linux内核开发正式进入双语言时代

2026年4月中旬,Linux 7.0内核的发布在开源社区激起了远比版本号数字本身更为深远的涟漪。在这个被Linus Torvalds亲自打上稳定标签的版本中,一项看似 merely administrative 的改动却承载着历史性的重量:Rust语言支持正式脱离"实验性"(experimental)状态,成为内核开发的正规成员。这意味着,从Linux 7.0开始,用Rust编写内核驱动不再是备受争议的尝试,而是与C语言平起平坐的官方选择。

Miguel Ojeda,这位Rust-for-Linux项目的负责人,在移除实验标签的提交中写得干脆利落:"The experiment is done, i.e. Rust is here to stay." 这句话的分量,不亚于当年Git取代BitKeeper成为Linux源码管理工具的时刻。它标志着一个长达五年的大规模技术验证画上了句号,同时也开启了开源操作系统内核开发的全新纪元。

从边缘试探到核心认可:Rust入核的五载长征

Rust与Linux内核的缘分并非始于2021年。早在2019年的Linux Security Summit上,就有开发者提出了用Rust编写内核模块的可能性。当时的设想更多是一个思想实验:能否用一种现代系统编程语言,在不牺牲性能的前提下,根除困扰内核开发数十年的内存安全问题?

2022年底,Rust支持正式合入Linux 6.1主线内核。但那时的状态被明确标注为"实验性"——文档中坦率地告诉所有开发者:"目前没有任何适合生产环境使用的树内驱动,Rust支持仍在开发中。" 这种谨慎是必要的。内核不是普通的应用程序,它是整个计算机系统的基石。任何编程语言的引入,都必须经过严苛的技术、流程和社会层面的检验。

在接下来的几个内核版本中,Rust-for-Linux团队以令人敬佩的耐心逐步推进。6.2版本引入了更多核心抽象,6.4版本增加了对网络子系统的初步支持,6.7版本开始有了真正可用的驱动原型。到了2025年的Linux内核维护者峰会,讨论的氛围已经发生了根本性转变。稳定内核维护者Greg Kroah-Hartman在评估了大量Rust驱动的实际表现后给出了结论性的判断:"用Rust编写的驱动,在安全性方面显著优于C语言实现。"

这个结论并非空穴来风。根据Android安全团队发布的统计数据,在已经部署到数百万台设备的Rust内核代码中,内存安全相关的漏洞数量为零。这与C语言驱动中持续出现的use-after-free、缓冲区溢出、空指针解引用形成了鲜明对比。2025年12月,Miguel Ojeda向内核邮件列表提交了移除"Rust实验"标签的补丁。两个月后,Linux 7.0发布,Rust正式"转正"。

技术原理:Rust为何能征服内核开发

要理解Rust在内核中的价值,不能停留在"内存安全"这个笼统的标签上。真正让内核维护者们信服的,是Rust将安全保证嵌入类型系统和编译期的独特能力,以及它与C语言生态的无缝衔接。

所有权系统:在编译期消灭整类漏洞

C语言内核开发中最痛苦的bug类别——use-after-free、双重释放、数据竞争——在Rust中不是通过运行时检查或编码规范来防范,而是通过所有权(Ownership)、借用(Borrowing)和生命周期(Lifetime)机制在编译阶段彻底消除。

考虑一个典型的内核场景:一个PCI设备驱动在probe函数中分配了设备私有数据结构,在remove函数中释放它。在C语言中,如果某个并发路径在remove之后仍持有该结构的指针,就会触发use-after-free。Rust的所有权系统从根本上禁止了这种可能:

rust
use kernel::prelude::*;
use kernel::pci;

struct MyPciDriver {
    device: pci::Device,
    private_data: Box<MyDeviceData>,
}

impl pci::Driver for MyPciDriver {
    fn probe(dev: &mut pci::Device, id: &pci::DeviceId) -> Result<Self> {
        let data = Box::try_new(MyDeviceData::new())?;
        pr_info!("PCI device probed: {:?}
", dev.name());
        Ok(MyPciDriver {
            device: dev.clone(),
            private_data: data,
        })
    }

    fn remove(&mut self, _dev: &mut pci::Device) {
        pr_info!("PCI device removed
");
        // self.private_data 在这里被隐式释放
        // 编译器保证没有任何地方还能访问这块内存
    }
}

在这段代码中,Box<MyDeviceData>的所有权与MyPciDriver实例绑定。当驱动实例被销毁时,私有数据自动释放,且编译器会在编译期验证没有任何悬垂引用存在。这不是依靠程序员的谨慎,而是类型系统的硬性约束。

零成本抽象:安全不等于慢

内核开发者对性能极度敏感。历史上,许多"安全语言"之所以无法进入系统编程领域,正是因为它们的安全保证需要运行时开销。Rust的核心理念之一是"零成本抽象"(Zero-Cost Abstractions):高级语言特性在编译后产生的机器码,与手写的C代码同样高效。

以Linux 7.0中合入的Rust NVMe驱动为例,在高IOPS(每秒输入输出操作数)工作负载下,其延迟相比传统C驱动降低了约10%。这个反直觉的结果源于Rust的所有权模型消除了传统锁机制的过度同步开销。当编译器能够在编译期证明数据访问的安全性时,就不需要运行时的锁保护。这种"编译期并发"(Compile-Time Concurrency)让Rust代码在某些场景下反而比保守的C代码更快。

FFI与绑定:和C世界的和平共处

Linux内核拥有超过3000万行C代码,不可能在一夜之间重写。Rust-for-Linux项目的智慧之处在于,它没有试图取代C,而是构建了一座桥梁。

内核中的Rust代码分为三个层次:

  • 自动生成的绑定(Bindings):通过bindgen工具从C头文件自动生成原始的、不安全的FFI声明

  • 安全抽象层(Abstractions):在绑定之上封装安全的Rust API,将内核的不变式编码进类型系统

  • 驱动与核心逻辑:只使用安全抽象层编写,原则上不直接调用unsafe代码
  • 这种分层架构意味着,C语言子系统不需要任何改动就能被Rust驱动调用,而Rust驱动提供的安全保证则向上传播。例如,DRM(Direct Rendering Manager)子系统的Rust抽象层会确保GPU命令提交缓冲区在生命周期内有效,防止恶意或错误的用户态程序触发内核内存损坏。

    rust
    // 一个简化的Rust内核模块框架示例
    use kernel::prelude::*;
    
    module! {
        type: MyKernelModule,
        name: "rust_demo_module",
        author: "Kernel Developer",
        description: "A minimal Rust kernel module",
        license: "GPL",
    }
    
    struct MyKernelModule;
    
    impl kernel::Module for MyKernelModule {
        fn init(_module: &'static ThisModule) -> Result<Self> {
            pr_info!("Rust kernel module loaded successfully
    ");
            Ok(MyKernelModule)
        }
    }
    
    impl Drop for MyKernelModule {
        fn drop(&mut self) {
            pr_info!("Rust kernel module unloading
    ");
        }
    }

    这段代码展示了一个完整的、可加载的内核模块。module!宏处理模块元数据和初始化,kernel::Module trait定义了模块生命周期,Drop trait确保资源清理。模块加载器在Linux 7.0中已经能够自动处理Rust特定的初始化流程,开发者不再需要编写繁琐的胶水代码。

    实践案例:Rust在内核中的真实战场

    实验标签的移除不是终点,而是起点。真正说服内核社区的是Rust在实际关键模块中的表现。Linux 6.15和7.0中合入的Rust代码,已经覆盖了从存储到网络、从图形到移动设备的多个核心领域。

    NVMe存储驱动:性能与安全的兼得

    NVMe(Non-Volatile Memory Express)是现代高性能SSD的标配协议,其驱动性能直接影响整个系统的I/O吞吐。Rust NVMe驱动的意义在于,它首次证明了安全语言不仅能匹配C的性能,还能在某些指标上超越。

    在传统C驱动中,为了避免并发访问导致的竞态条件,开发者通常会采用保守的锁策略。这种"以防万一"的做法在确保安全的同时,也 serializes 了本可并行的操作。Rust的所有权系统允许编译器在编译期分析数据访问模式,只在真正需要的地方插入同步原语。结果是,在高并发I/O场景下,Rust驱动的上下文切换次数和锁争用显著降低,延迟曲线更加平滑。

    网络子系统与DRM:向核心领域渗透

    Linux 6.15内核中的Rust代码扩展到了网络驱动和GPU驱动(DRM子系统)。网络驱动的挑战在于处理来自硬件的异步中断和来自用户态的系统调用,这两者的并发交互是传统bug的温床。Rust的SendSync trait在编译期标记了类型的线程安全性,使得跨上下文传递数据时,不安全的访问模式会被编译器拒绝。

    DRM子系统的Rust化则更具战略意义。图形驱动一直是内核中代码量最大、复杂度最高的部分之一。以AMD和Intel的开源驱动为例,它们需要管理复杂的GPU内存层次结构、命令缓冲区提交和硬件状态转换。Rust的类型系统可以将这些状态机编码为不可变的类型转换,确保驱动不会在某个状态下执行非法操作。例如,一个已经提交到硬件的命令缓冲区在Rust类型系统中会被标记为不可变,直到硬件完成处理并返回信号。

    Android的先行者角色

    在桌面和服务器内核还在讨论Rust的可行性时,Android已经用实际行动投了赞成票。Android 16基于Linux 6.12内核,其中Google的ashmem(匿名共享内存)子系统已完全用Rust重写。这项技术运行在上亿台Android设备上,包括Pixel系列和大量第三方厂商的设备。

    Google Android安全团队的报告提供了最有说服力的证据:在已部署的Rust内核代码中,生产环境中未出现任何内存安全漏洞。这与C语言实现的同类组件形成了鲜明对比。对于移动设备而言,这意味着更少的安全补丁、更稳定的系统和更长的设备支持周期。

    Rust与C:不是取代,而是进化

    尽管Rust的崛起势头强劲,但宣称"C语言已死"既不现实也不负责任。Linux内核维护者们的共识是:C将继续长期存在,但新开发的领域将越来越多地选择Rust。

    Greg Kroah-Hartman在2026年印度开源峰会上的表态很有代表性:"Linux不会突然放弃C。但看看周围的生态——Linux、Git,还有许多其他主要的开源项目,它们都在向Rust迁移。这不是潮流,而是工程上的必然。"

    这种双语言共存的局面将在未来十年成为内核开发的常态。已有的C代码经过数十年打磨,其稳定性和性能已经得到验证,没有理由为了重写而重写。但在以下场景中,Rust正成为默认选择:

  • 新驱动开发:尤其是面向PCIe、USB等新硬件的驱动

  • 安全关键模块:处理不可信用户态输入的子系统,如Binder、ashmem

  • 并发密集型组件:网络栈、存储栈中涉及大量异步交互的模块
  • 对于C语言维护者而言,这种转变并非威胁,而是减负。Rust抽象层在封装C子系统时,实际上承担了验证调用合法性的责任。这意味着C代码的作者不需要再担心Rust驱动的调用方式是否安全——类型系统已经保证了这一点。

    工具链与生态:从内核到发行版的全栈演进

    Rust在内核中的稳定化只是更大图景的一部分。2026年5月,Debian的APT包管理器宣布引入硬性的Rust依赖,用于.deb.ar.tar解析以及HTTP签名验证。APT是Debian及其衍生发行版(Ubuntu、Linux Mint、Kali Linux、Raspberry Pi OS等)的基础设施。当APT依赖Rust时,Rust实际上成为了全球数亿台Linux设备的必备组件。

    这种从内核到用户态工具链的渗透,解决了Rust内核开发中的一个关键问题:工具链的普遍性。过去,在某些嵌入式或特定架构上编译Rust内核模块可能面临工具链缺失的问题。随着Rust成为发行版核心基础设施的一部分,这一障碍正在迅速消失。

    当然,挑战依然存在。对于一些 legacy 架构(如Alpha、HP PA-RISC、M68k、SH4),提供可用的Rust编译器支持仍然是社区需要解决的问题。Debian给出了六个月的时间窗口,如果这些架构无法提供工作的Rust工具链,支持可能会被移除。这是技术演进的残酷一面,也是开源社区需要集体应对的挑战。

    现实的挑战:学习曲线与unsafe的陷阱

    任何技术都不是银弹,Rust在内核中的推广同样面临实实在在的障碍。

    学习曲线是第一个门槛。内核开发本身就是计算机科学中最具挑战性的领域之一,需要深入理解内存模型、中断上下文、锁层次结构和并发原语。叠加Rust的所有权模型后,开发者需要同时掌握两套复杂的知识体系。目前,同时精通内核机制和Rust语言的开发者仍然是稀缺资源,尽管这个群体正在快速扩大。

    文档缺口是第二个现实问题。C语言内核开发拥有三十年的文档积累、书籍、教程和示例代码。相比之下,Rust内核API的文档虽然在Linux 7.0中有了显著改善,但在深度和广度上仍有差距。开发者在某些场景下会发现,C语言的实现路径有详尽的文档指导,而Rust路径可能需要直接阅读源码。

    unsafe Rust是第三个值得警惕的陷阱。CVE-2025-68260,即Android Binder重写中的竞态条件漏洞,是一个深刻的教训。这个bug位于unsafe代码块中——那是Rust程序员明确告诉编译器"我知道自己在做什么,请相信我"的地方。本质上,unsafe块中的Rust代码与C代码面临同样的风险。这个CVE没有否定Rust的安全保证,反而验证了它:安全的Rust代码确实安全,而危险只存在于显式标记的unsafe边界内。

    Google Android团队对此的总结是:最小化unsafe代码的表面积,为每一个unsafe块详细文档化其不变式(invariants),并将unsafe视为例外而非模式。这三条原则应当成为所有Rust内核开发者的铁律。

    TIOBE指数的微妙与产业现实

    编程语言流行度排名TIOBE Index对Rust的态度一直颇为微妙。在2026年的榜单中,Rust并未如某些拥趸期待的那样蹿升至前十,甚至在前十五名中也难觅其踪。这种"低调"的排名与Rust在内核、浏览器引擎(Servo/Firefox)、云原生基础设施(TiKV、Vector)中的实际渗透形成了有趣的反差。

    但TIOBE的统计方式——基于搜索引擎查询量——反映的是大众关注度,而非工业界的实际采用深度。在系统编程这个细分领域,Rust的影响力已经远远超过了其排名所暗示的。Linux内核、Windows内核(部分组件)、Android系统、Cloudflare的基础设施、AWS的Firecracker虚拟化平台——这些支撑现代数字世界的底层系统,都在用Rust编写或重写关键组件。

    TIOBE指数忽略了一个关键维度:Rust的学习曲线陡峭意味着开发者不需要频繁搜索基础语法,而这恰恰降低了其在搜索引擎中的"可见度"。与此同时,Rust在Stack Overflow开发者调查中的"最受喜爱语言"榜单上已连续多年位居前列。对于内核开发这样高度专业化的领域,开发者的质量和代码的可靠性远比语言在大众中的知名度重要。

    未来展望:内核开发的新范式

    Rust成为Linux内核一等公民,影响的不仅仅是代码语言的选择,更是整个内核开发方法论的重塑。

    代码审查的范式转移正在发生。传统的内核代码审查极度依赖人工检查内存管理正确性,这是一项耗费大量资深维护者精力的工作。Rust的类型系统在很大程度上自动化了这种检查。未来的代码审查可以将更多注意力放在算法正确性、性能特征和架构设计上,而不是反复确认"这个指针是否被正确释放"。

    新贡献者的门槛也在发生微妙的变化。一方面,Rust的学习曲线提高了入门难度;另一方面,一旦掌握了Rust,内核开发中许多曾经需要多年经验才能避免的陷阱,现在由编译器自动防范。这可能意味着内核社区能够吸引更多来自用户态Rust生态的新鲜血液,尤其是那些有Web后端或嵌入式Rust经验但缺乏内核C开发背景的开发者。

    跨平台内核开发同样受益。Rust的cargo构建系统和强类型接口描述,使得为不同架构生成正确的内核绑定变得更加可靠。随着GCC对Rust的支持逐步成熟(GCCRS项目正在推进),内核将拥有除LLVM之外第二个完整的Rust编译器选择,这对于某些对工具链有特殊要求的嵌入式场景尤为重要。

    结语

    Linux 7.0中Rust的"转正",是开源操作系统发展史上的一个决定性时刻。它不仅仅是一种新编程语言被接纳,更是对"系统软件如何在保证极致性能的同时实现内存安全"这一根本问题的回答。

    Miguel Ojeda和他的团队用了五年时间,完成了这项看起来不可能的任务:让一门现代语言融入一个拥有三十年历史、超过三千万行C代码的庞大系统。这个过程中没有革命性的重写,没有对现有维护者的排斥,而是通过精心设计的抽象层、耐心的社区沟通和扎实的工程实践,逐步实现了一种和平演进。

    对于内核开发者而言,现在的问题是:当你开始一个新的驱动项目或重构一个安全敏感的子系统时,是否还有理由不选择Rust? Greg Kroah-Hartman的观察已经给出了方向——Linux、Git和更多开源项目正在向Rust迁移。这不是对C的背叛,而是对更可靠、更安全的系统软件的追求。

    开源操作系统的内核开发,正式进入双语言时代。而Rust,已经证明它值得占据其中一个席位。

    💬 评论区 (0)

    暂无评论,快来抢沙发吧!