cropped-forum.png

論壇總覽 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 篇)
        • 需要以回覆此篇主題...