RVOS-1.環境搭建與系統引導

0.環境搭建

riscv-operating-system-mooc: 開放課程《循序漸進,學習開發一個 RISC-V 上的操作系統》配套教材代碼倉庫。 mirror to https://github.com/plctlab/riscv-operating-system-mooc

在 Ubuntu 20.04 以上環境下我們可以直接使用官方提供的 GNU工具鏈和 QEMU 模擬器,執行如下命令在線安裝即可開始試驗:

$ sudo apt update
$ sudo apt install build-essential gcc make perl dkms git gcc-riscv64-unknown-elf gdb-multiarch qemu-system-misc

構建和使用說明:

- `make`:編譯構建
- `make run`:啟動 `qemu` 并運行
- `make debug`:啟動調試
- `make code`:反匯編查看二進制代碼
- `make clean`:清理

1. 系統引導

1.1 引導程序入口

硬件地址映射:

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

系統引導過程:

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

內核被加載到DRAM的地址 0x8000-0000,引導加載程序被加載到ROM的地址 0x0000-F0000x0000-0000

正常是固化在ROM的程序來引導,找到bootloader程序(BL0階段)。但這里我們使用模擬器QEMU,在makefile里面指定了內核程序入口:在啟動過程中,內核的入口點通常是位于ELF文件中的一個特定位置,這個位置由鏈接器腳本或者鏈接選項指定。在Makefile中,鏈接選項 -Ttext=0x80000000 指定了內核的文本段(代碼段)應該被加載到內存地址 0x80000000 處。這意味著當QEMU啟動時,它會將內核的代碼和數據加載到這個地址,并且從這個地址開始執行。

總而言之:run 目標使用QEMU模擬器運行內核,運行的確實是內核os.elf,并且在ELF文件里面的0x80000000地方開始運行。

但是我們還是分析一下這段匯編

auipc t0, 0x0
addi a2, t0, 40 	#可能是棧
csrr a0, mhartid	#將硬件線程ID寫入寄存器 a0。
lw a1, 32(t0)		#參數
lw t0, 24(t0)		#內核的入口地址存放處
jr t0				#jr t0:跳轉到寄存器 t0 指向的地址,即內核的入口地址。
start: .word

沒看明白,求大佬指點!

1.2 引導程序

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

這里類似于bootloader的 BL1階段:

BL1階段通常負責:

  • 初始化CPU和基本的硬件設備。
  • 設置棧指針。
  • 跳轉到下一個階段的bootloader(如BL2)或直接跳轉到操作系統。

start.S:

#include "platform.h"# size of each hart's stack is 1024 bytes# 用于分配一段內存空間 “External Public Uninitialized Block".equ 	STACK_SIZE, 1024.global _start.text
_start:# park harts with id != 0讓除了0號核的其他核都進入park狀態csrr t0, mhartid 		# read current hart idmv  tp,t0				# save current hart id to tpbnez t0,park 			# if hart id != 0, park# Setup stacks, the stack grows from bottom to top, so we put the# stack pointer to the very end of the stack range.slli	t0, t0, 10		# shift left the hart id by 1024-->(for multiple harts)la	sp, stacks + STACK_SIZE	# set the initial stack pointer# to the end of the first stack spaceadd	sp, sp, t0			# move the current hart stack pointer# to its place in the stack spacej	start_kernel		# hart 0 jump to cpark:wfij park# In the standard RISC-V calling convention, the stack pointer sp# is always 16-byte aligned.
.balign 16
stacks:.skip	STACK_SIZE * MAXNUM_CPU # allocate space for all the harts stacks.end				# End of file

kernel.c

void start_kernel(void)
{while (1) {}; // stop here!
}

platform.h

#ifndef __PLATFORM_H
#define __PLATFORM_H#define MAXNUM_CPU 8#endif // __PLATFORM_H

運行結果:成功進入void start_kernel(void);
在這里插入圖片描述疑問:這些文件怎么組織在一起的?

文件之間的聯系是通過鏈接器來建立的。鏈接器(Linker)是編譯過程中的一個工具,它將編譯后的目標文件(Object Files,通常是 .o 文件)和庫文件鏈接在一起,生成一個可執行文件(Executable File)或庫文件(Library File)

在此項目中,鏈接過程是通過 Makefile 控制的。Makefile 中定義了如何編譯和鏈接項目:

  1. OBJS_ASM 和 OBJS_C:這些變量定義了匯編和 C 語言的目標文件(Object Files)。

  2. ELF 和 BINELF 是鏈接后的可執行文件,BIN 是可執行文件的二進制格式。

  3. LDFLAGS:鏈接器標志,用于指定鏈接器的行為。在您的 Makefile 中,LDFLAGS 可以是 -T ${OUTPUT_PATH}/os.ld.generated(使用鏈接腳本)或 -Ttext=0x80000000(指定文本段的起始地址)。

  4. 鏈接命令

    ${ELF}: ${OBJS}ifeq (${USE_LINKER_SCRIPT}, true)${CC} -E -P -x c ${DEFS} ${CFLAGS} os.ld > ${OUTPUT_PATH}/os.ld.generatedendif${CC} ${CFLAGS} ${LDFLAGS} -o ${ELF} $^${OBJCOPY} -O binary ${ELF} ${BIN}
    

    這段代碼首先檢查是否使用鏈接腳本,如果是,則生成鏈接腳本文件。然后使用 CC(交叉編譯器)和 LDFLAGS 鏈接目標文件,生成 ELF 文件。最后,使用 OBJCOPY 將 ELF 文件轉換為二進制格式。

  5. 默認目標

    .DEFAULT_GOAL := all
    all: ${OUTPUT_PATH} ${ELF}
    

    默認目標是 all,它依賴于 OUTPUT_PATHELF 文件。

通過這些步驟,Makefile 確保了所有源文件被正確編譯和鏈接,生成最終的可執行文件。鏈接器根據鏈接腳本(如果使用)或鏈接器標志來確定如何將各個目標文件和庫文件組合在一起。

參考—汪老師講的太好了!!!!:

1.3 RISC-V寄存器_RISC-V體系結構編程與實踐(第2版)

【[完結] 循序漸進,學習開發一個RISC-V上的操作系統 - 汪辰 - 2021春】 https://www.bilibili.com/video/BV1Q5411w7z5/?p=19&share_source=copy_web&vd_source=d63943fdb26087d14a536adf35c52d6b

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/76069.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/76069.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/76069.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

UNet 改進(5):結合SE模塊提升圖像分割性能

U-Net是醫學圖像分割領域最成功的架構之一,其對稱的編碼器-解碼器結構和跳躍連接使其能夠有效捕捉多尺度特征。本文將解析一個改進版的U-Net實現,該版本通過引入Squeeze-and-Excitation(SE)模塊進一步提升了模型性能。 一、架構概覽 這個改進的U-Net保持…

機器人擰螺絲緊固裝配(Robot screw fastening assembly)

機器人擰螺絲緊固裝配技術正以其高精度、高效率和高靈活性,重塑著傳統制造業的生產范式。這項融合了機械臂定位、扭矩控制、視覺引導與數據分析的自動化解決方案,不僅將工人從重復性高強度勞動中解放出來,更通過實時數據反饋與精準執行&#…

圖像處理中的 Gaussina Blur 和 SIFT 算法

Gaussina Blur 高斯模糊 高斯模糊的數學定義 高斯模糊是通過 高斯核(Gaussian Kernel) 對圖像進行卷積操作實現的. 二維高斯函數定義為 G ( x , y , σ ) 1 2 π σ 2 e ? x 2 y 2 2 σ 2 G(x, y, \sigma) \frac{1}{2\pi \sigma^2} e^{-\frac{x^2 y^2}{2\sigma^2}} G(x…

在Unity中實現《幽靈行者》風格的跑酷動作

基礎設置 角色控制器選擇: 使用Character Controller組件或Rigidbody Capsule Collider 推薦使用Character Controller以獲得更精確的運動控制 輸入系統: 使用Unity的新輸入系統(Input System Package)處理玩家輸入 滑鏟實現 public class Slide…

青蛙吃蟲--dp

1.dp數組有關元素--路長和次數 2.遞推公式 3.遍歷順序--最終影響的是路長&#xff0c;在外面 其次次數遍歷&#xff0c;即這次路長所有情況都更新 最后&#xff0c;遍歷次數自然就要遍歷跳長 4.max時時更新 dp版本 #include<bits/stdc.h> using namespace std; #def…

Tiktok 關鍵字 視頻及評論信息爬蟲(2) [2025.04.07]

&#x1f64b;?♀?Tiktok APP的基于關鍵字檢索的視頻及評論信息爬蟲共分為兩期&#xff0c;希望對大家有所幫助。 第一期&#xff1a;基于關鍵字檢索的視頻信息爬取 第二期見下文。 1.Node.js環境配置 首先配置 JavaScript 運行環境&#xff08;如 Node.js&#xff09;&…

Matlab繪圖—‘‘錯誤使用 plot輸入參數的數目不足‘‘

原因1&#xff1a; ?? 文件列名不是合法變量名 在excel中數據列名稱為Sample:float,將:刪除就解決了

Kotlin問題匯總

Kotlin問題匯總 真機安裝調試 查看真機的Android版本&#xff0c;將build.gradle文件中的minSdk改為手機的Android版本&#xff0c;點Sync Now更新設置 apk安裝失敗 在gradle.properties全局配置中設置android.injected.testOnlyfalse Unresolved reference: 在activity_…

基于VMware的Cent OS Stream 8安裝與配置及遠程連接軟件的介紹

1.VMware Workstation 簡介&#xff1a; VMware Workstation&#xff08;中文名“威睿工作站”&#xff09;是一款功能強大的桌面虛擬計算機軟件&#xff0c;提供用戶可在單一的桌面上同時運行不同的操作系統&#xff0c;和進行開發、測試 、部署新的應用程序的最佳解決方案。…

Go語言從零構建SQL數據庫(4)-解析器

SQL解析器&#xff1a;數據庫的"翻譯官"圖解與代碼詳解 圖解SQL解析過程 SQL解析器就像是人類語言與計算機之間的翻譯官&#xff0c;將我們書寫的SQL語句轉換成數據庫能夠理解和執行的結構。 #mermaid-svg-f9gAqHutDLL4McGy {font-family:"trebuchet ms"…

十道海量數據處理面試題與十個方法總結

一、十道海量數據處理面試題 ??1、海量日志數據&#xff0c;提取出某日訪問百度次數最多的那個IP。(分治思想 哈希表) 首先&#xff0c;從日志中提取出所有訪問百度的IP地址&#xff0c;將它們逐個寫入一個大文件中&#xff0c;便于后續處理。 考慮到IP地址是32位的&#…

SolidWorks2025三維計算機輔助設計(3D CAD)軟件超詳細圖文安裝教程(2025最新版保姆級教程)

目錄 前言 一、SolidWorks下載 二、SolidWorks安裝 三、啟動SolidWorks 前言 SolidWorks 是一款由法國達索系統&#xff08;Dassault Systmes&#xff09;公司開發的三維計算機輔助設計&#xff08;3D CAD&#xff09;軟件&#xff0c;廣泛用于機械設計、工程仿真和產品開…

IntelliJ IDEA 2020~2024 創建SpringBoot項目編輯報錯: 程序包org.springframework.boot不存在

目錄 前奏解決結尾 前奏 哈&#xff01;今天在處理我的SpringBoot項目時&#xff0c;突然遇到了一些讓人摸不著頭腦的錯誤提示&#xff1a; java: 程序包org.junit不存在 java: 程序包org.junit.runner不存在 java: 程序包org.springframework.boot.test.context不存在 java:…

CPU 壓力測試命令大全

CPU 壓力測試命令大全 以下是 Linux/Unix 系統下常用的 CPU 壓力測試命令和工具&#xff0c;可用于測試 CPU 性能、穩定性和散熱能力。 1. 基本壓力測試命令 1.1 使用 yes 命令 yes > /dev/null & # 啟動一個無限循環進程 yes > /dev/null & # 啟動第二個進…

#SVA語法滴水穿石# (003)關于 sequence 和 property 的區別和聯系

在 SystemVerilog Assertions (SVA) 中,sequence 和 property 是兩個核心概念,它們既有區別又緊密相關。對于初學者,可能不需要過多理解;但是要想寫出復雜精美的斷言,深刻理解兩者十分重要。今天,我們匯總和學習一下該知識點。 1. 區別 特性sequenceproperty定義描述一系…

WordPress浮動廣告插件+飄動效果客服插件

源碼介紹 WordPress浮動廣告插件飄動效果客服插件 將源碼上傳到wordpress的插件根目錄下&#xff0c;解壓&#xff0c;然后后臺啟用即可 截圖 源碼免費獲取 WordPress浮動廣告插件飄動效果客服插件

虛幻基礎:藍圖基礎知識

文章目錄 組件藍圖創建時&#xff0c;優先創建組件&#xff0c;如c一樣。 UI控件控件不會自動創建&#xff0c;而是在藍圖創建函數中手動創建。 函數內使用S序列接退出&#xff0c;并不會等所有執行完再退出&#xff0c;而是一個執行完后直接退出 組件 藍圖創建時&#xff0c;…

《AI大模型應知應會100篇》加餐篇:LlamaIndex 與 LangChain 的無縫集成

加餐篇&#xff1a;LlamaIndex 與 LangChain 的無縫集成 問題背景&#xff1a;在實際應用中&#xff0c;開發者常常需要結合多個框架的優勢。例如&#xff0c;使用 LangChain 管理復雜的業務邏輯鏈&#xff0c;同時利用 LlamaIndex 的高效索引和檢索能力構建知識庫。本文在基于…

深度學習項目--分組卷積與ResNext網絡實驗探究(pytorch復現)

&#x1f368; 本文為&#x1f517;365天深度學習訓練營 中的學習記錄博客&#x1f356; 原作者&#xff1a;K同學啊 前言 ResNext是分組卷積的開始之作&#xff0c;這里本文將學習ResNext網絡&#xff1b;本文復現了ResNext50神經網絡&#xff0c;并用其進行了猴痘病分類實驗…

從代碼學習深度學習 - RNN PyTorch版

文章目錄 前言一、數據預處理二、輔助訓練工具函數三、繪圖工具函數四、模型定義五、模型訓練與預測六、實例化模型并訓練訓練結果可視化總結前言 循環神經網絡(RNN)是深度學習中處理序列數據的重要模型,尤其在自然語言處理和時間序列分析中有著廣泛應用。本篇博客將通過一…