Open mapleFU opened 3 years ago
第一点是标准库依赖,即 no_std
的时候需要处理的:
panic_handler
, panic 之后会带着信息走到这里来,nomicon 也有提到这个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
main
是用户的第一个函数,但是语言之类的可能提供运行时,所以裸金属上跑你还得处理 runtime 相关的问题。
以 Rust 语言为例,一个典型的链接了标准库的 Rust 程序会首先跳转到 C 语言运行时环境中的 crt0(C Runtime Zero)进入 C 语言运行时环境设置 C 程序运行所需要的环境(如创建堆栈或设置寄存器参数等)。 然后 C 语言运行时环境会跳转到 Rust 运行时环境的入口点(Entry Point)进入 Rust 运行时入口函数继续设置 Rust 运行环境,而这个 Rust 的运行时入口点就是被 start 语义项标记的。Rust 运行时环境的入口点结束之后才会调用 main 函数进入主程序。
我们需要函数到对应的入口,就要调整内存,和调整 Rust 开始运行的入口。
在修改 linker script 前,程序被放到低地址上,但是 os 应该位于高地址,所以需要调整
OpenSBI 相当于 bootloader, 也提供了一些简单的接口
OpenSBI 提供了运行时,我们需要设置对应的基本处理或者向量处理
当产生中断的时候,有几个s
寄存器会被设置,这里 rCore 把对应内容再封装了一层处理
为了状态的保存与恢复,我们可以先用栈上的一小段空间来把需要保存的全部通用寄存器和 CSR 寄存器保存在栈上,保存完之后在跳转到 Rust 编写的中断处理函数;而对于恢复,则直接把备份在栈上的内容写回寄存器。由于涉及到了寄存器级别的操作,我们需要用汇编来实现。
这里产生中断的时候,保存了所有寄存器,然后丢给了处理程序,再 save 回来
https://github.com/KodrAus/rust-no-std