深挖一篇嵌入式内核论文以后,我发现 Rust 正在悄悄改变世界



在知乎看到「Rust在嵌入式开发中的表现如何?」这个问题(阅读原文),因而写了一篇答案,顺便讲一个故事。git


以前看到了 TockOS(Rust实现的实时操做系统)团队在2015年写过的论文:https://www.tockos.org/assets/papers/tock-plos2015.pdfgithub

在论文里面该团队总结了 Rust 开发嵌入式的一些不足,以及他们总结出来 Rust 须要改进的地方。然而,这实际上是TockOS 犯下的一个乌龙错误编程

我来帮你们梳理一下整个乌龙事件的过程,而且帮助你们对嵌入式开发特色有一个基本认识。数组

嵌入式开发的一些特色安全



嵌入式开发特色:微信

  • 嵌入式系统一般使用缺少硬件保护机制的处理器和微控制权,好比内存管理单元,当硬件没法保护软件的时候,语言的安全性则能够保护软件。
  • 嵌入式应用程序对崩溃的容忍度较低,由于它们没法依靠用户干预来从运行时错误中恢复(例如,重启应用程序)。
  • 调试嵌入式内核很是困,由于一般没有日志功能,而且须要物理访问来链接调试器。
虽然安全性没法防止逻辑错误 或 产生Bug,可是它确实能极大保护嵌入式内核免受硬崩溃。不幸的是,对于系统编程来讲,一般的安全语言典型的附加特性,其缺点每每超过这些优势。例如,GC会引入不肯定性延迟,自动内存分配器使常见的内核优化变得复杂,例如Slab分配。
而 Rust 语言,则是在无GC的状况下保证了安全性和性能。TockOS的目标是在内存少于1MB字节的嵌入式平台使用,好比仅有64KB内存的开发平台。怎么看,Rust都是很是适合这个开发目标的。

2015年:Rust 全部权机制带来的问题闭包


可是,在 2015年的论文里,TockOS团队提出,Rust 的全部权在实现嵌入式内核的时候,遇到了三个问题:
  • Rust 的自动内存管理没有针对系统中常常出现的硬件资源和设备驱动程序进行优化。并发

  • 因为项目的基本设置中存在线程不安全问题,Rust的 全部权模型阻止了闭包和其余内核代码之间的资源共享。app

  • 尽管闭包对于简化事件处理是理想的,但对于嵌入式系统而言,它们对动态内存的要求倒是有问题的。
为了更好地支持事件驱动的嵌入式平台,TockOS 团队探索了一种可能的语言功能,称之为「执行上下文(execution contexts)」。当基础硬件约束或执行模型能够可靠地防止并发问题时,此功能将为 Rust 提供一个有价值的工具,用于容许安全的内存共享。
Rust 全部权机制在不少系统下是没有问题的,可是在一些使用基于非线程的并发模型的系统以及必须共享资源的状况下则没法正常工做。
好比,嵌入式操做系统避免了诸如线程之类的内存密集型机制,而是选择了事件驱动的并发性。相似地,微控制器一般没有硬件内存管理单元,而且不支持虚拟内存。所以,它们避免了动态内存机制,这是由于不可能交换内存以在内存耗尽时正常降级,也由于能够明确禁止动态分配。
为了不全部权带来的一些问题,团队使用了各类hack的写法,可是反而破坏了对嵌入式操做系统利用编译时安全检查的目的。

2017年:然而,过了两年发现乌龙了函数



而后,在2017年的时候,TockOS 发现,他们实际上是由于对 Rust 的认识不深,致使了误解。而后又立刻发了一篇新的论文来纠正以前的错误认知。问题的解决方法也比较简单:使用Rust的内部可变性。
博客: https://www.tockos.org/blog/2017/apsys-paper/
论文: https://www.tockos.org/assets/papers/rust-kernel-apsys2017.pdf
在新的论文中,TockOS团队说:
以咱们在Rust中编写资源高效的嵌入式内核的经验发现,仅需一小部分不安全的抽象就能够造成通用的内核构建块。因此,咱们认为 Rust 选择使用线性类型系统来避免运行时内存管理将使下一代安全操做系统成为了可能。

Unsafe 代码的安全抽象



在新的论文里讲到,TockOS中须要信任两种类型的 Unsafe 代码。
  • 第一个由Rust语言团队编写的Rust语言机制和库组成。这些提供了安全的接口,可是它们基本都是基于Unsafe代码的安全抽象。

  • 第二种必须信任的代码是由内核开发人员编写的内核代码部分,这些部分使用Unsafe代码来实现基本的操做系统功能,但又能够提供安全的接口。
具体来讲,内核依赖于如下四个使用 Unsafe 代码的Rust抽象形式:
  • 边界检查:数组通过边界检查,所以 Unsafe 代码使用length字段来确保访问是安全的。
  • 迭代器优化:跨Rust数组操做的规范方法是使用迭代器,这些迭代器使用Unsafe代码来避免没必要要的中间检查。
  • 编译器内部函数和基本类型强制转换。
  • 使用Cell。

论文后面还有不少关于嵌入式硬件抽象的内容,就不一一罗列了。
这个故事告诉咱们,作 Rust 开发,必定要先掌握好 Rust 的概念,不然会形成乌龙。

2020年:Tock OS 现状



打开TockOS团队最新博客看了一眼,真不得了。
https://www.tockos.org/blog/2020/hello-opensk/

Google发布的这个 OpenSK 是跑在 Tock上面的!


插一段新闻
现在,FIDO安全密钥经过提供一种简单的两因素身份验证(2FA)来防止网上诱骗,从而保护了账户,这种形式正变得愈来愈普遍。可是,并不是每一个人均可以访问和使用它们。为了促进和改善对FIDO Authenticator实现的访问,Google宣布发布OpenSK,这是用Rust编写的安全密钥的开源实现,该密钥同时支持FIDO U2F和FIDO2标准。
该项目将帮助业余爱好者,硬件供应商和研究人员进行开发和创新。经过刷新Nordic芯片加密狗上的OpenSK固件,人们能够制做本身的安全密钥。
除了价格低廉外,Google解释说选择Nordic芯片加密狗做为初始参考硬件是由于它支持FIDO2中提到的全部主要传输协议,包括NFC,低功耗蓝牙,USB和专用硬件加密内核。此外,Google提供了可定制的3D打印保护套,能够在各类打印机上使用。
根据Google的说法,OpenSK是用Rust编写的,可在TockOS上运行,以提供更好的隔离性和更简洁的操做系统抽象以支持安全性。Rust具备强大的内存安全性和零成本的抽象性,从而使代码不易受到逻辑攻击。经过其沙箱体系结构,TockOS提供了安全密钥小应用程序,驱动程序和内核之间的隔离,这是构建深度防护所需的。Google对TockOS的贡献,包括闪存存储系统和补丁,已上传到TockOS存储库的上游。
谷歌还表示,但愿将OpenSK扩展到其余类型的芯片,并带来更多创新和新功能,以及更强大的嵌入式加密技术。
看见了吗?Google的OpenSK 也是 Rust实现的: https://github.com/google/OpenSK

Rust 正在悄悄的改变世界!



感谢阅读


本文分享自微信公众号 - 觉学社(WakerGroup)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索