mapleFU / mwishCore

The kernel of mwish following the uCore
7 stars 0 forks source link

关于项目运行时支持/中断的 Note #6

Open mapleFU opened 3 years ago

mapleFU commented 3 years ago

https://github.com/KodrAus/rust-no-std

mapleFU commented 3 years ago

第一点是标准库依赖,即 no_std 的时候需要处理的:

  1. panic_handler, panic 之后会带着信息走到这里来,nomicon 也有提到这个
  2. 如果没有指定 panic = "abort", 那么需要如 [1] 中配置 eh_personality. 作为一个最小化的应用,其实貌似可以不用这个

[1] https://docs.rust-embedded.org/embedonomicon/smallest-no-std.html

doc 里面有指定行为的:https://doc.rust-lang.org/book/ch09-01-unrecoverable-errors-with-panic.html

mapleFU commented 3 years ago

main 是用户的第一个函数,但是语言之类的可能提供运行时,所以裸金属上跑你还得处理 runtime 相关的问题。

以 Rust 语言为例,一个典型的链接了标准库的 Rust 程序会首先跳转到 C 语言运行时环境中的 crt0(C Runtime Zero)进入 C 语言运行时环境设置 C 程序运行所需要的环境(如创建堆栈或设置寄存器参数等)。 然后 C 语言运行时环境会跳转到 Rust 运行时环境的入口点(Entry Point)进入 Rust 运行时入口函数继续设置 Rust 运行环境,而这个 Rust 的运行时入口点就是被 start 语义项标记的。Rust 运行时环境的入口点结束之后才会调用 main 函数进入主程序。

我们需要函数到对应的入口,就要调整内存,和调整 Rust 开始运行的入口。

mapleFU commented 3 years ago

在修改 linker script 前,程序被放到低地址上,但是 os 应该位于高地址,所以需要调整

mapleFU commented 3 years ago

OpenSBI 相当于 bootloader, 也提供了一些简单的接口

mapleFU commented 3 years ago

OpenSBI 提供了运行时,我们需要设置对应的基本处理或者向量处理

当产生中断的时候,有几个s 寄存器会被设置,这里 rCore 把对应内容再封装了一层处理

为了状态的保存与恢复,我们可以先用栈上的一小段空间来把需要保存的全部通用寄存器和 CSR 寄存器保存在栈上,保存完之后在跳转到 Rust 编写的中断处理函数;而对于恢复,则直接把备份在栈上的内容写回寄存器。由于涉及到了寄存器级别的操作,我们需要用汇编来实现。

这里产生中断的时候,保存了所有寄存器,然后丢给了处理程序,再 save 回来