RISC-V 體系結構編程與實踐
奔跑吧Linux社區
- 出版商: 人民郵電
- 出版日期: 2023-02-01
- 定價: $779
- 售價: 5.0 折 $390
- 語言: 簡體中文
- 頁數: 464
- ISBN: 711560360X
- ISBN-13: 9787115603609
-
相關分類:
RISC-V
-
其他版本:
RISC-V體系結構編程與實踐(第2版)
買這商品的人也買了...
-
$1,580$1,548 -
$2,800$2,660 -
$594$564 -
$505並行計算機組成與設計
-
$594$564 -
$708$673 -
$3,230Computer Organization and Design Risc-V Edition: The Hardware Software Interface, 2/e (Paperback)
-
$730SiFive 經典 RISC-V FE310 微控制器原理與實踐
-
$354$336 -
$534$507 -
$659$626 -
$279編譯原理及實現, 2/e
-
$319編譯技術原理及方法(慕課版)
-
$780$616 -
$474$450 -
$780$616 -
$980$774 -
$414$393 -
$523移動終端安全架構及關鍵技術
-
$356只是為了好玩:Linux 之父林納斯自傳 (修訂版)
-
$659$626 -
$1,014$963 -
$780$616 -
$454RISC-V 開放架構設計之道
-
$374開源 RISC-V 處理器架構分析與驗證
相關主題
商品描述
本書旨在介紹RISC-V體系結構的設計和實現。本書首先介紹RISC-V體系結構的基礎知識、實驗環境搭建、常用指令、函數調用規範與棧,然後講述GNU匯編器、鏈接器、鏈接腳本和GCC內嵌匯編代碼,接著討論RISC-V體系結構中的異常處理、中斷、內存管理、高速緩存、緩存一致性、TLB管理、原子操作、內存屏障指令,最後闡述RSIC-V體系結構中的壓縮指令擴展、虛擬化擴展等。
本書不僅適合軟件開發人員閱讀,還可以作為電腦相關專業和相關培訓機構的教材。
作者簡介
作者简介
奔跑吧Linux社区 由一群热爱开源的工程师组成,致力于开源硬件和开源软件的推广。
审校者简介
香山处理器团队
面向世界的体系结构创新开源平台,目前已形成由多家企业组成的香山联合开发团队。其中,香山处理器是由中国科学院计算技术研究所发起的开源高性能RISC-V处理器核项目。
龙蜥社区RISC-V SIG
坚持开放、开源,致力于龙蜥社区以及 RISCV 软硬件生态的共建和推广。
进迭时空
专注研发新一代高性能RISC-V处理器和计算系统,让开发者基于RISC-V芯片更自由地开发更有创意的新应用。
目錄大綱
目 錄
第 1章 RISC-V體系結構基礎知識 1
1.1 RISC-V介紹 1
1.1.1 RISC-V指令集優點 1
1.1.2 RISC-V指令集擴展 2
1.1.3 RISC-V商業化發展 2
1.2 RISC-V體系結構介紹 3
1.2.1 RISC-V體系結構 3
1.2.2 採用RISC-V體系結構的常見處理器 3
1.2.3 RISC-V體系結構中的基本概念 4
1.2.4 SBI服務 5
1.3 RISC-V寄存器 6
1.3.1 通用寄存器 6
1.3.2 系統寄存器 7
1.3.3 U模式下的系統寄存器 8
1.3.4 S模式下的系統寄存器 9
1.3.5 M模式下的系統寄存器 11
1.4 香山處理器介紹 15
1.4.1 香山處理器體系結構 15
1.4.2 香山處理器的前端子系統 16
1.4.3 香山處理器的後端子系統 18
1.4.4 香山處理器的訪存子系統 20
1.4.5 香山處理器的L2/L3高速緩存 25
第 2章 搭建RISC-V實驗環境 29
2.1 實驗平臺 29
2.1.1 QEMU 29
2.1.2 NEMU 30
2.2 搭建實驗環境 31
2.2.1 實驗2-1:輸出“Welcome RISC-V!” 31
2.2.2 實驗2-2:單步調試BenOS和MySBI 32
2.3 BenOS和MySBI基礎實驗代碼解析 34
2.3.1 MySBI基礎代碼分析 34
2.3.2 BenOS基礎代碼分析 37
2.3.3 合並BenOS和MySBI 41
2.4 QEMU + RISC-V + Linux實驗平臺 41
第3章 基礎指令集 44
3.1 RISC-V指令集介紹 44
3.2 RISC-V指令編碼格式 45
3.3 加載與存儲指令 46
3.4 PC相對尋址 49
3.5 移位操作 53
3.6 位操作指令 55
3.7 算術指令 56
3.8 比較指令 57
3.9 無條件跳轉指令 58
3.10 條件跳轉指令 59
3.11 CSR指令 61
3.12 尋址範圍 62
3.13 陷阱:為什麽ret之後就進入死循環 62
3.14 實驗 64
3.14.1 實驗3-1:熟悉加載指令 64
3.14.2 實驗3-2:PC相對地址尋址 64
3.14.3 實驗3-3:memcpy()函數的實現 65
3.14.4 實驗3-4:memset()函數的實現 65
3.14.5 實驗3-5:條件跳轉指令1 65
3.14.6 實驗3-6:條件跳轉指令2 66
3.14.7 實驗3-7:子函數跳轉 66
3.14.8 實驗3-8:在匯編中實現串口輸出功能 66
第4章 函數調用規範與棧 67
4.1 函數調用規範 67
4.2 入棧與出棧 70
4.3 RISC-V棧的佈局 72
4.3.1 不使用FP的棧佈局 72
4.3.2 使用FP的棧佈局 74
4.3.3 棧回溯 76
4.4 實驗 78
4.4.1 實驗4-1:觀察棧佈局 78
4.4.2 實驗4-2:觀察棧回溯 78
第5章 GNU匯編器 79
5.1 編譯流程與ELF文件 79
5.2 一個簡單的匯編程序 82
5.3 匯編語法 84
5.3.1 註釋 84
5.3.2 符號 84
5.4 常用的偽指令 85
5.4.1 對齊偽指令 85
5.4.2 數據定義偽指令 86
5.4.3 與函數相關的偽指令 87
5.4.4 與段相關的偽指令 87
5.4.5 與宏相關的偽指令 89
5.4.6 與文件相關的偽指令 91
5.5 RISC-V依賴特性 91
5.5.1 RISC-V特有的命令行選項 91
5.5.2 RISC-V特有的偽指令 92
5.6 實驗 92
5.6.1 實驗5-1:匯編語言練習—查找最大數 92
5.6.2 實驗5-2:匯編語言練習—通過C語言調用匯編函數 92
5.6.3 實驗5-3:匯編語言練習—通過匯編語言調用C函數 92
5.6.4 實驗5-4:使用匯編偽操作實現一張表 92
5.6.5 實驗5-5:匯編宏的使用 93
第6章 鏈接器與鏈接腳本 94
6.1 鏈接器 94
6.2 鏈接腳本 95
6.2.1 一個簡單的鏈接程序 95
6.2.2 設置入口點 96
6.2.3 基本概念 97
6.2.4 符號賦值與引用 97
6.2.5 當前位置計數器 98
6.2.6 SECTIONS命令 99
6.2.7 常用的內置函數 101
6.3 加載重定位 103
6.3.1 BenOS重定位 103
6.3.2 OpenSBI和Linux內核重定位 105
6.4 鏈接重定位與鏈接器鬆弛優化 108
6.4.1 鏈接重定位 108
6.4.2 函數跳轉優化 112
6.4.3 符號地址訪問優化 114
6.5 實驗 116
6.5.1 實驗6-1:分析鏈接腳本 116
6.5.2 實驗6-2:輸出每個段的內存佈局 116
6.5.3 實驗6-3:加載地址不等於運行地址 117
6.5.4 實驗6-4:設置鏈接地址 117
6.5.5 實驗6-5:鏈接器鬆弛優化1 117
6.5.6 實驗6-6:鏈接器鬆弛優化2 117
6.5.7 實驗6-7:分析Linux 5.15內核的鏈接腳本 117
第7章 內嵌匯編代碼 118
7.1 內嵌匯編代碼基本用法 118
7.1.1 基礎內嵌匯編代碼 118
7.1.2 擴展內嵌匯編代碼 118
7.1.3 內嵌匯編代碼修飾符 120
7.1.4 使用匯編符號名字 121
7.1.5 內嵌匯編代碼與宏結合 122
7.1.6 使用goto修飾詞 122
7.1.7 小結 123
7.2 案例分析 124
7.3 註意事項 128
7.4 實驗 128
7.4.1 實驗7-1:實現簡單的memcpy()函數 128
7.4.2 實驗7-2:使用匯編符號名寫內嵌匯編代碼 128
7.4.3 實驗7-3:使用內嵌匯編代碼完善memset()函數 129
7.4.4 實驗7-4:使用內嵌匯編代碼與宏的結合 129
7.4.5 實驗7-5:實現讀和寫系統寄存器的宏 129
7.4.6 實驗7-6:goto模板的內嵌匯編代碼 129
第8章 異常處理 130
8.1 異常處理基本概念 130
8.1.1 異常類型 130
8.1.2 同步異常和異步異常 131
8.1.3 異常入口和返回 131
8.1.4 異常返回地址 132
8.1.5 異常返回的處理器模式 133
8.1.6 棧的選擇 133
8.2 與M模式相關的異常寄存器 133
8.2.1 mstatus寄存器 134
8.2.2 mtvec寄存器 134
8.2.3 mcause寄存器 135
8.2.4 mie寄存器 135
8.2.5 mtval寄存器 136
8.2.6 mip寄存器 136
8.2.7 mideleg和medeleg寄存器 136
8.2.8 中斷配置 137
8.3 與S模式相關的異常寄存器 137
8.3.1 sstatus寄存器 137
8.3.2 sie寄存器 137
8.3.3 sip寄存器 138
8.3.4 scause寄存器 138
8.3.5 stvec寄存器 138
8.3.6 stval寄存器 139
8.4 異常上下文 139
8.4.1 保存異常上下文 141
8.4.2 恢復異常上下文 141
8.5 案例分析8-1:實現SBI系統調用 142
8.5.1 調用ECALL指令 142
8.5.2 實現SBI系統調用 143
8.6 案例分析8-2:BenOS的異常處理 148
8.6.1 設置異常向量表 148
8.6.2 保存和恢復異常上下文 149
8.6.3 異常處理 151
8.6.4 委托中斷和異常 153
8.6.5 觸發異常 153
8.7 實驗 154
8.7.1 實驗8-1:在SBI中實現串口輸入功能 154
8.7.2 實驗8-2:在BenOS中觸發非法指令異常 155
8.7.3 實驗8-3:輸出觸發異常時函數棧的調用過程 155
8.7.4 實驗8-4:在MySBI中模擬實現RDTIME偽指令 155
第9章 中斷處理與中斷控制器 156
9.1 中斷處理基本概念 156
9.1.1 中斷類型 156
9.1.2 中斷處理過程 157
9.1.3 中斷委派和註入 158
9.1.4 中斷優先級 158
9.2 CLINT 159
9.3 案例分析9-1:定時器中斷 160
9.3.1 訪問mtimer 160
9.3.2 在MySBI中實現定時器服務 160
9.3.3 定時器中斷處理 161
9.3.4 打開中斷總開關 163
9.3.5 小結 164
9.4 PLIC 164
9.4.1 中斷號 165
9.4.2 中斷優先級 166
9.4.3 中斷使能寄存器 166
9.4.4 中斷待定寄存器 166
9.4.5 中斷優先級閾值寄存器 167
9.4.6 中斷請求/完成寄存器 167
9.5 案例分析9-2:串口中斷 167
9.5.1 初始化PLIC 168
9.5.2 使能串口0的接收中斷 169
9.5.3 處理中斷 169
9.6 實驗 171
9.6.1 實驗9-1:定時器中斷 171
9.6.2 實驗9-2:使用匯編函數保存和恢復中斷現場 171
9.6.3 實驗9-3:實現並調試串口0中斷 171
第 10章 內存管理 172
10.1 內存管理基礎知識 172
10.1.1 內存管理的“遠古時代” 172
10.1.2 地址空間的抽象 174
10.1.3 分段機制 175
10.1.4 分頁機制 175
10.2 RISC-V內存管理 178
10.2.1 頁表分類 179
10.2.2 Sv39頁表映射 180
10.2.3 Sv48頁表映射 182
10.2.4 頁表項描述符 183
10.2.5 頁表屬性 185
10.2.6 與地址轉換相關的寄存器 186
10.3 物理內存屬性與物理內存保護 187
10.3.1 物理內存屬性 187
10.3.2 物理內存保護 188
10.4 案例分析10-1:在BenOS里實現恆等映射 190
10.4.1 頁表定義 191
10.4.2 頁表數據結構 193
10.4.3 創建頁表 193
10.4.4 打開MMU 198
10.4.5 測試MMU 198
10.4.6 圖解頁表創建的過程 200
10.5 內存管理實驗 204
10.5.1 實驗10-1:建立恆等映射 204
10.5.2 實驗10-2:為什麽MMU無法運行 205
10.5.3 實驗10-3:實現一個MMU頁表的轉儲功能 205
10.5.4 實驗10-4:修改頁面屬性 205
10.5.5 實驗10-5:使用匯編語言來建立恆等映射 206
10.5.6 實驗10-6:在MySBI中實現和驗證PMP機制 206
第 11章 高速緩存 207
11.1 為什麽需要高速緩存 207
11.2 高速緩存的訪問延時 208
11.3 高速緩存的工作原理 210
11.4 高速緩存的映射方式 212
11.4.1 直接映射 212
11.4.2 全相聯映射 213
11.4.3 組相聯映射 213
11.4.4 組相聯的高速緩存的例子 214
11.5 虛擬高速緩存與物理高速緩存 215
11.5.1 物理高速緩存 215
11.5.2 虛擬高速緩存 215
11.5.3 VIPT和PIPT 215
11.6 重名和同名問題 216
11.6.1 重名問題 217
11.6.2 同名問題 217
11.6.3 VIPT產生的重名問題 218
11.7 高速緩存策略 220
11.8 高速緩存的維護指令 221
11.8.1 高速緩存管理指令 221
11.8.2 高速緩存預取指令 222
第 12章 緩存一致性 224
12.1 為什麽需要緩存一致性 224
12.2 緩存一致性的分類 225
12.2.1 緩存一致性協議發展歷程 225
12.2.2 緩存一致性分類 226
12.2.3 系統緩存一致性問題 227
12.3 緩存一致性的解決方案 227
12.3.1 關閉高速緩存 228
12.3.2 使用軟件維護緩存一致性 228
12.3.3 使用硬件維護緩存一致性 228
12.4 MESI協議 228
12.4.1 MESI協議簡介 229
12.4.2 本地讀寫與總線操作 230
12.4.3 MESI狀態轉換 230
12.4.4 初始狀態為I 231
12.4.5 初始狀態為M 233
12.4.6 初始狀態為S 234
12.4.7 初始狀態為E 234
12.4.8 小結與案例分析 235
12.4.9 MOESI協議 237
12.5 高速緩存偽共享 237
12.6 兩種緩存一致性控制器 239
12.6.1 CCI緩存一致性控制器 239
12.6.2 CCN緩存一致性控制器 240
12.7 案例分析12-1:偽共享的避免 241
12.8 案例分析12-2:DMA和高速緩存的一致性 242
12.8.1 從內存到設備的FIFO緩沖區 243
12.8.2 從設備的FIFO緩沖區到內存 243
12.9 案例分析12-3:自修改代碼的一致性 244
12.10 實驗 245
12.10.1 實驗12-1:高速緩存偽共享 245
12.10.2 實驗12-2:使用Perf C2C發現高速緩存偽共享 245
第 13章 TLB管理 246
13.1 TLB基礎知識 247
13.2 TLB重名與同名問題 249
13.2.1 重名問題 249
13.2.2 同名問題 250
13.3 ASID 251
13.4 TLB管理指令 253
13.4.1 TLB維護指令介紹 253
13.4.2 TLB廣播 254
13.4.3 SFENCE.VMA指令使用場景 256
13.5 TLB案例分析 256
13.5.1 TLB在Linux內核中的應用 256
13.5.2 ASID在Linux內核中的應用 257
13.5.3 Linux內核中的TLB維護操作 257
13.5.4 BBM機制 259
第 14章 原子操作 261
14.1 原子操作介紹 261
14.2 保留加載與條件存儲指令 262
14.3 獨占內存訪問工作原理 263
14.3.1 獨占監視器 264
14.3.2 獨占監視器與緩存一致性 265
14.4 原子內存訪問操作指令 266
14.4.1 原子內存訪問指令工作原理 266
14.4.2 原子內存訪問指令與LR/SC指令的效率對比 267
14.4.3 RISC-V中的原子內存訪問指令 268
14.5 比較並交換操作 270
第 15章 內存屏障指令 275
15.1 內存屏障指令產生的原因 275
15.1.1 順序一致性內存模型 276
15.1.2 處理器一致性內存模型 277
15.1.3 弱一致性內存模型 277
15.1.4 釋放一致性內存模型 278
15.1.5 MCA模型 279
15.2 RISC-V約束條件 280
15.2.1 全局內存次序與保留程序次序 280
15.2.2 RVWMO的約束規則 281
15.3 RISC-V中的內存屏障指令 284
15.3.1 使用內存屏障的場景 284
15.3.2 FENCE指令 285
15.3.3 內置獲取和釋放屏障原語的指令 285
15.3.4 FENCE.I指令 286
15.3.5 SFENCE.VMA指令 286
15.4 RISC-V內存屏障指令移植指南 286
15.4.1 從RISC-V到x86體系結構 286
15.4.2 從RISC-V到ARM體系結構 287
15.4.3 Linux內核常用的內存屏障API函數 287
15.5 案例分析 288
15.5.1 消息傳遞問題 288
15.5.2 單方向內存屏障與自旋鎖 289
15.5.3 郵箱傳遞消息 290
15.5.4 關於DMA的案例 291
15.5.5 在Linux內核中使指令高速緩存失效 291
15.6 模擬和測試內存屏障故障 291
15.6.1 使用Litmus測試工具集 292
15.6.2 編寫C程序來模擬 295
15.7 實驗 297
15.7.1 實驗15-1:編寫Litmus腳本並測試內存一致性1 297
15.7.2 實驗15-2:編寫Litmus腳本並測試內存一致性2 298
第 16章 合理使用內存屏障指令 299
16.1 存儲緩沖區與寫內存屏障指令 300
16.2 無效隊列與讀內存屏障指令 305
16.3 內存屏障指令總結 307
16.4 案例分析:Linux內核中的內存屏障指令 308
16.4.1 第 一次使用內存屏障指令 309
16.4.2 第二次使用內存屏障指令 310
16.4.3 第三次使用內存屏障指令 313
16.4.4 第四次使用內存屏障指令 314
16.4.5 小結:內存屏障指令的使用 315
16.5 實驗 315
16.5.1 實驗16-1:驗證和測試內存一致性1 315
16.5.2 實驗16-2:驗證和測試內存一致性2 315
16.5.3 實驗16-3:驗證和測試內存一致性3 315
第 17章 與操作系統相關的內容 316
17.1 C語言常見陷阱 317
17.1.1 數據模型 317
17.1.2 數據類型轉換與整型提升 318
17.1.3 移位操作 320
17.2 創建進程 320
17.2.1 進程控制塊 320
17.2.2 0號進程 321
17.2.3 do_fork()函數的實現 323
17.2.4 進程上下文切換 324
17.2.5 新進程的第 一次執行 326
17.3 簡易進程調度器 327
17.3.1 擴展進程控制塊 327
17.3.2 就緒隊列 327
17.3.3 調度類 328
17.3.4 簡易調度器的實現 329
17.3.5 自願調度 330
17.3.6 搶占調度 331
17.3.7 測試用例 333
17.3.8 關於調度的思考 333
17.4 讓進程運行在用戶模式 335
17.5 系統調用 338
17.5.1 系統調用介紹 338
17.5.2 在用戶模式下調用SVC指令 338
17.5.3 在內核模式下對系統調用的處理 339
17.5.4 系統調用表 340
17.6 實現clone系統調用 341
17.7 實驗 343
17.7.1 實驗17-1:進程創建 343
17.7.2 實驗17-2:進程調度 343
17.7.3 實驗17-3:讓進程運行在用戶模式 343
17.7.4 實驗17-4:新增一個malloc()系統調用 343
17.7.5 實驗17-5:新增一個clone()系統調用 344
第 18章 可伸縮矢量計算與優化 345
18.1 矢量計算基本概念 345
18.1.1 SISD與SIMD 345
18.1.2 定長計算與可變長矢量計算 347
18.1.3 通道 347
18.1.4 矢量與標量 347
18.2 RVV寄存器 348
18.2.1 矢量寄存器 348
18.2.2 mstatus寄存器中的矢量上下文狀態 348
18.2.3 vtype寄存器 348
18.2.4 vl寄存器 350
18.2.5 vlenb寄存器 351
18.2.6 vstart寄存器 351
18.3 配置編譯和運行環境 351
18.3.1 搭建編譯環境 351
18.3.2 運行第 一個“hello RVV!”程序 352
18.3.3 單步調試匯編程序 353
18.3.4 單步調試C語言與匯編混合程序 355
18.4 RVV指令格式 357
18.5 配置指令 358
18.6 加載和存儲指令 360
18.6.1 單位步長模式 360
18.6.2 任意步長模式 363
18.6.3 聚合加載/離散存儲 364
18.6.4 打包數據的加載與存儲 365
18.6.5 首次異常加載指令 367
18.6.6 加載和存儲全部矢量數據 368
18.7 矢量掩碼指令 369
18.7.1 邏輯操作指令 369
18.7.2 VCPOP.M指令 369
18.7.3 VFIRST.M指令 370
18.7.4 VMSBF.M指令 370
18.7.5 VMSIF.M指令 371
18.7.6 VMSOF.M指令 372
18.8 矢量整型算術指令 372
18.8.1 加寬和變窄算術指令 372
18.8.2 加法和減法指令 373
18.8.3 加寬模式的加法和減法指令 374
18.8.4 位操作指令 376
18.8.5 移位操作指令 376
18.8.6 比較指令 376
18.8.7 數據搬移指令 377
18.9 案例分析18-1:使用RVV指令優化strcmp()函數 377
18.9.1 使用純匯編方式 378
18.9.2 測試 379
18.10 案例分析18-2:RGB24轉BGR24 380
18.10.1 使用C語言實現RGB24轉BGR24 380
18.10.2 使用RVV指令優化 380
18.10.3 測試 381
18.11 案例分析18-3:4 × 4矩陣乘法運算 382
18.11.1 使用C語言實現4 × 4矩陣乘法運算 382
18.11.2 使用RVV指令優化 383
18.11.3 測試 387
18.12 案例分析18-4:使用RVV內置函數 388
18.13 案例分析18-5:自動矢量優化 388
18.14 術語 390
18.15 實驗 391
18.15.1 實驗18-1:RGB24轉BGR32 391
18.15.2 實驗18-2:8 × 8矩陣乘法運算 391
18.15.3 實驗18-3:使用RVV指令優化strcpy()函數 391
18.15.4 實驗18-4:使用RVV內置函數優化 391
18.15.5 實驗18-5:使用RVV優化轉置矩陣的求法 392
第 19章 壓縮指令擴展 393
19.1 RISC-V指令集的特點 393
19.2 RVC支持的指令格式與指令編碼 394
第 20章 虛擬化擴展 396
20.1 虛擬化技術介紹 396
20.1.1 虛擬化技術的發展歷史 396
20.1.2 虛擬機管理程序的分類 398
20.1.3 內存虛擬化 398
20.1.4 I/O虛擬化 399
20.2 RISC-V虛擬化擴展 399
20.2.1 CPU虛擬化擴展 399
20.2.2 M模式下系統寄存器的擴展 400
20.2.3 HS模式下的系統寄存器 402
20.2.4 VS模式下的系統寄存器 404
20.3 RISC-V內存虛擬化 404
20.4 RISC-V虛擬化擴展中的新增指令 406
20.4.1 加載與存儲虛擬機內存指令 406
20.4.2 虛擬化內存屏障指令 406
20.5 進入和退出虛擬機 407
20.5.1 異常陷入 408
20.5.2 異常返回 408
20.5.3 新增的中斷與異常類型 409
20.6 中斷虛擬化 410
20.6.1 虛擬中斷註入 410
20.6.2 陷入與模擬 411
20.7 案例分析20-1:進入和退出虛擬機 412
20.7.1 進入虛擬機 413
20.7.2 退出虛擬機 414
20.8 案例分析20-2:建立虛擬化兩階段地址映射 415
20.8.1 建立第二階段的地址映射 416
20.8.2 建立第 一階段的地址映射 418
20.8.3 測試 419
20.9 案例分析20-3:在虛擬機中實現虛擬定時器 420
20.10 案例分析20-4:在VMM中加載和存儲虛擬機內存地址 422
20.11 案例分析20-5:在VMM中模擬串口設備 424
20.12 實驗 429
20.12.1 實驗20-1:加載虛擬機1 429
20.12.2 實驗20-2:加載虛擬機2 430
20.12.3 實驗20-3:虛擬化地址映射 430
20.12.4 實驗20-4:解析虛擬機陷入的指令 430
20.12.5 實驗20-5:在VMM中模擬實現vPLIC 430
20.12.6 實驗20-6:在虛擬機中加載並運行Linux內核 430
附錄A 關於RISC-V體系結構自測題的參考答案與提示 431
附錄B RV64I指令速查表 433
附錄C RV64M指令速查表 437
附錄D RV64常用偽指令速查表 439