概要
本文記搭建 RISCV 虛擬化環境的流程。
整體架構
我們使用 QEMU 來模擬 RISCV 的各種硬件擴展環境,通過 QEMU 啟動 Ubuntu 作為我們的 Host 來在 Host 之中通過 KVMTOOL 來運行 Guest,學習 RISCV 的虛擬化。
目前我的 X86_64 主機使用的是 Ubuntu 的 22.04 桌面版。具體如下:
Linux ovo-ovo 6.8.0-52-generic #53~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Jan 15 19:18:46 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
準備 Ubuntu 鏡像
打開終端,執行以下命令,下載鏡像。
wget https://old-releases.ubuntu.com/releases/22.04.4/ubuntu-22.04-preinstalled-server-riscv64+unmatched.img.xz
解壓縮系統鏡像文件然后擴個容。
xz -d ubuntu-22.04-preinstalled-server-riscv64+unmatched.img.xz
qemu-img resize ubuntu-22.04-preinstalled-server-riscv64+unmatched.img +20G
編譯 QEMU-v9.2.2
考慮到直接使用 apt 命令安裝的 QEMU 可能不支持 RISC-V 虛擬化擴展。所以直接下載源碼編譯。
安裝編譯前所需工具
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 ninja-build \libglib2.0-dev libfdt-dev libpixman-1-dev
# 根據 python 版本調整版本號
sudo apt-get install python3.12-venv
QEMU 的 user 用戶模式網絡配置需要 libslirp 的支持
下載 libslirp 源碼和編譯所需工具
git clone https://gitlab.freedesktop.org/slirp/libslirp.git
sudo apt install meson
libslirp 編譯,安裝
meson build
ninja -C build install
下載 QEMU 源碼
git clone https://gitee.com/popukey/qemu.git
切換到目標版本。
git checkout v9.2.2
編譯 RV64 架構下的 QEMU:qemu-system-riscv64
cd qemu && ./configure --target-list=riscv64-softmmu --enable-slirp && make -j 8
編譯結束之后生成的可執行文件位于 QEMU
目錄下的 build
目錄中。
把該路徑在 ~/.bashrc
文件最后寫入環境變量 PATH
。
export PATH="\$HOME/riscv64-qemu/qemu/build/:\$PATH"
source ~/.bashrc
確保修改生效。qemu-system-riscv64 --version
通過該命令驗證 QEMU 版本正確。
安裝最新 U-Boot 和 OpenSBI-v1.6
交叉編譯工具
編譯需要交叉編譯工具 riscv64-unknown-linux-gnu-gcc
,RISCV 倉庫中有編譯好的,這里我使用當前最新的會出錯,需要我更新 libc 到 2.38。遂放棄。使用低一點的版本。
wget https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2024.09.03/riscv64-glibc-ubuntu-22.04-gcc-nightly-2024.09.03-nightly.tar.gz
mkdir riscv
tar -xf riscv64-glibc-ubuntu-22.04-gcc-nightly-2024.09.03-nightly.tar.gz -C riscv --strip-components=1
把目錄加入 PATH 中,方便后續使用。把下面內容放入 ~/.bashrc
文件最末尾。
export PATH="$HOME/crossTools/riscv/bin/:$PATH"
確保修改生效。
source ~/.bashrc
U-boot
克隆 U-boot 項目并編譯。
git clone https://source.denx.de/u-boot/u-boot.git
cd u-boot
export ARCH=riscv
make CROSS_COMPILE=riscv64-unknown-linux-gnu- qemu-riscv64_smode_defconfig
make CROSS_COMPILE=riscv64-unknown-linux-gnu- -j 8
編譯之后的 u-boot 位于項目目錄下。
openSBI-v1.6
克隆 openSBI 項目并編譯。
git clone https://github.com/riscv-software-src/opensbi.git
cd opensbi && git checkout v1.6
make PLATFORM=generic CROSS_COMPILE=riscv64-unknown-linux-gnu- ARCH=riscv -j 8
編譯之后的內容位于 build/platform/generic/firmware/
目錄中。
qemu引導Linux
啟動 Linux
qemu-system-riscv64 -machine virt -nographic -m 8192 -smp 6 -bios opensbi/build/platform/generic/firmware/fw_jump.bin -kernel u-boot/u-boot -device virtio-net-device,netdev=eth0 -netdev user,id=eth0,hostfwd=tcp::6666-:22 -device virtio-rng-pci -drive file=./ubuntu-22.04-preinstalled-server-riscv64+unmatched.img,format=raw,if=virtio
此時,我們可以通過 ssh 命令 ssh -p 6666 ubuntu@localhost
登錄到 Linux,系統會立即要求更改密碼
# 默認用戶名和密碼
username: ubuntu
password: ubuntu
加載 kvm 模塊,并驗證
sudo modprobe kvm
此時應該會看到,系統目前沒有 KVM 模塊。
編譯升級 Linux 內核
依照上文方式用 QEMU 引導 RISCV 的內核之后,在 Host 中編譯。這種方式可能較慢。接下來的操作都在 Host 中進行。
安裝必要的工具:
sudo apt update
sudo apt install build-essential libncurses-dev bison flex libssl-dev libelf-dev fakeroot dwarves
下載內核源碼壓縮包。
這里下載版本 v6.13.7 并解壓縮。
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.13.7.tar.xz
tar -xf linux-6.13.7.tar.xz
cd linux-6.13.7/
拷貝配置文件并對配置文件做選擇性修改。
cp -v /boot/config-$(uname -r) .configmake localmodconfig
最后對配置文件做些修改,確保編譯過程順利。
scripts/config --disable SYSTEM_TRUSTED_KEYS
scripts/config --disable SYSTEM_REVOCATION_KEYS
scripts/config --set-str CONFIG_SYSTEM_TRUSTED_KEYS ""
scripts/config --set-str CONFIG_SYSTEM_REVOCATION_KEYS ""
開始編譯
fakeroot make -j8
查看結果,命令執行之后為 0 則一切正常。
echo $?
安裝內核模塊、更新用戶頭文件、安裝內核內核并重啟。
sudo make modules_install
sudo make headers_install INSTALL_HDR_PATH=/usr
sudo make install
sudo reboot
輸入命令驗證內核版本。
uname -rs
此時,我們再加載 kvm 模塊。并驗證在 dev 下有 kvm 這個設備文件存在。
sudo modprobe kvm
ls /dev/
下載最新 KVMTool
下載另外一個經常更新的 KVMTOOL 并編譯源碼。
sudo apt-get install libfdt-dev
git clone git://git.kernel.org/pub/scm/linux/kernel/git/will/kvmtool.git
cd kvmtool && make
小結
完結撒花!