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
brew install qemu

我们刚刚安装的qemu 内有若干台的机器(可通过 qemu-system-riscv32 -machine 选项指定),这非常方便。

接下来,让我们安装 OpenOCD 的 RISC-V 兼容副本和 RISC-V 工具链。

  1. 从此处下载 RISC-V OpenOCD 和 RISC-V 工具链的预构建版本:

  2. 将这些文件移动并解压缩到某个目录中。我为这个和其他 RISC-V 工具链 QEMU 等创建一个名为~/usys/riscv 的文件夹。请记住你选择的目录,因为我们将在本文和下一篇文章中使用它。

    1
    2
    3
    4
    5
    6
    7
    mkdir -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
  3. 设置环境变量:RSICV_OPENOCD_PATHRISCV_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
  4. 接下来,我们要给这些可执行文件创建一个软链接到 /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
2
3
cd ~/wherever/you/want/to/clone/this
git clone --recursive https://github.com/sifive/freedom-e-sdk.git
cd freedom-e-sdk

传统技能,运行一个 freedom-e-sdk 提供的 hello world 程序吧!首先,使用 Makefile来编译他们提供的程序,并指定编译后的目标。

1
make PROGRAM=hello TARGET=sifive-hifive1 CONFIGURATION=debug software

然后,在 QEMU 上运行:

1
2
qemu-system-riscv32 -nographic -machine sifive_e -kernel software/hello/debug/hello.elf
Hello, World!

下一步

这是一个很好的开始,但是我的目标是 shave the yak,尽管已经确认我们有一个行之有效的工具链,但freedom-e-sdk 示例却隐藏了很多有趣的细节。请注意,我们不必设置任何链接器文件或启动代码——SiFive 提供板级支持的链接器脚本,各种Makefilefreedom-metal library 为我们解决这些问题。

在本系列的第二部分中,我们将摆脱freedom-e-sdk的束缚,走自己的路。我们将使用dtc检查 qemu 虚拟机的硬件布局,设计并检查链接器脚本,创建基本运行时以设置我们的堆栈,了解一些基本的 RISC-V 装配,等等。


RISC-V from Scratch 1
https://dingfen.github.io/2020/07/24/2020-7-24-riscv-from-scratch-1/
作者
Bill Ding
发布于
2020年7月24日
更新于
2024年4月9日
许可协议