type
status
date
slug
summary
tags
category
icon
password
Build QEMU
- 安裝所需的套件:
- 下載 QEMU source codes:
git clone --recursive [email protected]:qemu/qemu.git
cd qemu
./configure --target-list=riscv64-softmmu,riscv32-softmmu,riscv64-linux-user,riscv32-linux-user
make -j
- 幾個好用的 debug configure 參數:
--extra-cflags=CFLAGS
:append extra C compiler flags QEMU_CFLAGS- e.g.
--extra-cflags="-g3 --save-temps"
--extra-ldflags=LDFLAGS
:append extra linker flags LDFLAGS--enable-debug-tcg
:enable TCG debugging--disable-debug-tcg
:disable TCG debugging (default)--disable-debug-info
:disable debugging information--enable-debug
:enable common debug build options--disable-strip
:disable stripping binaries--disable-werror
:disable compilation abort on warning--enable-pie
:build Position Independent Executables--disable-pie
:do not build Position Independent Executables
- 幾個好用的執行參數:
-d item1,...
:enable logging of specified items-D logfile
:output log to logfile (default stderr)
Build RISC-V toolchains
- 安裝所需的套件:
- 下載 toolchains source codes:
git clone --recursive
[email protected]
:riscv/riscv-gnu-toolchain.git
cd riscv-gnu-toolchain
- Install:
- Newlib:
./configure --prefix=/opt/riscv
make
- Linux:
./configure --prefix=/opt/riscv
make linux
- 將 RISC-V toolchain binary 路徑加入
PATH
環境變數: export PATH=/opt/riscv/bin:$PATH
Build Buildroot
- 下載 Buildroot source codes:
git clone
[email protected]
:buildroot/buildroot.git
make qemu_riscv64_virt_defconfig menuconfig
- 如果不想由 bulidroot 編譯 Linux Kernel:
- 取消勾選:Kernel → Linux Kernel (
BR2_LINUX_KERNEL
) - 如果不想由 bulidroot 編譯 OpenSBI:
- 取消勾選:Bootloaders → opensbi (
BR2_TARGET_OPENSBI
) - 如果不想由 bulidroot 編譯 U-Boot:
- 取消勾選:Bootloaders →U-Boot (
BR2_TARGET_UBOOT
) - 如果不想由 buildroot 編譯 QEMU:
- 取消勾選:Host utilities → host qemu (
BR2_PACKAGE_HOST_QEMU
) - 如果想使用自行編譯的 toolchain:
- Toolchain →Toolchain type → 選擇:External toolchain (
BR2_TOOLCHAIN_EXTERNAL
) - Toolchain → Toolchain → 選擇:Custom toolchain (
BR2_TOOLCHAIN_EXTERNAL_CUSTOM
) - Toolchain → Toolchain origin → 選擇:Pre-installed toolchain (
BR2_TOOLCHAIN_EXTERNAL_PREINSTALLED
) - 設置 toolchain 的路徑:
- Toolchain → Toolchain path (
BR2_TOOLCHAIN_EXTERNAL_PATH
): - e.g.
/home/yihaoc/workspace/toolchains/c-gnu-toolsuite-17.9.0-2023.10.1-rc1-x86_64-linux-ubuntu14
- 設置 toolchain 的 prefix:
- Toolchain → Toolchain prefix (
BR2_TOOLCHAIN_EXTERNAL_CUSTOM_PREFIX
): - e.g.
$(ARCH)-unknown-linux-gnu
- 此外,還需根據所使用的 toolchain 設定其他的選項:
- 選擇 toolchain 的 gcc 版本:
- Toolchain → External toolchain gcc version:
- e.g.
13.x
(BR2_TOOLCHAIN_EXTERNAL_GCC_13
) - 選擇 toolchain 的 Kernel headers series:
- Toolchain → External toolchain kernel headers series:
- e.g.
6.2.x
(BR2_TOOLCHAIN_EXTERNAL_HEADERS_6_2
) - 選擇 toolchain 的 C library:
- Toolchain → External toolchain C library:
- e.g.
glibc
(BR2_TOOLCHAIN_EXTERNAL_CUSTOM_GLIBC
) - 選擇 toolchain 是否支援 RPC:
- Toolchain → Toolchain has RPC support? (
BR2_TOOLCHAIN_EXTERNAL_INET_RPC
) - SiFive toolchain → No
- 選擇 toolchain 是否支援 C++:
- Toolchain → Toolchain has C++ support? (
BR2_TOOLCHAIN_EXTERNAL_CXX
) - SiFive toolchain → Yes
- 選擇 toolchain 是否支援 Fortran:
- Toolchain → Toolchain has Fortran support? (
BR2_TOOLCHAIN_EXTERNAL_FORTRAN
) - SiFive toolchain → Yes
- 選擇 toolchain 是否支援 OpenMP:
- Toolchain → Toolchain has OpenMP support?(
BR2_TOOLCHAIN_EXTERNAL_OPENMP
) - SiFive toolchain → Yes
- 如果想使用 initramfs:
- 勾選:Filesystem images →cpio the root filesystem (for use as an initial RAM filesystem) (
BR2_TARGET_ROOTFS_CPIO
) - 編譯 rootfs 以及選擇 rootfs 的格式:
- Filesystem images → ext2/3/4 root filesystem (
BR2_TARGET_ROOTFS_EXT2
) - Filesystem images → ext2/3/4 root filesystem → ext2/3/4 variant:
- e.g. ext4 (
BR2_TARGET_ROOTFS_EXT2_4
)
make -j
Build Busybox
- 下載 Busybox source codes:
git clone
[email protected]
:mirror/busybox.git
- 編譯 Busybox:
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- menuconfig
- 勾選:
Settings
→Build static binary (no shared libs)
(CONFIG_STATIC)
,以 statically linked 的方式編譯 Busybox - 若無勾選,則預設會採用 dynamic linked 的方式編譯 Busybox,在建立 rootfs 的時候需要將所需的 library files 複製至 libs 資料夾,否則 Linux Kernel boot up 的時候會出現:
kernel panic - not syncing: No working init found.
的錯誤訊息 (此訊息不一定是代表init
檔案找不到,無法正確執行init
程式亦會顯示同樣的錯誤訊息)。 make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- -j
- 將 Busybox 安裝至
_install
資料夾: make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- install
Build rootfs from busybox (if rootfs is not built in Linux Kernel image)
- 建立大小為 10 MB 的 disk image:
dd if=/dev/zero of=root.ext2 bs=1M count=10
- 將 disk image 格式化為
ext2
格式: mkfs.ext2 -F root.ext2
- 掛載 rootfs:
mkdir rootfs
sudo mount root.ext2 rootfs
cd rootfs
- 複製 Busybox 至 rootfs:
sudo cp -r ../busybox/_install/* .
- (假設 Busybox 的路徑為:
../busybox
)
- 建立所需的資料夾:
sudo mkdir etc dev proc sys tmp
- 建立
etc/inittab
檔:
- 建立所需的裝置檔案:
sudo mknod dev/console c 5 1
sudo mknod dev/null c 1 3
- 解除掛載:
cd .. && sudo umount rootfs
Bulid OpenSBI
- 下載 OpenSBI source codes:
git clone
[email protected]
:riscv-software-src/opensbi.git
make CROSS_COMPILE=riscv64-unknown-elf- PLATFORM=generic -j
Build U-Boot
- 下載 U-Boot source codes:
git clone
[email protected]
:u-boot/u-boot.git
- TODO
Build Linux Kernel
- 下載 Linux Kernel source codes:
git clone
[email protected]
:torvalds/linux.git
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- menuconfig
- 如果要使用 initramfs,且將 rootfs 直接編譯至核心中,則需:
- 勾選:General setup → Initial RAM filesystem and RAM disk (initramfs/initrd) support (
CONFIG_BLK_DEV_INITRD
) - 並設置 initramfs rootfs 路徑 (
CONFIG_INITRAMFS_SOURCE
) - e.g.
/home/yihaoc/frankchang/buildroot/output/images/rootfs.cpio
- 如果想包含 debug symbols:
- 開啟 Kernel debugging:
- Kernel hacking → Kernel debugging (
DEBUG_KERNEL
) - 選擇 DWARF debug info 版本:
- Kernel hacking → Compile-time checks and compiler options → Debug information
- e.g. Rely on the toolchain’s implicit default DWARF version (
DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT
) - 如果想要包含 devmem:
- Device Drivers → Character devices → /dev/mem virtual device support (
CONFIG_DEVMEM
) - 切換 Compiler optimization level 為 Optimize for size (
-Os
) - 勾選:General setup →Compiler optimization level → Optimize for size (-Os) (
CONFIG_CC_OPTIMIZE_FOR_SIZE
)
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- -j
Boot QEMU with Linux Kernel and rootfs
Method 1: rootfs built-in in Linux Kernel image:
- (假設 QEMU 執行檔的路徑為:
./qemu/build/qemu-system-riscv64
)
- (假設 OpenSBI image 的路徑為:
./opensbi/build/platform/generic/firmware/fw_jump.elf
)
- (假設 Linux Kernel image 的路徑為:
./linux/arch/riscv/boot/Image
)
Method 2: Load rootfs from disk:
- (假設 QEMU 執行檔的路徑為:
./qemu/build/qemu-system-riscv64
)
- (假設 OpenSBI image 的路徑為:
./opensbi/build/platform/generic/firmware/fw_jump.elf
)
- (假設 Linux Kernel image 的路徑為:
./linux/arch/riscv/boot/Image
)
- (假設 rootfs disk image 的路徑為:
./images/root.ext2
)
Debug Linux Kernel with GDB with QEMU
- Linux Kernel 需要勾選:
Kernel hacking
→Kernel debugging
(CONFIG_DEBUG_KERNEL)
Kernel hacking
→Compile-time checks and compiler options
→Compile the kernel with debug info
(CONFIG_DEBUG_INFO)
Kernel hacking
→Compile-time checks and compiler options
→Provide GDB scripts for kernel debugging
(CONFIG_GDB_SCRIPTS)
- 啟動 QEMU:
-S
:Freeze CPU at startup (use 'c' to start execution).-s
:Shorthand for-gdb tcp::1234
.-gdb dev
:Wait for gdb connection ondev
.
- 使用 GDB debug Linux Kernel:
- 使用 CGDB debug Linux Kernel:
- References:
Debug QEMU
- 編譯 QEMU:
./configure --target-list=riscv64-softmmu --enable-debug
./configure --target-list=riscv64-softmmu --enable-debug --extra-cflags="-g3 --save-temps" --extra-ldflags="-g3" --disable-strip --disable-pie
- 使用 GDB:
- 使用 CGDB:
GDB / CGDB
Build bbl (Berkery Boot Loader)
- 下載 riscv-pk source codes:
git clone
[email protected]
:riscv/riscv-pk.git
cd riscv-pk
mkdir build
cd build
../configure --enable-logo --with-payload=../../linux/vmlinux --host=riscv64-unknown-linux-gnu
- (假設 Linux Kernel vmlinux 的路徑為:
../../linux/vmlinux
)
make -j
P.S. 如果要使用 BBL 開機的話,QEMU 的 -kernel 參數要指定 BBL image:
e.g.
-kernel ./riscv-pk/build/bbl
- (假設 bbl 的路徑為:
./riscv-pk/build/bbl
)
- References: