过程:
在物理服务器上安装qemu模拟器,模拟器中运行基于riscv指令集编译的linux镜像文件。
工具集合:
- riscv-qemu(模拟器,可以模拟运行riscv指令集的程序或镜像)
- riscv-tools(基于riscv指令集的交叉编译工具)
- riscv-pk(用于包装内核文件vmlinux)
- busybox(用于给linux镜像安装基本命令,如ls,cat,mv等等)
一、从零开始
首先创建一个工作目录叫做$TOP
,进入工作目录,并将设定$TOP
环境变量
$ mkdir riscv |
二、安装riscv-toolchain
1 . 下载交叉编译工具:
$ git clone https://github.com/riscv/riscv-tools.git |
2 . 为了编译gcc,我们需要安装一些其他的依赖库,包括 flex, bison, autotools, libmpc, libmpfr, and libgmp. Ubuntu系统可以通过如下命令安装:
$ sudo apt-get install autoconf automake autotools-dev curl device-tree-compiler libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf |
3 . 在开始安装之前,需要设置$RISCV
,$PATH
环境变量,这些环境变量会在整个安装过程中使用:
$ export RISCV=$TOP/riscv #将作为所有工具的安装路径 --prefix=$RISCV |
4 . 安装spike工具:
$ ./build-spike-only.sh |
5 . 编译 riscv64-unknown-linux-gnu-gcc
:
$ cd riscv-gnu-toolchain |
这会将riscv64-unknown-linux-gnu-gcc
与riscv64-unknown-elf-gcc
工具一样安装到$RISCV
,同时 $RISCV/bin
已经被添加置PATH中,所以上述工具可以直接使用。
最后执行下面的指令,运行build:
$ make linux |
三、安装riscv-qemu
1、安装qemu:
$ cd $TOP |
2、测试qemu的用户模式:
$ riscv64-unknown-linux-gnu-gcc hello.c -o hello |
3、测试qemu的镜像模式:
启动qemu,载入bbl示例镜像文件,下载地址:bblvmlinuxinitramfs_dynamic
$ riscv-qemu/riscv64-softmmu/qemu-system-riscv64 -kernel /home/tank/bblvmlinuxinitramfs_dynamic -nographic |
四、编译busybox
$ git clone https://github.com/mirror/busybox |
CONFIG_STATIC=y
, listed as “Build BusyBox as a static binary (no shared libs)” in BusyBox Settings → Build OptionsCONFIG_CROSS_COMPILER_PREFIX=riscv64-unknown-linux-gnu-
, listed as “Cross Compiler prefix” in BusyBox Settings → Build OptionsCONFIG_FEATURE_INSTALLER=y
, listed as “Support —install [-s] to install applet links at runtime” in BusyBox Settings → General ConfigurationCONFIG_INIT=y
, listed as “init” in Init utilitiesCONFIG_ASH=y
, listed as “ash” in ShellsCONFIG_ASH_JOB_CONTROL=n
, listed as “Ash → Job control” in ShellsCONFIG_MOUNT=y
, listed as “mount” in Linux System UtilitiesCONFIG_FEATURE_USE_INITTAB=y
, listed as “Support reading an inittab file” in Init Utilities
编译完成后会在busybox目录下生成busybox二进制执行文件
五、编译riscv-linux
1 . 获取内核代码:
$ cd $TOP |
2 . 准备一个文件系统初始化文件,命名为initramfs.txt
,可以在其中创建任意想要的文件夹文件,如下是我的文件系统样例:
dir /dev 755 0 0 |
3 . 准备一份初始化表,命名为inittab
,放置在内核的/etc
目录下,如下是一个简单的inittab
样例:
::sysinit:/bin/busybox mount -t proc proc /proc |
4 . 下面正式开始编译内核,首先配置编译选项:
$ make mrproper #很重要 |
- 如果不执行make mrproper编译内核时可能出现缺少头文件错误
- menuconfig : “General setup -> Initial RAM Filesystem…” (CONFIG_BLK_DEV_INITRD=y)
- menuconfig : “General setup -> Initramfs source files (CONFIG_INITRAMFS_SRC=/path/to/your/initramfs.txt)
- menuconfig : “General setup -> Cross-compiler tool prefix (CONFIG_CROSS_COMPILER_PREFIX=riscv64-unknown-linux-gnu-)
六、启动qemu运行linux镜像
所有准备工作完成,下面开始运行linux镜像
1 . 首先需要通过pk工具包中的bbl工具为linux kernel添加boot loader:
$ cd <riscv-pk>/build |
2 . 接下来通过qemu运行上一步中生成的bbl文件:
riscv-qemu/riscv64-softmmu/qemu-system-riscv64 -kernel <riscv-pk>/build/bbl -nographic |
3 . 接下来你的屏幕上会想RV图像,通过你的制作的linux镜像也会通过qemu运行,因为我们已经在其中添加了busybox工具包,你可以执行例如ls、cd、pwd等指令。通过还可以将自己编写的c语言,g语言的程序通过riscv的工具链进行编译,然后按照样例修改initramfs.txt
文件,将编译好的二进制文件加入到内核的文件系统中,然后重新从编译内核开始重新执行一遍上述过程,便可以在内核中运行你自己写的程序。
七、最后
最后我想说的是,上述过程是一个非常繁琐的过程,你需要有足够的耐心以及足够运行,首先gcc工具链和内核的编译安装是一个非常费事的过程,不仅如此你还遇到各种各种莫名其妙的问题,其中各个工具链版本的匹配便是一个令人极度头痛的问题.
博主足够幸运,在第一次运行上述过程中非常幸运的没有遇到版本不匹配的问题,希望诸位也能如此幸运。
八、最后的最后
近期因为各种原因需要重新使用最新版本复现上述过程,耗时近3天遇到了各种各样的问题。最后,在师兄的提示下,选择了sifive公司的集成工具。完成上述工程只需要:
$ git clone --recursive https://github.com/sifive/freedom-u-sdk |
接下来你就会发现,自己之前所做的一切努力在别人看来只不过一个脚本就能解决,并且你不会想到sifive为你移植多少依赖库。。。
最后给大家送上一个运行界面图(默认用户名为:root,密码为:sifive):
