論壇總覽 BeagleV-beta RISC-V 開源單板電腦 OpenSBI 簡介與說明

標籤: , , ,

正在檢視 3 篇文章 - 1 至 3 (共計 3 篇)
  • 作者
    文章
  • #631
    johnson
    管理員
    @johnson

    零、參考資料

    適用於BeagleV的OpenSBI github專案連結:

    https://github.com/starfive-tech/opensbi

    WD的SBI說明投影片(OpenSBI最主要由Western Digital Corporation貢獻):

    https://riscv.org/wp-content/uploads/2019/12/Summit_bootflow.pdf

    RISC-V官方OpenSBI

    https://github.com/riscv/opensbi

    壹、前言

    OpenSBI是一個介於M-Mode與S-Mode之間的應用界面,引述官方github說明:

     

    The RISC-V Supervisor Binary Interface (SBI) is the recommended interface between:

    A platform-specific firmware running in M-mode and a bootloader, a hypervisor or a general-purpose OS executing in S-mode or HS-mode.
    A hypervisor running in HS-mode and a bootloader or a general-purpose OS executing in VS-mode.

    RISC-V二進制介面(SBI)主要針對以下情況:

    1. 在M-mode下運行的特定於平台的韌體,以及在S-mode 或HS-mode 下執行的引導程式,管理程式或通用OS。
    2. 在HS-mode下運行的管理程式以及在VS-mode下執行的引導加載程式或通用OS。

    其中,M-mode是指Machine Mode,Hypervisor是一個搭載不同作業系統的小程式,HS-mode 或 S-mode是指作業系統Operation System。

    但上述說明似乎還是不淺顯易懂,依據筆者的理解,OpsnSBI是SBI規範下的一個實作軟體,他負責調度使用者或作業系統的命令給底層硬體。除此之外,還將各家廠商的平台進行整合,讓OpenSBI不會碎片化。

    在更簡單的表示就是作業系統與硬體系統的媒介。

     

    貳、簡介

     

    https://en.wikipedia.org/wiki/Protection_ring

    上圖是傳統x86架構中的Privilege Ring。

    在傳統的x86架構系統中,CPU為了更高的安全性以及避免系統硬體被惡意程式控制,創造一種中文名為”分級保護域” Privilege Level的架構,依據維基百科節錄:

    電腦作業系統提供不同的資源訪問級別。在計算機體系結構中,Rings是由兩個或更多的特權態組成。在一些硬體或者微代碼級別上提供不同特權態模式的CPU架構上,保護環通常都是硬體強制的。Rings是從最高特權級(通常被叫作0級)到最低特權級(通常對應最大的數字) 依序排列。在大多數作業系統中,Ring 0擁有最高特權,並且可以和最多的硬體直接互動(比如CPU,快取記憶體)。

    這種架構被證實是可行且有效的,因此如ARM、RISC-V也都採用這種方式來保護電腦的CPU與其他硬體設備。

    在RISC-V架構中,由最低優先權到最高優先權分別是

    User mode (U-mode)

    Supervisor mode(S-mode)

    Hypervisor mode(H-mode/HS-mode)

    Firmware(M-mode)

    RISC-V的系統優先層級對應到ARM架構如下圖所示:

    除此之外,在電腦的作業系統架構中,Hypervisor又稱為虛擬機器監視器,是用來建立與執行虛擬機器的軟體、韌體或硬體。

    https://zh.wikipedia.org/wiki/Hypervisor

    上圖是Hypervisor Type1與Tpye2 在系統中的腳色。

    在我們這個層級,由於還沒有OS在執行,因此我們的Hypervisor是Type1的型態,介於上層作業系統與下層硬體的中介。

    RISC-V是一個將過去指令集去蕪存菁的新架構,其泛用性被各家廠商欽賴。然而這將無法避免整個RISC-V架構碎片化的問題(Fragmentation)。為了避免最終RISC-V變成各家廠商坐擁獨立標準的混亂指令集架構,由RISC-V Foundation統一出一個Supervisor規範名為SBI,即”Supervisor Binary Interface”。

     

    參、RISC-V 系統啟動流程

    在系統啟動之前,有些開發板會提供啟動模式的選項,可以透過指撥開關或電阻等等方式來實現0與1的硬體訊號。

    在BeagleV中,電路圖就有提供BootMode的選擇

    傳統的系統開機流程如下:

    首先是圖中ROM方塊,又稱作Zero Stage Bootloader

    CPU內部的ROM中會存放引導啟動程式,當開發版上電後,系統時脈開始震盪,CPU收到時賣訊號後,便會從這個ROM的位址(如0x08000000)開始讀取啟動程式碼。

    這部分的啟動程式包含硬體中斷向量、SRAM的設定參數等等。

    接著是LOADER部分,又稱作First Stage Bootloader

    當SRAM被設定完成,CPU會把要執行的程式碼由外部的EEPROM或其他儲存媒介載入到SRAM中執行。由於CPU內部的ROM非常珍貴,因此比較主要的開機程序會在SRAM中執行。

    這裡會再把板子上的DDRAM做初始化設定,並且載入下一階段的啟動程式。

    下一步是RUNTIME程式,其全名是Runtime envoiroment,執行時系統

    可以理解成所有應用程式會呼叫到共同程式碼,也就是標準Library。

    在Linux系統中可以是glibc等等。

    他是一種把半編譯的執行碼在目標機器上執行的環境,其包含SOC的安全設定以及Bootloader的設定等等。在RISC-V架構中,Runtime系統是由OpenSBI實作的。

    最後在進入系統之前,要先載入Bootloader。

    常見的Bootloader有U-Boot, GRUB, LinuxBoot等等。這層Bootloader做的事情是建立核心的檔案系統、網路設定、以及開機的選項設定等,有些也會加入顯示器設定等周邊裝置的參數。

    最後,我們就能夠進入Operation System(OS)來做任何我們想要的操作。

    RISC-V與傳統開機流程有些許不同,其中最大的差異是第二階段啟動

     

    RISC-V的開機流程如下

    :

    將傳統系統動流程與RISC-V啟動流程互相比對後,會發現兩者其實大同小異,主要是中間OpenSBI是RISC-V特有的。

    雖然ARM架構的系統在啟動時也有專屬的ATF(ARM Trusted Firmware) 做為RUNTIME的腳色,但在這邊OpenSBI還包含整合家廠商不同的韌體,並且規範統一的指令名稱。

     

    肆、OpenSBI特色

    OpenSBI 最主要的特色有以下幾點:

    1. 分層結構設計使整體通用於各種結構

    – 包含描述平台(platform)抽象概念(abstraction)的通用SBI函式庫,大部分被外部韌體或開機引導程序使用,如EDK2等。

    – 特定平台函式庫 ,與核心函式庫相當但多了特定平台所需之驅動程式。

    – 特定平台韌體參考,提供三種不同型態的RUNTIME韌體。

    2.超廣泛的硬體支援

    -支援32位元(RV32)與64位元(RV64)

    -支援Hypervisor模式

    -支援未對齊的加載/儲存處理(Misaligned load/store handling )

    (因為未對齊的記憶體或資料位址會造成整體性能下降)

    -支援丟失的CSR模擬

    -支援使用PMP保護韌體(PMP: Physical Memory Protection)

    那為什麼RISC-V架構的OpenSBI要這麼講求開發板 (Platform) 的概念呢?

    因為RISC-V是一個開源的硬體架構,大家可以不用支付權利金使用指令集以及核心,但這一定會造成各家廠商擁有一定的能力開發後,導致碎片化發生,就是大家擁有各自的客製化指令集,或客製化的IC Layout,最後成為一盤散沙。Android作業系統在開發初期就經歷過類似的事件,一直到後期才逐漸統一。所以要避免碎片化,他們想出一套方法,讓每一個產品自己需要的平台專屬部分獨立出來,共用的部分則保留在主要SPI函式庫中。OpenSBI的資料庫架構如下圖所示:

    圖中,最基本的SBI函式庫是libsbi.a,這是每個RISC-V平台都會用到的通用函式庫。

    接著,廠商自己的平台會有自己的libplatsbi.a函式庫,最後,再將整個硬體客製化(platform specific)的韌體打包好使用。

    伍、OpenSBI韌體型態

    OpenSBI最後包好的韌體可以有三種型態,這三種型態的韌體都是基於開發板的,其分別是:

    1. FW_PAYLOAD

    -連結下一啟動階段的韌體

    2.FW_JUMP

    -可以跳躍到下一啟動階段的靜態位址的韌體

    3.FW_DYNAMIC

    -可以跳躍到下一啟動階段的動態位址的韌體

    接下來會對三種型態的韌體作介紹。

     

    FW_PAYLOAD

    FW_PAYLOAD如同其名,是一個韌體載體。

    他把RUNTIME(運行時系統,也就是library)與下一階段BootLoader包在一起。這麼做的好處可以直接覆蓋裝置樹(Device tree blob)設定,讓開機速度更快。

    但缺點是當OpenSBI或BootLoader有更動,我們就要重新建構一個PAYLOAD,且沒有溝通機制讓LOADER與PAYLOAd做通訊。

    而FW_PAYLOAD的啟動流程如上圖所示,會照順序從ROM>LOADER>FW_PAYLOAD>OS 進行啟動。

     

    FW_JUMP

    FW_JUMP型態的韌體與FW_PAYLOAD最大的差異除了沒有把OpenSBI與BootLoader包在一起之外,JUMP型態的韌體在啟動過程進行到LOADER階段,會同時載入RUNTIME以及BootLoader,這在使用QEMU進行模擬的情況非常好用。

    但這種方法缺點是LOADER階段載入BootLoader的位址是寫死的,且與FW_PAYLOAD相同,這種型態的韌體也沒有與前一個開機階段互相溝通的機制。

     

    FW_DYNAMIC

    FW_DYNAMIC改善上述FW_JUMP的缺點,讓OpenSBI可以動態載入下一啟動階段。透過使用fw_dynamic_info結構的參數,包含版本、下一啟動階段位址、模式等等參數設定下一階段的流程。可以注意到struct fw_dynamic_info中第一項”magic”參數,它的功能是讓使用這個struct的程式可以利用magic與version參數來檢查引用的資料型態是否正確。

    由於OpenSBI是在kernel之前的韌體,還沒有載入glibc或標準C/C++語言函式庫,因此像是class等宣告無法作用,只能用struct來撰寫相同功能。

    但衍生出一個缺點,就是前一階段的啟動器需要注意fw_dynamic_info的資料內容與型態。

    前言中有提到,RISC-V把整個電腦系統分成M-mode、S-mode以及U-mode,每個層級不能直接存取更底層的資源,需要透過ABI或library進行呼叫。但在OpenSBI中,沒有ABI也沒有library,只能夠過LOADER在M-mode存放資料存在暫存器,RUNTIME(OpenSBI)在S-mode中讀取暫存器的資料這種方法來傳遞資料。

    FW_DYNAMIC利用”a2″暫存器把struct fw_dynamic_info 放進去,讓OpenSBI讀取。但雖然都是資料,卻又衍生出”Big ending/ Little ending” 也就是”位元組順序“的問題。所以在這底層階段,位元組的順序也需要考慮進去,可以說是非常仔細且嚴謹的。

     

    陸、OpenSBI作為函式庫使用

    OpenSBI 除了可以包裝成各種不同功能的韌體之外,也可以當作UEFI (Unified Extensible Firmware Interface) 的一環。EDK2(EDKII)是EFI的Development Kit,也就是EFI的開發環境,此開發環境把OpenSBI中的函式庫與LOADER連結在一起,讓擴充韌體可以完整使用OpenSBI中的所有函式庫,如libsbi.a、libsbiutils.a、libplatsbi.a等等。(OpenSBI Librery usage)

    目前RISC-V實作的範例是由HPE(Hewlett Packard Enterprise)主導的開源EDK2,並且整合OpenSBI,其專案在Github上開源。

    柒、結論

    OpenSBI 是SBI的實作,但只提供執行時程式的韌體與函式庫。

    得力於OpenSBI以開發平台為主的特性,可以容易的移植到新的SoC上。

    此外,OpenSBI所引用的韌體是非強制性的,任何晶片提供廠可以實作自己專屬的,同時也不會強制執行任何開機引導程序。

     

    #657
    johnson
    管理員
    @johnson

    關於”未對齊記憶體存取”的相關討論,可以參考RISC-V基金會中的google論壇討論:

    https://groups.google.com/a/groups.riscv.org/g/hw-dev/c/F8tWQ2A-vd0?pli=1

    文中提到,若有一個資料是12位元,對於4位元記憶體來說是有對齊的 (12%4 = 0)

    但對於8位元記憶體來說,是沒有對齊的。

    而任何位元對於單一位元記憶體來說都是有對齊的,因為任何數都整除1。

     

    #678
    johnson
    管理員
    @johnson
正在檢視 3 篇文章 - 1 至 3 (共計 3 篇)
  • 需要以回覆此篇主題...