rCore 学习笔记 - 第一章
前言
这些笔记的内容主要有两个:一个是记录下我实际操作过程中,遇到的和教程不一样的地方,并且记录下我的解决方法;二是记录写练习的过程。我不会重复记录手册里已经有的知识。
我希望能够尽量使用新一点的特性,避免原教程中妥协的地方(比如在当时 rust 的有些特性在正式版中不支持,只能用 nightly 版本)。
环境
首先根据文档的指引配置好实验环境,我使用了 Windows + wsl2,但出于个人喜好,我没有使用 Ubuntu,而是用了 OpenSUSE Tumbleweed.
文档已经有一段时间没更新了,有些内容发生了些许变化,比如随着 rust 版本的更新,一些实验特性变成了稳定特性。我使用的 rust 版本是 1.83.0.
同时我使用了 Qemu 7.0.0 和最新版(Prereleased 2024-03-24)的 rustsbi-qemu.
在 OpenSUSE Tumbleweed中,我发现 gdb 似乎本来就有了切换架构到 risc-v 的功能,就没有折腾 riscv64-unknown-elf-gdb 了(这东西在 OpenSUSE Tumbleweed 下需要手动编译,非常麻烦)。
在内核加载前
在控制权递交给内核前,经历了两个步骤,一个是从载入到跳转到 0x80000000,另一个是经过 RustSBI 的初始化,从 0x80000000 到 0x80200000 的内核处。
1 |
|
可能是因为 Qemu 版本不一样,我自己用 gdb 调试的时候和文档不太一样,不过区别不大。
第一行 auipc t0,0x0
实际上将 pc
的值,即 0x1000
赋值给了 t0
,接下来三行似乎是对三个寄存器进行了赋值,暂时看不出来有什么用。关键的一行是 0x1010
这里,t0 + 24
得到的是 0x1018
,这里有两个字节的 0,ld
将会加载一个 64 位的数据,也就是 8 个字节,由于采用小端序,所以 0x1019
是 0x00
,0x1020
是 0x80
,最后 t0
的值是 0x0000_0000_8000_0000
,所以会跳转到 0x80000000
。
到达 0x8000000
后就到了 RustSBI 的部分,进行了串口设备初始化等步骤后,再跳转到 0x80200000
。