cropped-forum.png

論壇總覽 BeagleV-beta RISC-V 開源單板電腦 OpenSBI 程式碼概述

標籤: , , ,

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

      閱讀過上一篇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資料夾,以下會介紹各個資料夾內容以及用途。

      1. build: 此為建構結果資料夾,建構好的二進制程式碼會存放於此
      2. docs: 為文件資料夾存放關於此專案的說明以及一些設定參數說明
      3. firmware: 存放不同型態的韌體程式碼,包含組合語言以及動態連結檔
      4. include: 存放引用的程式標頭檔資料夾,包含sbi基本指令以及sbi的工具程式如平坦裝置樹(flat device tree),計時器(timer)等等。
      5. lib: 此處為函式庫資料夾,裡面的程式會引用include資料夾中的標頭檔,實現程式功能。
      6. platform: 本資料夾存放不同供應商所製造之硬體平台對應的程式碼,如晶心科技Andes,Sifive,或通用的generic 資料夾。
      7. scripts: 存放一些小腳本供測試使用。

      我們的BeagleV beta 使用starfive vic7100 晶片,我們可以從opensbi/platform/starfive/vic7100/資料夾中看到關於這個平台的一些設定檔案。
      本資料夾包含config.mk, objects.mk 以及 platform.c

      1. config.mk:
        這個檔案包含makefile中使用到的變數定義,如同C語言中的標頭檔(.h)相似,在本文件中定義了編譯器會用到的設定,如platform-cpp-flags-y, platform-cflags-y等,以及先前OpenSBI的三種韌體型態 FW_PAYLOAD, FW_JUMP, 以及FU_DYNAMIC的相關參數會在此檔案定義。
      2. 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變數。
      3. 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從)開始的運作過程,還請各位讀者見諒。

      #677
      johnson
      管理員
        @johnson

        關於OpenSBI的規格文件,可以參考https://github.com/riscv/riscv-sbi-doc/blob/master/riscv-sbi.adoc

        有更詳細的說明唷

      正在檢視 2 篇文章 - 1 至 2 (共計 2 篇)
      • 需要以回覆此篇主題...