安全嵌入式操作系統Tock

Tock是一種用於傳感器網絡和物聯網的安全嵌入式操作系統。Tock是第一個允許多個不受信任的應用程序在基於微控制器的計算機上同時運行的操作系統。Tock內核使用Rust(一種不依賴垃圾回收器的內存安全系統語言)編寫。用戶空間應用程序在可以用任何語言編寫的單線程進程中運行。

Tock設計用於在基於Cortex-M和RISC-V的嵌入式平臺上運行多個併發的、互不信任的應用程序。Tock的設計圍繞著保護,包括潛在的惡意應用程序和設備驅動程序。Tock使用兩種機制來保護操作系統的不同組件。首先,內核和設備驅動程序是用Rust編寫的,Rust是一種提供編譯時內存安全、類型安全和嚴格別名的系統編程語言。Tock使用Rust來保護內核(例如調度器和硬件抽象層)不受平臺特定設備驅動程序的影響,並將設備驅動程序彼此隔離。其次,Tock使用內存保護單元將應用程序彼此和內核隔離開來。Tock體系結構如下圖所示。

安全嵌入式操作系統Tock

上圖顯示了Tock的體系結構。代碼分為三類:核心內核、膠囊和進程。內核和膠囊都是用Rust寫的。Rust是一種類型安全的系統語言;Rust語言對內核設計影響的關鍵思想是Rust代碼不能以不同於預期的方式使用內存(例如,溢出緩衝區)。

大多數操作系統使用類似於進程的抽象來提供組件之間的隔離:每個組件都有自己的內存地址空間(用於堆棧、堆、數據),其他組件無法訪問這些內存。進程很好,因為它們為隔離和併發提供了方便的抽象。然而,在資源有限的系統上,比如內存遠小於1MB的微控制器,這種方法會導致隔離粒度和資源消耗之間的權衡。Tock的體系結構通過使用一個語言沙箱來隔離組件和一個協作調度模型來解決這個問題。首先,Tock中的所有組件包括內核中的組件都是相互不信任的。在內核內部,Tock通過一個基於語言的隔離抽象來實現這一點,該抽象不需要內存或計算開銷。在用戶空間中,Tock使用傳統的進程模型,其中進程與內核隔離,並使用硬件保護機制相互隔離。Tock有利於系統的整體可靠性,並阻止組件在出現錯誤時阻止系統進程。

安全嵌入式操作系統Tock

Tock包括三個架構組件。用Rust編寫的小型可信內核實現了硬件抽象層(HAL)、調度器(Scheduler)和特定於平臺的配置(Config)。其他的系統組件是用兩種保護機制之一實現的:膠囊(內核編譯時使用Rust的類型和模塊系統來保證安全)和進程(使用MPU在運行時進行保護)。因此,每種方法都更適合實現不同的組件。一般來說,驅動程序和虛擬化層實現為膠囊,而使用現有代碼/庫的應用程序和複雜驅動程序實現為進程。

膠囊

膠囊是一種Rust結構和相關功能。膠囊直接相互作用,訪問暴露的字段並調用其他膠囊中的函數。可信平臺配置代碼初始化它們,使它們能夠訪問所需的任何其他膠囊或內核資源。膠囊可以通過不導出某些函數或字段來保護內部狀態。

膠囊以特權硬件模式在內核內部運行,但Rust的類型和模塊系統保護核心內核不受錯誤或惡意膠囊的影響。由於類型和內存安全性在編譯時是強制的,因此不存在與安全性相關的開銷,而且膠囊需要最小的錯誤檢查。例如,膠囊從不需要檢查參數的有效性。如果引用存在,則指向正確類型的有效內存。

Rust的語言保護提供了強大的安全保證。除非膠囊能夠顛覆Rust類型的系統,否則它只能訪問顯式授予它的資源,並且只能以這些資源公開的接口允許的方式訪問。但是,由於膠囊是在與內核相同的單線程事件循環中協同調度的,因此必須信任它們以保證系統的活性。如果膠囊崩潰,或者不向事件處理程序讓步,則系統只能通過重新啟動來恢復。

進程

進程是與內核隔離的獨立應用程序,在與內核分離的執行線程中以較低的權限運行。內核優先調度進程,因此進程比膠囊具有更強的系統活性保證。此外,Tock使用硬件保護在運行時強制執行進程隔離。這允許用任何語言編寫進程,並在運行時安全加載。

內存佈局

進程之間、內核和底層硬件之間由硬件內存保護單元(MPU)顯式隔離。MPU限制進程可以訪問的內存地址。在進程允許區域之外的訪問會導致錯誤並陷阱到內核。

存儲在flash中的進程代碼可以通過只讀存儲器保護區訪問,而其存儲器被分配為RAM的一個連續區域。Tock進程的一個新方面是在地址空間的頂部存在一個“授權”區域。這是分配給進程的內存,但由進程既不能讀也不能寫的內存保護區域覆蓋。授權區域允許內核從進程借用內存以響應系統調用。

源碼結構

Tock有幾個主代碼目錄,包括arch、boards、capsules、chips、doc、kernel、libraries、tools和vagrant。

安全嵌入式操作系統Tock

arch:存儲特定於體系結構的代碼。包括用於執行上下文切換和進行系統調用的代碼。

boards:包含特定Tock平臺的代碼。包括用於將MCU的IO管腳配置為正確狀態的代碼,初始化內核並加載進程。此目錄中的主體文件是main.rs,主體初始化函數是reset_handler(在MCU復位時執行)。

capsules:包含獨立於MCU的內核擴展,可以構建在特定外設的特定芯片實現之上。

chips:包含微控制器專用代碼,如SPI、I2C、GPIO、UART等微控制器專用代碼的實現。

doc:包含Tock的文檔,包括內部接口和教程的規範。

kernel:包含與微控制器無關的內核代碼,如調度程序、進程和內存管理。這個目錄和arch是所有核心內核代碼所在的位置。

libraries:包含內部使用和外部共享的庫。

tools:包含幫助編譯和代碼維護的關聯工具,例如檢查代碼格式、轉換二進制文件和生成腳本。

vagrant:包含有關如何使Tock在類似於虛擬機的環境中運行的信息。


分享到:


相關文章: