教你如何在優麒麟上搭建 RISC-V 交叉編譯環境

由於 RISC-V 設備價格昂貴、不易采購等諸多原因,許多小夥伴雖然很感興趣,但仍無法參與 RISC-V 開發工作,今天就教大傢如何在優麒麟上搭建 RISC-V 交叉編譯環境,快學起來吧!

交叉編譯(Cross Compile)指編譯代碼的平臺,和執行編譯後源代碼的平臺是兩個不同的平臺,比如在 x86/Linux 平臺下使用交叉編譯工具鏈編譯 ARM/Linux 平臺下的可執行文件。今天我們要講的就是在優麒麟(x86/Linux)上編譯 RISC-V 架構可執行文件的方法。

我們為什麼需要交叉編譯呢,主要有以下考慮:

01.性能與速度

交叉編譯的目標平臺往往 CPU 性能較差,內存和磁盤性能也可能不能滿足編譯的要求,這時候就要依賴性能資源更好的編譯主機進行編譯。

02.缺乏編譯條件

就算目標平臺性能足夠且資源充足,可以本地編譯,但第一個在目標平臺運行的本地編譯器總是需要我們通過交叉編譯獲得。

03.軟件編譯環境

一個完整的 Linux 發行版需要由數百個包構成,而我們往往隻關註需要在目標主機上安裝的包,所以我們可以在交叉編譯的主機上配置這些環境,而不是把時間浪費在配置目標主機的編譯依賴上。

本文包含以下兩部分:

1、如何搭建一個 RISC-V 的交叉編譯環境。

2、交叉編譯 Linux 內核。

一、搭建 RISC-V 交叉編譯環境。

通常來講,在搭建交叉編譯環境時需要考慮不同體系架構的不同特性,包括 CPU 架構是 64 位還是 32 位系統、字節序是大端( big-endian )或小端( little-endian )、內存字節對齊方式等,不過好在 RISC-V 已經有完善的工具鏈,包含交叉編譯所需的 binutils 、 gcc 和 glibc 3 個部分。

● 首先需要 RISC-V 交叉編譯工具鏈,如果網絡較慢,可以忽略其中的 qemu 子項目

git clone --recursive https://github.com/riscv/riscv-gnu-toolchain

這是 RISC-V 的 C/C++ 交叉編譯工具鏈,其支持兩種構建模式:

1. 通用 ELF/Newlib 工具鏈

2. Linux-ELF/glibc 工具鏈

● 安裝所需依賴包

sudo apt-get install -y 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 libncurses-dev device-tree-compiler libssl-dev gdisk swig

● 接下來開始編譯

cd riscv-gnu-toolchain
./configure --prefix=/opt/riscv(路徑可以根據個人習慣自定義)
sudo make linux -j `nproc`

編譯完成後,剛才指定的路徑 opt/riscv/bin 下會生成以下文件:

交叉編譯所需的工具,包括 Binutils(ld,as,ar 等,瞭解詳情可參考https://sourceware.org/binutils/docs-2.37/binutils/index.html )、gcc 、gdb 等都在其中。

可以將這個路徑添加到環境變量中:

export PATH=/opt/riscv/bin:$PATH

也可以添加到:

echo "export PATH=/opt/riscv/bin:$PATH" >> ~/.bashrc

到這裡我們就完成瞭交叉編譯所需環境的搭建。

二、編譯 Linux 內核

接下來我們以內核源碼為例,瞭解一下上述交叉編譯工具鏈的使用方法。

● 首先下載內核源碼

git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git

● 不過這裡下載較慢,可以去國內的鏡像站下載,比如清華大學鏡像站

git clone https://mirrors.tuna.tsinghua.edu.cn/git/linux-stable.git

● 下載完成後

git checkout

接下來將需要打上你想要編譯的開發板的 patch ,以 hifive unmatched 為例

● 首先下載

git clone https://github.com/sifive/meta-sifive

這裡面還包含瞭編譯 OpenSBI 和 U-Boot 所需的 patch ,編譯過程大同小異,如果想要自己構建一個系統鏡像,可以分別編譯這兩個工具。這裡以內核為例:

● 打上所有 patch

for f in path to /meta-sifive/recipes-kernel/linux/files/*.patch; do echo $f;patch -p1 < $f;done

● 復制 defconfig 配置文件

cp path to /meta-sifive/recipes-kernel/linux/files/defconfig  ./.config

如果想避免產生額外後綴名,可以添加

touch .scmversion

接下來開始編譯內核,這裡需要指定 make 的兩個參數:

1、CROSS_COMPILE:交叉編譯器的前綴,表示將代碼編譯編譯成目標CPU指令的工具,如果不指定,make 會默認使用系統自帶的 gcc 來編譯,這裡指定我們之前編譯出來的 riscv64-unknown-linux-gnu- 為前綴。

2、ARCH:即 architecture ,用於選擇編譯哪種 CPU 架構,也就是編譯 arch/ 目錄下的哪個子目錄,這裡指定 ARCH=riscv ,arch/riscv 目錄下也包含此架構特有的 Kconfig 配置文件,所以 make menuconfig 時也會用到這個目錄。

make CROSS_COMPILE=riscv64-unknown-linux-gnu- ARCH=riscv olddefconfig
make CROSS_COMPILE=riscv64-unknown-linux-gnu- ARCH=riscv -j`nproc`

也可以將內核和內核模塊打成 tar 包或 deb 包

make CROSS_COMPILE=riscv64-unknown-linux-gnu- ARCH=riscv    INSTALL_MOD_STRIP=1 -j`nproc` tarbz2-pkg
make CROSS_COMPILE=riscv64-unknown-linux-gnu- ARCH=riscv INSTALL_MOD_STRIP=1 -j`nproc` bindeb-pkg

添加版本號

version=`cat include/config/kernel.release`;echo $version

編譯完成後,會生成 path to/arch/riscv/boot/Image 內核鏡像文件和 path to/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dtb 硬件 dtb 文件。

如果選擇打成 deb 包,會生成三個 .deb 文件:

1. linux-headers-…

2. linux-libc-dev_…

3. linux-image-…

(其中省略號表示版本號)

到這裡我們就完成瞭 RISC-V 架構 Linux 內核的編譯,接下來便可以基於這個內核制作自己的系統鏡像。

各位小夥伴,你學會瞭嗎?

參考文檔:

https://github.com/carlosedp/riscv-bringup/tree/bbef412a4456acefdf814a9e14a75ce2778992ed/unmatched#build-u-boot

https://github.com/sifive/meta-sifive/tree/2021.12/recipes-kernel/linux/files

https://github.com/riscv-collab/riscv-gnu-toolchain

https://github.com/sifive/freedom-u-sdk

到此這篇關於手把手教你在優麒麟上搭建 RISC-V 交叉編譯環境的文章就介紹到這瞭,更多相關優麒麟搭建RISC-V環境內容請搜索GuideAH以前的文章或繼續瀏覽下面的相關文章,希望大傢以後多多支持GuideAH!