RISCV——內核及匯編
小狼@http://blog.csdn.net/xiaolangyangyang
1、寄存器組(ABI)
2、異常及中斷
????????XV6 trap(二)RISCV中斷異常處理/定時器中斷
- mie:中斷開關
- mip:中斷狀態
- mstatus.mie:全局中斷開關
????????RISCV異常及中斷向量有兩種方式:一是全部異常及中斷使用同一個入口,二是使用向量表,D1s芯片使用的是第一種方式,全部異常及中斷使用同一入口,再通過scause判斷是異常還是中斷,以及異常或中斷編號,如下圖所示:
3、特權模式
????????RISC-V特權模式與寄存器
4、啟動代碼分析
/* linker.ld */
/* 起始地址是0x27000 */SECTIONS
{/** 設置benos的加載入口地址為0x27000** 這里“.”表示location counter,當前位置*/. = 0x27000,/** 這里是第一個段text.boot,起始地址就是0x27000* 這個段存放了benos的第一條指令*/_text_boot = .;.text.boot : { *(.text.boot) }_etext_boot = .;/** text代碼段*/. = ALIGN(8);_text = .;_stext = .;.text :{*(.text)}. = ALIGN(8);_etext = .;/** 只讀數據段*/_rodata = .;.rodata : { *(.rodata) }_erodata = .;/** 數據段*/_data = .;.data : { *(.data) }_edata = .;/** bss段** ALIGN(8)表示8個字節對齊* bss_begin的起始地址以8字節對齊*/. = ALIGN(0x8);_bss = .;.bss : { *(.bss*) } _ebss = .;
}
/* boot.S */
/* 啟動代碼,需要設置SP指針 */.section ".text.boot".globl _start
_start:/* 關閉中斷 */csrw sie, zerocall __init_uartcall print_asm/* 設置棧, 棧的大小為4KB */la sp, stacks_startli t0, 4096add sp, sp, t0/* 跳轉到C語言 */tail kernel_mainprint_asm:/*此時SP棧空間還沒分配,把返回地址ra保存到臨時寄存器中*/mv s1, rala a0, boot_stringcall put_string_uart/*恢復返回地址ra*/mv ra, s1ret.section .data
.align 12
.global stacks_start
stacks_start:.skip 4096.section .rodata
.align 3
.globl boot_string
boot_string:.string "\r\nBooting at asm\r\n"
/* entry.S */
/* 主要定義了異常及中斷入口 */#include "asm/asm-offsets.h"
#include "asm/csr.h".macro kernel_entryaddi sp, sp, -(PT_SIZE)sd x1, PT_RA(sp)sd x3, PT_GP(sp)sd x5, PT_T0(sp)sd x6, PT_T1(sp)sd x7, PT_T2(sp)sd x8, PT_S0(sp)sd x9, PT_S1(sp)sd x10, PT_A0(sp)sd x11, PT_A1(sp)sd x12, PT_A2(sp)sd x13, PT_A3(sp)sd x14, PT_A4(sp)sd x15, PT_A5(sp)sd x16, PT_A6(sp)sd x17, PT_A7(sp)sd x18, PT_S2(sp)sd x19, PT_S3(sp)sd x20, PT_S4(sp)sd x21, PT_S5(sp)sd x22, PT_S6(sp)sd x23, PT_S7(sp)sd x24, PT_S8(sp)sd x25, PT_S9(sp)sd x26, PT_S10(sp)sd x27, PT_S11(sp)sd x28, PT_T3(sp)sd x29, PT_T4(sp)sd x30, PT_T5(sp)sd x31, PT_T6(sp)csrr s1, sstatussd s1, PT_SSTATUS(sp)/*保存sepc*/csrr s2, sepcsd s2, PT_SEPC(sp)/*保存sbadaddr*/csrr s3, sbadaddrsd s3, PT_SBADADDR(sp)/*保存scause*/csrr s4, scausesd s4, PT_SCAUSE(sp)/*保存ssratch*/csrr s5, sscratchsd s5, PT_TP(sp)/*保存SP*/addi s0, sp, PT_SIZE sd s0, PT_SP(sp)
.endm.macro kernel_exitld a0, PT_SSTATUS(sp)csrw sstatus, a0ld a2, PT_SEPC(sp)csrw sepc, a2ld x1, PT_RA(sp)ld x3, PT_GP(sp)ld x4, PT_TP(sp)ld x5, PT_T0(sp)ld x6, PT_T1(sp)ld x7, PT_T2(sp)ld x8, PT_S0(sp)ld x9, PT_S1(sp)ld x10, PT_A0(sp)ld x11, PT_A1(sp)ld x12, PT_A2(sp)ld x13, PT_A3(sp)ld x14, PT_A4(sp)ld x15, PT_A5(sp)ld x16, PT_A6(sp)ld x17, PT_A7(sp)ld x18, PT_S2(sp)ld x19, PT_S3(sp)ld x20, PT_S4(sp)ld x21, PT_S5(sp)ld x22, PT_S6(sp)ld x23, PT_S7(sp)ld x24, PT_S8(sp)ld x25, PT_S9(sp)ld x26, PT_S10(sp)ld x27, PT_S11(sp)ld x28, PT_T3(sp)ld x29, PT_T4(sp)ld x30, PT_T5(sp)ld x31, PT_T6(sp)ld x2, PT_SP(sp)
.endm/*do_exception_vector必須4字節對齊否則寫入stvec寄存器會不成功*/
.align 2
.global do_exception_vector
do_exception_vector:kernel_entrycsrw sscratch, x0la ra, ret_from_exceptionmv a0, sp /* pt_regs */mv a1, s4tail do_exceptionret_from_exception:restore_all:kernel_exitsret.global trigger_load_access_fault
trigger_load_access_fault:li a0, 0x100001ld a0, (a0)ret
5、調試
????????體驗第一個程序
????????平頭哥IP核C906的JTAG調試器DIY教程(一)
????????平頭哥IP核C906的JTAG調試器DIY教程(二)
? ? ? ? 《T-HEAD+CPU調試技巧.pdf》
6、各特權態的指令
- 各個特權級都擁有的指令:
????????ECALL:U態陷入S態,S態陷入M態
????????EBREAK:產生斷點異常
????????FENCE.I:產生一個內存讀寫屏障
????????SRET/URET:M太返回S態,S態返回U態
- S態引入的指令:
? ? ? ? SFENCE.VMA:主要用于刷新頁表
- M態引入的指令:
? ? ? ? WFI:讓當前處理器核心進入睡眠狀態
7、各特權態的CSR
- CSR寄存器有自己的一套獨立的地址空間,訪問CSR需要使用專用的指令
- 每一個處理器核心都有自己一套獨立的4K CSR,這4K CSR分別對應到4個特權態(U\S\V\M),對于每個特權態,最多有1024個CSR可使用
- 訪問沒有權限的CSR會Trap,訪問不存在的CSR會Trap,寫只讀CSR會Trap,對于可選寄存器的操作會被忽略
【百問網DongshanPI-D1S開發板體驗】2環境搭建
全志D1s開發板裸機開發之壞境搭建
DongshanPi-D1s快速上手 | 開發環境搭建
韋東山D1S板子——xfel工具無法燒寫bin文件到spi norFlash問題解決
RISC-V 架構 - 精講