RISCV——内核及汇编

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, zero

	call __init_uart
	call print_asm

	/* 设置栈, 栈的大小为4KB */
	la sp, stacks_start
	li t0, 4096
	add sp, sp, t0

	/* 跳转到C语言 */
	tail kernel_main

print_asm:
        /*此时SP栈空间还没分配,把返回地址ra保存到临时寄存器中*/
	mv s1, ra

	la a0, boot_string
	call put_string_uart

	/*恢复返回地址ra*/
	mv ra, s1
	ret

.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_entry
	addi 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, sstatus
	sd s1, PT_SSTATUS(sp)

	/*保存sepc*/
	csrr s2, sepc
	sd s2, PT_SEPC(sp)
	
	/*保存sbadaddr*/
	csrr s3, sbadaddr
	sd s3, PT_SBADADDR(sp)

	/*保存scause*/
	csrr s4, scause
	sd s4, PT_SCAUSE(sp)

	/*保存ssratch*/
	csrr s5, sscratch
	sd s5, PT_TP(sp)

	/*保存SP*/
	addi s0, sp, PT_SIZE 
	sd s0, PT_SP(sp)
.endm

.macro kernel_exit
	ld a0, PT_SSTATUS(sp)
	csrw sstatus, a0

	ld a2, PT_SEPC(sp)
	csrw sepc, a2

	ld 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_entry

	csrw sscratch, x0

	la ra, ret_from_exception

	mv a0, sp /* pt_regs */
	mv a1, s4
	tail do_exception

ret_from_exception:

restore_all:
	kernel_exit
	sret

.global trigger_load_access_fault
trigger_load_access_fault:
	li a0, 0x100001
	ld 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 架构 - 精讲

相关推荐
草莓熊Lotso1 天前
【C语言编译与链接】--翻译环境和运行环境,预处理,编译,汇编,链接
c语言·开发语言·汇编·经验分享·笔记·其他
艾莉丝努力练剑2 天前
深入详解编译与链接:翻译环境和运行环境,翻译环境:预编译+编译+汇编+链接,运行环境
c语言·开发语言·汇编·学习
一条叫做nemo的鱼2 天前
从汇编的角度揭秘C++函数重载,原来这么简单
汇编·c++·函数重载·原理解密
清水白石0084 天前
WebSockets 在实时通信中的应用与优化
开发语言·汇编·python·websockets
南玖yy5 天前
如何创建和使用汇编语言,以及下载编译汇编软件(Notepad++,NASM的安装)
汇编·策略模式
南玖yy5 天前
x86 与 ARM 汇编深度对比:聚焦 x86 汇编的独特魅力
开发语言·汇编·arm开发·边缘计算
JCBP_5 天前
C++(4)
开发语言·汇编·c++
Funny-Boy8 天前
初识main函数
汇编·c++
0xCC说逆向8 天前
Windows逆向工程提升之IMAGE_IMPORT_DESCRIPTOR
c语言·汇编·windows·安全·逆向·pe结构