› 論壇總覽 › BeagleV-beta RISC-V 開源單板電腦 › OpenSBI 程式碼概述
- This topic has 1 則回覆, 1 個參與人, and was last updated 3 years, 4 months ago by johnson.
-
作者文章
-
2021 年 6 月 24 日 下午 3:20 #672
閱讀過上一篇OpenSBI簡介與說明 後,想必讀者對於OpenSBI的瞭解又更進一步。
接下來我們就可以大膽的對OpenSBI的原始碼一探究竟。
在面對從來沒看過的程式碼,或者其他人撰寫的原始碼時,最重要的一定事先看README檔案,也就是程式的說明文件。
經過良好編排的文件檔案能夠讓使用者快速進入狀況,並且對於程式架構與實現方法描繪出基本輪廓。BeagleV openSBI 就是一個很好的例子,其中不僅包含簡介、所需工具鍊、建構指南還有補充資料。
但雖然如此,在面對一個新的專案時,我們也會不知道如何下手,從那裡去開始我們的程式碼,要從main開始呢? 還是從Include? 又或者從Library?
以我們BeagleV為例,因為它是一個嵌入式系統專案,我們知道所有程式碼在主機端撰寫、測試後,最後都要上傳到目標端(target),而任何程式最終產生的執行檔都匯至二進制檔案,這樣CPU才看得懂並加以執行。因此,我們可以先從Opensbi的build資料夾下手。
首先利用git clone將 https://github.com/starfive-tech/opensbi 整個專案下載到電腦,並照個它的指示建構出程式碼。
接著會發現opensbi下方多出一個build資料夾,這是opensbi的Make檔案做的事情,關於Make檔案的說明與介紹,可以參考
深入淺出GD32 RISC-V Nano/Pico – (四) MapleBoard 工具鏈範例使用教學
這裡它把所有基於硬體平台最後產生出的檔案放在這裡,由於我們使用的平台是starfive vic7100 SoC,可以從路徑 opensbi/build/platform/starfive/vic7100/firmware/中找到各種檔案,其中包含最終的fw_payoad.bin,
以及所需的fw_payload.elf, fw_payload.elf.ld
其中,先從fw_payload.dep開始,.dep檔案裡面記載建置過程中所需檔案的絕對路徑,透過這個路徑檔,我們可以找到檔案位置,再去追蹤檔案。下圖是筆者的fw_payload.dep內容,讀者實際的內容路徑會與筆者不同,因為這個.dep檔是opensbi在編譯過程中自動產生的檔案之一。
接下來下一個檔案是fw_payload.elf.ld,裡面是紀錄程式碼,資料,變數等等要放的記憶體位置,其檔案架構可以參考elf file formate的wiki說明。
接下來,編譯器會將elf檔案轉換成obj file,最後變成bin file用到的指令是objcopy。
objcopy在opensbi主資料夾下的Makefile被調用,位於第348行處。
有了這些資訊,我們可以追蹤出主程式碼的Entry point以及所需的函式庫,以及建構要求等等。在這裡有一些 Trace Tip可以參考:
1. 使用less瀏覽: q退出 /搜尋 G前往文底部 g前往文件起始 120往後120行
2. 使用vi瀏覽: :q退出 :q!不存檔退出 120前往第120行 G前往文件底部 gg前往文件起始 /搜尋3. 使用grep搜尋:<pre> $grep -nr “^_start” </pre> 使用遞迴搜每個檔案中含有以”_start”為首的單詞
想要概觀整個專案資料夾的內容,可以使用tree指令來將資料夾劃出樹狀圖:
johnson@debian:~/opensbi$ tree -d . ├── build │ ├── lib │ │ ├── sbi │ │ └── utils │ │ ├── fdt │ │ ├── ipi │ │ ├── irqchip │ │ ├── libfdt │ │ ├── reset │ │ ├── serial │ │ ├── sys │ │ └── timer │ └── platform │ └── starfive │ └── vic7100 │ ├── firmware │ │ └── payloads │ └── lib ├── docs │ ├── external │ ├── firmware │ └── platform ├── firmware │ └── payloads ├── include │ ├── sbi │ └── sbi_utils │ ├── fdt │ ├── ipi │ ├── irqchip │ ├── reset │ ├── serial │ ├── sys │ └── timer ├── lib │ ├── sbi │ └── utils │ ├── fdt │ ├── ipi │ ├── irqchip │ ├── libfdt │ ├── reset │ ├── serial │ ├── sys │ └── timer ├── platform │ ├── andes │ │ └── ae350 │ ├── fpga │ │ ├── ariane │ │ └── openpiton │ ├── generic │ │ └── include │ ├── kendryte │ │ └── k210 │ ├── nuclei │ │ └── ux600 │ ├── sifive │ │ └── fu540 │ ├── starfive │ │ └── vic7100 │ ├── template │ └── thead │ └── c910 └── scripts 65 directories
在這張圖表中,我們可以看到OpenSBI最主要有build, docs, firmware, include, lib, platform以及最後的sctipt資料夾,以下會介紹各個資料夾內容以及用途。
- build: 此為建構結果資料夾,建構好的二進制程式碼會存放於此
- docs: 為文件資料夾存放關於此專案的說明以及一些設定參數說明
- firmware: 存放不同型態的韌體程式碼,包含組合語言以及動態連結檔
- include: 存放引用的程式標頭檔資料夾,包含sbi基本指令以及sbi的工具程式如平坦裝置樹(flat device tree),計時器(timer)等等。
- lib: 此處為函式庫資料夾,裡面的程式會引用include資料夾中的標頭檔,實現程式功能。
- platform: 本資料夾存放不同供應商所製造之硬體平台對應的程式碼,如晶心科技Andes,Sifive,或通用的generic 資料夾。
- scripts: 存放一些小腳本供測試使用。
我們的BeagleV beta 使用starfive vic7100 晶片,我們可以從opensbi/platform/starfive/vic7100/資料夾中看到關於這個平台的一些設定檔案。
本資料夾包含config.mk, objects.mk 以及 platform.c- config.mk:
這個檔案包含makefile中使用到的變數定義,如同C語言中的標頭檔(.h)相似,在本文件中定義了編譯器會用到的設定,如platform-cpp-flags-y, platform-cflags-y等,以及先前OpenSBI的三種韌體型態 FW_PAYLOAD, FW_JUMP, 以及FU_DYNAMIC的相關參數會在此檔案定義。 - objects.mk
這個檔案只有一行程式碼: platform-objs-y += platform.o
意思是把platform-objs-y這個變數多加入platform.o這個字串。
platform-objs-y 這個變數在opensbi的主要Makefile中,儲存編譯過程中會用的obj檔案(.o檔),可以參考opemsbi/Makefile第134行的程式碼,這裡開發者把libsbi-objs-path-y這個變數加入obj變數、platform-objs-y變數、以及platform-build-dir變數。 - platform.c
這個檔案就是vic7100平台的opensbi程式碼,可以看到一開始的地方引入sbi的基本標頭檔,包含libfdt.h(flat device tree library), sbi/riscv_asm.h, sbi_riscv_io.h等等,檔案名稱中_riscv代表是針對RISC-V架構所適用的opensbi程式庫,當然還有另外通用的小程式工具如sbi_utils/irqchip.h, sbu_utils/serial/uart8250.h等等。
以上就是OpenSBI在BeagleV的原始碼解析,礙於筆者能力有限,沒有辦法細部介紹OpenSBI從)開始的運作過程,還請各位讀者見諒。
2021 年 6 月 27 日 下午 9:52 #677關於OpenSBI的規格文件,可以參考https://github.com/riscv/riscv-sbi-doc/blob/master/riscv-sbi.adoc
有更詳細的說明唷
-
作者文章
- 需要以回覆此篇主題...