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
2
3
4
5
6
7
8
9
10
0x1000: auipc   t0,0x0
0x1004: addi a2,t0,40
0x1008: csrr a0,mhartid
0x100c: ld a1,32(t0)
0x1010: ld t0,24(t0)
0x1014: jr t0
0x1018: unimp
0x101a: .insn 2,0x8000
0x101c: unimp
0x101e: unimp

可能是因为 Qemu 版本不一样,我自己用 gdb 调试的时候和文档不太一样,不过区别不大。

第一行 auipc t0,0x0 实际上将 pc 的值,即 0x1000 赋值给了 t0,接下来三行似乎是对三个寄存器进行了赋值,暂时看不出来有什么用。关键的一行是 0x1010 这里,t0 + 24 得到的是 0x1018,这里有两个字节的 0,ld 将会加载一个 64 位的数据,也就是 8 个字节,由于采用小端序,所以 0x10190x000x10200x80,最后 t0 的值是 0x0000_0000_8000_0000,所以会跳转到 0x80000000

到达 0x8000000 后就到了 RustSBI 的部分,进行了串口设备初始化等步骤后,再跳转到 0x80200000


rCore 学习笔记 - 第一章
http://xiao-h.com/2025/01/12/rCore-0x01/
作者
小H
发布于
2025年1月12日
许可协议