RISC-V from Scratch 1
RISC-V from Scratch 1
译自:RISC-V from scratch 1: Introduction, toolchain setup, and hello world!
最近在尝试完成一个 RISC-V 内核,在搜索资料的时不经感叹 RISC-V 的中文相关内容少且不精,而当我读完这系列英文博客后感觉受益匪浅,故将其翻译为中文,既方便接下来的研究,也方便更多朋友学习。这是系列 github 库。
简介
通过 RISC-V from scratch,我会给你介绍一些很多与 RISC-V 及其生态相关的底层概念(例如编译、链接、原语运行时、汇编等)。
在第一篇博文中,我将简短的讨论一下 RISC-V 以及为什么它很重要,并搭建起 RISC-V 的工具链,最后在 RISC-V 模拟器中构建并运行一个简单的 C 程序。
什么是 RISC-V
RISC-V 是一个开源免费的 ISA,始于2010年在 UC-Berkeley 的一个项目。不得不承认,免费使用对其成功起到了重要作用,也使之与其他体系结构形成了鲜明的对比。以 ARM 为例——为创作一个兼容 ARM 的处理器,你必须支付100万美元至1000万美元的前期费用,以及每片0.5%-2%的特许权使用费。这种免费、开放的模型使 RISC-V 对许多人来说都是有吸引力的,这是因为很多硬件初创公司无力负担许可处理器,以及学术机构、开源社区的费用。
RISC-V 的迅速崛起在当时并没有引起人们的注意。ARM 推出了一个现在被淘汰的网站,该网站试图(但没有成功)强调 ARM 相对于 RISC-V 的假定优势。现如今 RISC-V 得到了包括 Google,Nvidia 和Western Digital 在内的众多主要公司的支持。
QEMU and RISC-V toolchain setup
除非我们有一个适合的环境,否则我们肯定无法在 RISC-V 处理器上跑任何代码。当然,在 qemu 的帮助下,我们也不需要真的买一个 RISC-V 的处理器来完成这个实验。在 Mac 下,安装 qemu
是非常简单的(其余操作系统看这里):
1 |
|
我们刚刚安装的qemu
内有若干台的机器(可通过 qemu-system-riscv32 -machine
选项指定),这非常方便。
接下来,让我们安装 OpenOCD 的 RISC-V 兼容副本和 RISC-V 工具链。
-
从此处下载 RISC-V OpenOCD 和 RISC-V 工具链的预构建版本:
-
将这些文件移动并解压缩到某个目录中。我为这个和其他 RISC-V 工具链 QEMU 等创建一个名为
~/usys/riscv
的文件夹。请记住你选择的目录,因为我们将在本文和下一篇文章中使用它。1
2
3
4
5
6
7mkdir -p ~/usys/riscv
cd ~/Downloads
cp openocd-<date>-<platform>.tar.gz ~/usys/riscv
cp riscv64-unknown-elf-gcc-<date>-<platform>.tar.gz ~/usys/riscv
cd ~/usys/riscv
tar -xvf openocd-<date>-<platform>.tar.gz
tar -xvf riscv64-unknown-elf-gcc-<date>-<platform>.tar.gz -
设置环境变量:
RSICV_OPENOCD_PATH
和RISCV_PATH
,方便其他程序找到我们的工具链。在不同操作系统下,该操作会明显不同,在 Mac 上,可以这样做:1
2
3
4
5
6
7# I put these two exports directly in my ~/.zshenv file
# If you use a different shell or OS you may have to do something else.
export RISCV_OPENOCD_PATH="$HOME/usys/riscv/openocd-<date>-<version>"
export RISCV_PATH="$HOME/usys/riscv/riscv64-unknown-elf-gcc-<date>-<version>"
# Reload .zshenv with our new environment variables.
# Restarting your shell will have a similar effect.
source ~/.zshenv -
接下来,我们要给这些可执行文件创建一个软链接到
/usr/local/bin
,这样我们就可以不必每次都把完整的路径打出来了。1
2
3# Symbolically link our gcc executable into /usr/local/bin.
# Repeat this process for any other executables you want to quickly access.
ln -s ~/usys/riscv/riscv64-unknown-elf-gcc-8.2.0-<date>-<version>/bin/riscv64-unknown-elf-gcc /usr/local/bin
好啦,我们已经装好了 RISC-V 工具链。这些可执行文件(例如 riscv64-unknown-elf-gcc
, riscv64-unknown-elf-gdb
, riscv64-unknown-elf-ld
等都放在 ~/usys/riscv/riscv64-unknown-elf-gcc-<date>-<version>/bin/
。
Hello, RISC-V!
于2019年5月26日更新
很不幸的是,因为 RISC-V QEMU 出现了一个 bug ,导致在 QEMU 上运行 freedom-e-sdk “hello world” 程序无法跑通。补丁已经加上,但接下来的部分你们是无法跑通的,不过,你不必担心,因为接下来的部分可以跳过,不会影响后续的实验结果。
更多信息,请看这里: https://github.com/sifive/freedom-e-sdk/issues/260#issuecomment-496037827
现在我们已经有了工具链,让我们运行一个示例 RISC-V 程序。之前,我链接了一个名为 freedom-e-sdk 的 SiFive 库,该库提供了我们可以尝试的各种程序。首先以递归方式 clone 此库:
1 |
|
传统技能,运行一个 freedom-e-sdk 提供的 hello world 程序吧!首先,使用 Makefile
来编译他们提供的程序,并指定编译后的目标。
1 |
|
然后,在 QEMU 上运行:
1 |
|
下一步
这是一个很好的开始,但是我的目标是 shave the yak,尽管已经确认我们有一个行之有效的工具链,但freedom-e-sdk
示例却隐藏了很多有趣的细节。请注意,我们不必设置任何链接器文件或启动代码——SiFive 提供板级支持的链接器脚本,各种Makefile
和 freedom-metal library 为我们解决这些问题。
在本系列的第二部分中,我们将摆脱freedom-e-sdk
的束缚,走自己的路。我们将使用dtc
检查 qemu
虚拟机的硬件布局,设计并检查链接器脚本,创建基本运行时以设置我们的堆栈,了解一些基本的 RISC-V 装配,等等。