要學習riscv架構,首先第一步,要搞定riscv的gcc交叉編譯器。下面就對riscv的gcc交叉編譯器,進行詳細的介紹。
一、riscv gcc工具下載
Riscv的gcc交叉編譯器,以開源的方式託管在github上。鏈接如下:
https://github.com/riscv/riscv-gnu-toolchain
該倉庫,裏面包含了一些子倉庫。
使用以下這個命令,將所有倉庫,都clone下來。
git clone --recursive https://github.com/riscv/riscv-gnu-toolchain
以下是各個倉庫的github地址:
riscv-gcc |
|
riscv-glibc |
|
riscv-newlib |
|
riscv-dejagnu |
|
riscv-gdb |
|
riscv-binutils |
|
riscv-qemu |
二、編譯riscv gcc
下載完畢後,就要開始編譯。首先在riscv-gnu-toolchain根目錄下,創建build目錄。用於編譯riscv gcc。
riscv gcc可以編譯成以下幾個版本
-
riscv32-unknown-elf-gcc
-
riscv64-unknown-elf-gcc
-
riscv32-unknown-linux-gnu-gcc
-
riscv64-unknown-linux-gnu-gcc
-
riscv64-multilib-elf-gcc
-
riscv64-liunx-multilib-gcc
以下編譯,是基於 riscv架構支持 imc三種指令集,來進行編譯的。如果想要支持其他的指令集,只需要修改 --with-arch選項。
1、riscv32-unknown-elf-gcc
該工具,針對於riscv32架構的編譯器,使用的C運行庫爲newlib。
執行以下命令:
../configure --prefix=/opt/riscv32 --with-arch=rv32imc --with-abi=xxx
make
--mabi可以選擇如下:
-
ilp32
-
ilp32f
-
ilp32d
編譯完成後,在/opt/riscv/bin目錄下,有riscv32-unknown-elf-gcc的所有工具。
通過 riscv32-unknown-elf-gcc -v命令,可以得到該工具鏈的配置信息。
Using built-in specs.
COLLECT_GCC=./riscv32-unknown-elf-gcc
COLLECT_LTO_WRAPPER=/opt/riscv/libexec/gcc/riscv32-unknown-elf/8.2.0/lto-wrapper
Target: riscv32-unknown-elf
Configured with: /tools/riscv-gnu-toolchain-1/build/../riscv-gcc/configure --target=riscv32-unknown-elf --prefix=/opt/riscv --disable-shared --disable-threads --enable-languages=c,c++ --with-system-zlib --enable-tls --with-newlib --with-sysroot=/opt/riscv/riscv32-unknown-elf --with-native-system-header-dir=/include --disable-libmudflap --disable-libssp --disable-libquadmath --disable-libgomp --disable-nls --src=../../riscv-gcc --enable-checking=yes --disable-multilib --with-abi=ilp32 --with-arch=rv32imc 'CFLAGS_FOR_TARGET=-Os -mcmodel=medlow' 'CXXFLAGS_FOR_TARGET=-Os -mcmodel=medlow'
Thread model: single
gcc version 8.2.0 (GCC)
可以看出:
--target=riscv32-unknown-elf: 指定工具爲riscv32-unknow-elf
--prefix=/opt/riscv32: 指定工具生成的目錄
--enable-languages=c,c++: 支持c,c++語言
--with-newlib: c運行庫使用newlib
--with-abi=ilp32: 工具鏈支持的abi方式是ilp64
--with-arch=rv32imc: 工具鏈支持的riscv架構是 rv64imc
在build目錄下,有如下的文件夾和文件生成。
其中有newlib和newlib-nano,就表示c運行庫,就是用的newlib以及newlib-nano。
2、riscv64-unknown-elf-gcc
該工具,針對於riscv64架構的編譯器,使用的C運行庫爲newlib。
執行以下命令:
../configure --prefix=/opt/riscv64 --with-arch=rv64imc --with-abi=xxx
make
--with-abi可以選擇如下:
-
lp64
-
lp64f
-
lp64d
編譯完成後,在/opt/riscv64/bin目錄下,有riscv64-unknown-elf-gcc的所有工具。
使用 riscv64-unknown-elf-gcc -v 命令,可以得到該工具鏈的配置信息。
Using built-in specs.
COLLECT_GCC=./riscv64-unknown-elf-gcc
COLLECT_LTO_WRAPPER=/opt/riscv64/libexec/gcc/riscv64-unknown-elf/8.2.0/lto-wrapper
Target: riscv64-unknown-elf
Configured with: /tools/riscv-gnu-toolchain-1/build/../riscv-gcc/configure --target=riscv64-unknown-elf --prefix=/opt/riscv64 --disable-shared --disable-threads --enable-languages=c,c++ --with-system-zlib --enable-tls --with-newlib --with-sysroot=/opt/riscv64/riscv64-unknown-elf --with-native-system-header-dir=/include --disable-libmudflap --disable-libssp --disable-libquadmath --disable-libgomp --disable-nls --src=../../riscv-gcc --enable-checking=yes --disable-multilib --with-abi=lp64 --with-arch=rv64imc 'CFLAGS_FOR_TARGET=-Os -mcmodel=medlow' 'CXXFLAGS_FOR_TARGET=-Os -mcmodel=medlow'
Thread model: single
gcc version 8.2.0 (GCC)
可以看出:
--target=riscv64-unknown-elf: 指定工具爲riscv64-unknow-elf
--prefix=/opt/riscv64: 指定工具生成的目錄
--enable-languages=c,c++: 支持c,c++語言
--with-newlib: c運行庫使用newlib
--with-abi=lp64: 工具鏈支持的abi方式是lp64
--with-arch=rv64imc: 工具鏈支持的riscv架構是 rv64imc
在build目錄下,有如下的文件夾和文件生成。
其中有newlib和newlib-nano,就表示c運行庫,就是用的newlib以及newlib-nano。
3、riscv32-unknown-linux-gnu-gcc
該工具,針對於riscv32架構的編譯器,使用的C運行庫爲linux中的標準glibc。
執行以下命令:
../configure --prefix=/opt/riscv32-linux --with-arch=rv32imc --with-abi=xxx --enable-linux
make linux
--with-abi可以選擇如下:
-
lp64
-
lp64f
-
lp64d
編譯完成後,在/opt/riscv32-linux/bin目錄下,有riscv32-unknown-linux-gnu-gcc的所有工具。
使用 riscv32-unknown-linux-gnu-gcc -v 命令,可以得到該工具鏈的配置信息。
Using built-in specs.
COLLECT_GCC=./riscv32-unknown-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/opt/riscv-linux/libexec/gcc/riscv32-unknown-linux-gnu/8.2.0/lto-wrapper
Target: riscv32-unknown-linux-gnu
Configured with: /tools/riscv-gnu-toolchain-1/build/../riscv-gcc/configure --target=riscv32-unknown-linux-gnu --prefix=/opt/riscv-linux --with-sysroot=/opt/riscv-linux/sysroot --with-newlib --without-headers --disable-shared --disable-threads --with-system-zlib --enable-tls --enable-languages=c --disable-libatomic --disable-libmudflap --disable-libssp --disable-libquadmath --disable-libgomp --disable-nls --disable-bootstrap --src=../../riscv-gcc --enable-checking=yes --disable-multilib --with-abi=ilp32 --with-arch=rv32imc 'CFLAGS_FOR_TARGET=-O2 -mcmodel=medlow' 'CXXFLAGS_FOR_TARGET=-O2 -mcmodel=medlow'
Thread model: single
gcc version 8.2.0 (GCC)
可以看出:
--target=riscv32-unknown-linux-gnu: 指定工具爲riscv32-unknow-linux-gnu
--prefix=/opt/riscv-linux: 指定工具生成的目錄
--enable-languages=c,c++: 支持c,c++語言
--with-abi=ilp32: 工具鏈支持的abi方式是ilp32
--with-arch=rv32imc: 工具鏈支持的riscv架構是 rv32imc
雖然有--with-newlib配置選項,但是編譯卻不會有newlib編譯,而有glibc編譯。因爲使用的是make linux進行編譯。也可以在configure階段,加上--enable-linux選項。
在build目錄下,有如下文件以及文件夾:
可以看出,用的c運行庫是glibc。
4、riscv64-unknown-linux-gnu-gcc
該工具,針對於riscv64架構的編譯器,使用的C運行庫爲linux中的標準glibc。
執行以下命令:
../configure --prefix=/opt/riscv64-linux --with-arch=rv64imafdc --with-abi=xxx --enable-linux
make linux
--with-abi可以選擇如下:
-
lp64
-
lp64f
-
lp64d
編譯完成後,在/opt/riscv64-linux/bin目錄下,有riscv64-unknown-linux-gnu-gcc的所有工具。
使用 riscv64-unknown-linux-gnu-gcc -v 命令,可以得到該工具鏈的配置信息。
Using built-in specs.
COLLECT_GCC=./riscv64-unknown-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/opt/riscv64-linux/libexec/gcc/riscv64-unknown-linux-gnu/8.2.0/lto-wrapper
Target: riscv64-unknown-linux-gnu
Configured with: /tools/riscv-gnu-toolchain-1/build/../riscv-gcc/configure --target=riscv64-unknown-linux-gnu --prefix=/opt/riscv64-linux --with-sysroot=/opt/riscv64-linux/sysroot --with-newlib --without-headers --disable-shared --disable-threads --with-system-zlib --enable-tls --enable-languages=c --disable-libatomic --disable-libmudflap --disable-libssp --disable-libquadmath --disable-libgomp --disable-nls --disable-bootstrap --src=../../riscv-gcc --enable-checking=yes --disable-multilib --with-abi=lp64d --with-arch=rv64imafdc 'CFLAGS_FOR_TARGET=-O2 -mcmodel=medlow' 'CXXFLAGS_FOR_TARGET=-O2 -mcmodel=medlow'
Thread model: single
gcc version 8.2.0 (GCC)
可以看出:
--target=riscv64-unknown-linux-gnu: 指定工具爲riscv64-unknow-linux-gnu
--prefix=/opt/riscv64: 指定工具生成的目錄
--enable-languages=c,c++: 支持c,c++語言
--with-abi=lp64d: 工具鏈支持的abi方式是lp64d
--with-arch=rv64imafdc: 工具鏈支持的riscv架構是 rv64imafdc
雖然有--with-newlib配置選項,但是編譯卻不會有newlib編譯,而是有glibc編譯。因爲使用的是make linux進行編譯。也可以在configure階段,加上--enable-linux選項。
在build目錄下,有如下文件以及文件夾:
可以看出,用的c運行庫是glibc。
5、riscv64-linux-multilib
在編譯riscv工具鏈的時候,可以編譯multilib版本的gcc,這樣這個工具,可以同時支持32位和64位。
執行以下命令:
../configure --prefix=/opt/riscv-linux-multilib --enable-multilib --target=riscv64-linux-multilib
make linux
編譯完成後,在/opt/riscv64-linux/bin目錄下,有riscv64-linux-multilib -gcc的所有工具。
雖然有通過--target指定,但是生成的工具鏈名字還是riscv64-unknow-linu-gnu-gcc。
使用 riscv64-unknown-linux-gnu-gcc -v 命令,可以得到該工具鏈的配置信息。
Using built-in specs.
COLLECT_GCC=./riscv64-unknown-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/opt/riscv-multilib/libexec/gcc/riscv64-unknown-linux-gnu/8.2.0/lto-wrapper
Target: riscv64-unknown-linux-gnu
Configured with: /tools/riscv-gnu-toolchain-1/build/../riscv-gcc/configure --target= riscv64-linux-multilib --prefix=/opt/riscv-linux-multilib --with-sysroot=/opt/riscv-linux-multilib/sysroot --with-newlib --without-headers --disable-shared --disable-threads --with-system-zlib --enable-tls --enable-languages=c --disable-libatomic --disable-libmudflap --disable-libssp --disable-libquadmath --disable-libgomp --disable-nls --disable-bootstrap --src=../../riscv-gcc --enable-checking=yes --enable-multilib --with-abi=lp64d --with-arch=rv64imafdc 'CFLAGS_FOR_TARGET=-O2 -mcmodel=medlow' 'CXXFLAGS_FOR_TARGET=-O2 -mcmodel=medlow'
Thread model: single
可以看出:
--target= riscv64-linux-multilib: 指定工具爲riscv64-linux-multilib
--prefix=/opt/riscv-linux-multilib: 指定工具生成的目錄
--enable-languages=c,c++: 支持c,c++語言
--with-abi=lp64d: 工具鏈支持的abi方式是lp64d
--with-arch=rv64imafdc: 工具鏈支持的riscv架構是 rv64imafdc
--enabl-multilib: 啓動 multilib
對於riscv64-linux-multilib-gcc編譯器,可以通過以下選項,來決定生成的程序是32位版本還是64位版本:
- -march=rv32: 32位版本
- -march=rv64: 64位版本
6、riscv64-multilib-elf-gcc
在裸機編譯riscv工具鏈的時候,可以編譯multilib版本的gcc,這樣這個工具,可以同時支持32位和64位。
執行以下命令:
../configure --prefix=/opt/riscv64-multilib-elf --enable-multilib --target=riscv64-multilib-elf
make
編譯完成後,在/opt/ riscv64-multilib-elf /bin目錄下,有riscv64-multilib-elf-gcc的所有工具。
雖然有使用--target指定,但是生成的編譯器還是riscv64-unknown-elf-gcc。
使用 riscv64-unknown-elf-gcc -v 命令,可以得到該工具鏈的配置信息。
Using built-in specs.
COLLECT_GCC=./riscv64-unknown-elf-gcc
COLLECT_LTO_WRAPPER=/opt/riscv64-multilib-elf/libexec/gcc/riscv64-unknown-elf/8.2.0/lto-wrapper
Target: riscv64-unknown-elf
Configured with: /tools/riscv-gnu-toolchain-1/build/../riscv-gcc/configure --target=riscv64-multilib-elf --prefix=/opt/riscv64-multilib-elf --disable-shared --disable-threads --disable-tls --enable-languages=c,c++ --with-system-zlib --with-newlib --with-sysroot=/opt/riscv64-multilib-elf/riscv64-unknown-elf --disable-libmudflap --disable-libssp --disable-libquadmath --disable-libgomp --disable-nls --src=../../riscv-gcc --enable-checking=yes --enable-multilib --with-abi=lp64d --with-arch=rv64imafdc 'CFLAGS_FOR_TARGET=-Os -mcmodel=medlow' 'CXXFLAGS_FOR_TARGET=-Os -mcmodel=medlow'
Thread model: single
gcc version 8.2.0 (GCC)
可以看出:
--target=riscv64-multilib-elf: 指定工具爲riscv64-multilib-elf
--prefix=/opt/riscv64-multilib-elf: 指定工具生成的目錄
--enable-languages=c,c++: 支持c,c++語言
--with-abi=lp64d: 工具鏈支持的abi方式是lp64d
--with-arch=rv64imafdc: 工具鏈支持的riscv架構是 rv64imafdc
--enable-multilib: 啓用multilib
對於riscv64-multilib-elf-gcc編譯器,可以通過以下選項,來決定生成的程序是32位版本還是64位版本:
- -march=rv32: 32位版本
- -march=rv64: 64位版本
三、riscv-none-embed-gcc
專門爲嵌入式使用的gcc交叉編譯工具鏈。官方網站:
https://gnu-mcu-eclipse.github.io/toolchain/riscv/
可以直接下載linux的二進制執行程序,以及windows的安裝包。這個一般要搭配GNU MCU eclipse工具一起使用。
因爲這個工具,直接提供執行程序,因此就不介紹了。
四、總結
riscv的gcc編譯器,分爲2大類:
-
裸機: unknown-elf,none-embed
-
linux: linux
除了none-embed編譯器,對於每一類,如果禁用multilib,那麼又分爲32位版本和64位版本。如果使能multilib,那麼就只有一個版本,但是這個版本工具,可以同時支持32位和64位。