RISC-V體系結構編程與實踐( 簡體 字) | |
作者:奔跑吧Linux社區 | 類別:1. -> 電腦組織與體系結構 -> 單晶片 -> RISC-V |
出版社:人民郵電出版社 | 3dWoo書號: 56215 詢問書籍請說出此書號! 有庫存 NT售價: 650 元 |
出版日:2/1/2023 | |
頁數:464 | |
光碟數:0 | |
站長推薦: | |
印刷:黑白印刷 | 語系: ( 簡體 字 ) |
ISBN:9787115603609 | 加入購物車 │加到我的最愛 (請先登入會員) |
(簡體書上所述之下載連結耗時費功, 恕不適用在台灣, 若讀者需要請自行嘗試, 恕不保證, 繁體書的下載亦請直接連絡出版社) | |
第 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 本書旨在介紹RISC-V體系結構的設計和實現。本書首先介紹RISC-V體系結構的基礎知識、實驗環境搭建、常用指令、函數調用規范與棧,然后講述GNU匯編器、鏈接器、鏈接腳本和GCC內嵌匯編代碼,接著討論RISC-V體系結構中的異常處理、中斷、內存管理、高速緩存、緩存一致性、TLB管理、原子操作、內存屏障指令,最后闡述RSIC-V體系結構中的壓縮指令擴展、虛擬化擴展等。
本書不僅適合軟件開發人員閱讀,還可以作為計算機相關專業和相關培訓機構的教材。 |