深挖一篇嵌入式內核論文以後,我發現 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源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索