在ubuntu上构建riscv64编译运行环境

您所在的位置:网站首页 ubuntu交叉编译环境配置 在ubuntu上构建riscv64编译运行环境

在ubuntu上构建riscv64编译运行环境

#在ubuntu上构建riscv64编译运行环境| 来源: 网络整理| 查看: 265

Ubuntu && LLVM && RISC-V

主要参考:

https://risc-v-getting-started-guide.readthedocs.io/en/latest/linux-qemu.html;

https://zhuanlan.zhihu.com/p/263550372;

https://zhuanlan.zhihu.com/p/258394849

文章目录 Ubuntu && LLVM && RISC-V1 LLVM构建1.1 LLVM 源码下载1.2 编译前配置 & 编译安装 2 构建RISCV交叉编译工具链2.1 环境准备2.2 从国内镜像git riscv-gnu-toolchain 并移除qemu并下载其他子库2.3 编译交叉工具链2.4 export2.5 验证 3 构建RISCV运行环境:QEMU3.1 下载qemu源码3.2 编译和安装qemu3.3 export3.4 验证qemu3.5 下载内核源码3.6 配置和编译内核3.7 下载busybox源码3.8 配置编译安装busybox3.9 制作一个最小的文件系统 4 编译并启动运行4.1 编译4.2 启动qemu并运行riscv可执行文件

1 LLVM构建 1.1 LLVM 源码下载

建议下载LLVM release版本:https://releases.llvm.org/

当前版本:11.0.0

下载:Sources --> llvm-project monorepo source code (.sig)选项

1.2 编译前配置 & 编译安装

创建build,然后使用cmake配置;或者使用clion等IDE配置,参考https://blog.csdn.net/qq_21746331/article/details/110198265#t8

推荐先了解cmake,再使用IDE

$ cmake -G [options] SRC_ROOT

其中:

generator 表示用于最终驱动 gcc 执行编译生成 llvm 的工具,是用双引号括起来的字符串,cmake 支持跨平台开发,有以下四种选项:

Unix Makefiles: 即采用 Unix 上传统的 Make,指定该选项后 cmake 负责生成用于 Make 的 makefile 文件。Ninja: 采用 Ninja,指定该选项后 cmake 负责生成用于 Ninja 的 build.ninja 文件。这是 LLVM 的开发社区推荐采用的方式,因为对于像 LLVM 这样的大型软件来说,采用 Ninja 会大大加速编译的速度。Visual Studio: 指示 cmake 产生用于 Visual Studio 的项目构造文件。Xcode: 指示 cmake 产生用于 Xcode 的项目构造文件, Xcode 是运行在操作系统 MacOS X 上的集成开发工具(IDE)。

SRC_ROOT: LLVM 的官方定义是 the top level directory of the LLVM source tree, 在这里指的就是我们下载的仓库根目录 llvm-project 下的 llvm 子目录,在 LLVM 项目中 llvm 子目录存放的是这个项目的主框架代码,是必须要编译的对象。

options,以 -D 开头定义的选项宏,如果超过一个则用空格分隔。这些选项会影响 cmake 生成的构造配置文件并进而影响整个编译构造过程,针对 LLVM 常用的有以下这些,更多选项请参阅 【参考 1】:

CMAKE_BUILD_TYPE=type: 指定生成的应用程序(这里当然指的是 LLVM)的类型,type 包括 Debug、Release、RelWithDebInfo 或者 MinSizeRel。如果不指定缺省为 Debug。CMAKE_INSTALL_PREFIX=directory: 用于指定编译完后安装 LLVM 工具和库的路径,如果不指定,默认安装在 /usr/local。LLVM_TARGETS_TO_BUILD: 用于指定生成的 LLVM 可以支持的体系架构(这里称为 target),LLVM 和 GCC 有个很大的不同点是, GCC 需要为每个特定的体系架构,譬如 arm/x86 独立生成一套交叉工具链套件,而 LLVM 是在一个工具链套件中就可以支持多个体系架构。如果不指定,默认会编译所有的 targets,具体的 targets 有哪些,可以看源码 llvm-project/llvm/CMakeLists.txt 中 LLVM_ALL_TARGETS 的定义。具体制作时可以自己指定需要的 targets,通过以分号(semicolon)分隔方式给出,譬如 -DLLVM_TARGETS_TO_BUILD="ARM;PowerPC;X86"。LLVM_DEFAULT_TARGET_TRIPLE: 可以通过该选项修改默认的 target 的 triple 组合,不指定默认是 x86_64-unknown-linux-gnu。LLVM_ENABLE_PROJECTS='...': LLVM 是整个工具链套件的总称,LLVM 下包括了很多个子项目,譬如 clang, clang-tools-extra, libcxx, libcxxabi, libunwind, lldb, compiler-rt, lld, polly, or debuginfo-tests 等。如果不指定该选项,默认只编译 llvm 这个主框架。如果要选择并指定编译哪些子项目,可以通过分号分隔方式给出,譬如我们在编译 llvm 之外还想编译 Clang, libcxx, 和 libcxxabi, 那么可以写成这样:-DLLVM_ENABLE_PROJECTS="clang;libcxx;libcxxabi"。 $ cmake -G "Unix Makefiles" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=../install \ -DLLVM_TARGETS_TO_BUILD="RISCV" \ -DLLVM_ENABLE_PROJECTS="clang;libcxx;libcxxabi" \ -DLLVM_DEFAULT_TARGET_TRIPLE="riscv64-unknown-linux-gnu" \ ../llvm $ make -j $(nproc) $ make install $ ../install/bin/clang -v clang version 10.0.1 (https://gitee.com/mirrors/llvm-project.git ef32c611aa214dea855364efd7ba451ec5ec3f74) Target: riscv64-unknown-linux-gnu Thread model: posix InstalledDir: /home/u/ws/llvm-project/test/../install/bin 2 构建RISCV交叉编译工具链 2.1 环境准备 $ sudo apt install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev \ gawk build-essential bison flex texinfo gperf libtool patchutils bc \ zlib1g-dev libexpat-dev git \ libglib2.0-dev libfdt-dev libpixman-1-dev \ libncurses5-dev libncursesw5-dev $ mkdir riscv64-linux $ cd riscv64-linux 2.2 从国内镜像git riscv-gnu-toolchain 并移除qemu并下载其他子库 $ git clone https://gitee.com/mirrors/riscv-gnu-toolchain $ cd riscv-gnu-toolchain $ git rm qemu $ git submodule update --init --recursive 2.3 编译交叉工具链 $ ./configure --prefix=/opt/riscv64 $ sudo make linux -j $(nproc) 2.4 export export PATH="$PATH:/opt/riscv64/bin" 2.5 验证 $ riscv64-unknown-linux-gnu-gcc -v Using built-in specs. COLLECT_GCC=riscv64-unknown-linux-gnu-gcc COLLECT_LTO_WRAPPER=/opt/riscv64/libexec/gcc/riscv64-unknown-linux-gnu/10.1.0/lto-wrapper Target: riscv64-unknown-linux-gnu Configured with: /home/u/ws/riscv64-linux/riscv-gnu-toolchain/riscv-gcc/configure --target=riscv64-unknown-linux-gnu --prefix=/opt/riscv64 --with-sysroot=/opt/riscv64/sysroot --with-system-zlib --enable-shared --enable-tls --enable-languages=c,c++,fortran --disable-libmudflap --disable-libssp --disable-libquadmath --disable-libsanitizer --disable-nls --disable-bootstrap --src=.././riscv-gcc --disable-multilib --with-abi=lp64d --with-arch=rv64imafdc --with-tune=rocket 'CFLAGS_FOR_TARGET=-O2 -mcmodel=medlow' 'CXXFLAGS_FOR_TARGET=-O2 -mcmodel=medlow' Thread model: posix Supported LTO compression algorithms: zlib gcc version 10.1.0 (GCC) 3 构建RISCV运行环境:QEMU 3.1 下载qemu源码 $ cd riscv64-linux #回到根目录 $ wget https://download.qemu.org/qemu-5.2.0.tar.xz $ tar xvJf qemu-5.2.0.tar.xz 3.2 编译和安装qemu $ cd qemu-5.1.0/ $ ./configure --target-list=riscv64-softmmu --prefix=/opt/qemu $ make -j $(nproc) $ sudo make install 3.3 export export PATH=$PATH:/opt/riscv64/bin:/opt/qemu/bin 3.4 验证qemu $ qemu-system-riscv64 --version QEMU emulator version 5.1.0 Copyright (c) 2003-2020 Fabrice Bellard and the QEMU Project developers 3.5 下载内核源码 $ cd riscv64-linux #回到根目录 $ git clone https://gitee.com/mirrors/linux.git

如果出现“过早的文件结束符”,尝试扩大缓存

3.6 配置和编译内核 $ git checkout v5.4 $ make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- defconfig $ make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- -j $(nproc) 3.7 下载busybox源码 $ cd riscv64-linux #回到根目录 $ git clone https://gitee.com/mirrors/busyboxsource.git $ cd busyboxsource 3.8 配置编译安装busybox $ CROSS_COMPILE=riscv64-unknown-linux-gnu- make menuconfig #打开配置菜单后进入第一行的 "Settings",在"Build Options"节中,选中 “Build static binary (no shared libs)”,设置好后退出保存配置。 $ CROSS_COMPILE=riscv64-unknown-linux-gnu- make -j $(nproc) $ CROSS_COMPILE=riscv64-unknown-linux-gnu- make install $ ls _install bin linuxrc sbin usr 3.9 制作一个最小的文件系统 $ cd riscv64-linux #回到根目录 $ qemu-img create rootfs.img 1g $ mkfs.ext4 rootfs.img $ mkdir rootfs $ sudo mount -o loop rootfs.img rootfs $ cd rootfs $ sudo cp -r ../busyboxsource/_install/* . $ sudo mkdir proc sys dev etc etc/init.d $ cd etc/init.d/ $ sudo touch rcS $ sudo vi rcS #编辑该文件如下 #!/bin/sh mount -t proc none /proc mount -t sysfs none /sys /sbin/mdev -s $ sudo chmod +x rcS $ sudo umount rootfs 4 编译并启动运行 4.1 编译

编辑一个简单的 c 文件 test.c

$ vim test.c #include int main(int argc, char *argv[]) { printf("Hello, world!\n"); return 0; }

受限于 LLVM 自身链接器和 C 库的不完善,clang 目前需要使用 GNU 的链接器和 C 库来生成 RISC-V 的可执行程序。

运行 clang 编译程序,通过 --sysroot 选项来指定 gnu 工具链的 sysroot,通过 --gcc-toolchain 来指定 gcc 工具链的位置。

使用 2 中制作的交叉编译工具链,生成riscv上的可执行文件

$ clang --target=riscv64-unknown-linux-gnu --gcc-toolchain=/opt/riscv64 --sysroot=/opt/riscv64/sysroot/ --static test.c

验证文件格式

$ file a.out a.out: ELF 64-bit LSB executable, UCB RISC-V, version 1 (SYSV), statically linked, for GNU/Linux 4.15.0, with debug_info, not stripped 4.2 启动qemu并运行riscv可执行文件

将文件复制到3中构建的文件系统中

$ cd riscv64-linux #回到根目录 $ sudo mount -o loop rootfs.img rootfs $ sudo cp rootfs/root/ $ sudo umount rootfs

启动qemu并运行

$ qemu-system-riscv64 -M virt -m 256M -nographic -kernel linux/arch/riscv/boot/Image -drive file=rootfs.img,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -append "root=/dev/vda rw console=ttyS0" / # cd root/ /root # ./a.out Hello, world!


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3