1. 编译RISC-V内核

  1. 安装qemu
sudo pacman -S qemu-full
  1. 下载编译链 可以在https://toolchains.bootlin.com/下载交叉编译工具链,需要对指令集架构和libc进行选择,这里使用riscv 64和glibc,点击Download stable即可下载。也可以wget下载。
wget https://toolchains.bootlin.com/downloads/releases/toolchains/riscv64-lp64d/tarballs/riscv64-lp64d--glibc--stable-2022.08-1.tar.bz2
  1. 解压编译链
tar -xvf riscv64-lp64d--glibc--stable-2022.08-1.tar.bz2
  1. 安装开发工具
//编译kernel需要
sudo pacman -S base-devel bc
//编译buildroot需要
sudo pacman -S cpio unzip rsync
  1. 下载内核
wget http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/v5.x/linux-5.10.7.tar.gz
  1. 解压内核
tar -xvf linux-5.10.7.tar.gz
  1. 设置编译环境变量
export PATH=/home/modao/Desktop/qemu/riscv64-lp64d--glibc--stable-2022.08-1/bin:$PATH
export ARCH=riscv
export CROSS_COMPILE=riscv64-linux-
  1. 编译内核
make defconfig
make menuconfig

编译完成后,最后生成的Kernel文件在linux/arch/riscv/boot/Image

在执行 make menuconfig 命令时需要对内核配置进行修改,打开调试开关:

  • 选择kernel hacking选项,进入以后继续选择compile-time checks and compile options, 然后选择compile the kernel with debug info
  • 选择save, 就可以把这个信息保存到.config中

至此,一个可调试的内核就编译好了

2. 使用buildroot制作根文件系统

buildroot可以一键编译内核,根文件系统,配置好相应的qemu启动脚本等。由于上面已经下载了工具链并编译好了内核,所以不再buildroot重复编译。

  1. 下载buildroot
git clone https://ghproxy.com/https://github.com/buildroot/buildroot.git
  1. 生成buildroot默认配置
cd buildroot/
make qemu_riscv64_virt_defconfig
  1. 修改配置
make menuconfig

这里需要修改两个部分:

  1. 修改使用本地的交叉编译工具链 需要确定下载的编译链版本号:
cd riscv64-lp64d--glibc--stable-2022.08-1/bin
./riscv64-linux-gcc --version

还需要确定内核版本号,交叉编译器类型(glibc)。

选择toolchain选项,并修改图中用红框标出的部分,其中Toolchain path需要修改为工具链的绝对地址。

  1. 取消编译内核 选择kernel再把Linux Kernel选项取消选中。

  1. 编译
make -j8

其中:rootfs.ext2 是根文件系统,start-qemu.sh 是启动qemu的脚本,

fw_*是OpenSBI支持的固件

  • fw_dynamic固件:带有动态信息的固件
  • fw_jump固件:指定下一引导阶段的跳转地址,不直接包含下一阶段的二进制代码
  • fw_payload固件:包含下一引导阶段有效负载的二进制代码,通常这个有效负载是bootloader或者操作系统镜像

3. 在qemu中启动内核

修改buildroot编译生成的start-qemu.sh脚本,需要修改Image为Image的实际地址(内核镜像的绝对路径):

启动qemu:

sudo ./start-qemu.sh

默认登陆账号:root 关闭qemu:poweroff

内核gdb调试

开启gdb需要在原始的qemu脚本中加入-gdb tcp::1234 -S

#!/bin/sh

BINARIES_DIR="${0%/*}/"
# shellcheck disable=SC2164
cd "${BINARIES_DIR}"

mode_serial=false
mode_sys_qemu=false
while [ "$1" ]; do
    case "$1" in
    --serial-only|serial-only) mode_serial=true; shift;;
    --use-system-qemu) mode_sys_qemu=true; shift;;
    --) shift; break;;
    *) echo "unknown option: $1" >&2; exit 1;;
    esac
done

if ${mode_serial}; then
    EXTRA_ARGS='-nographic'
else
    EXTRA_ARGS=''
fi

if ! ${mode_sys_qemu}; then
    export PATH="/home/modao/Desktop/qemu/buildroot/output/host/bin:${PATH}"
fi

exec qemu-system-riscv64 -M virt -bios fw_jump.elf -kernel /home/modao/Desktop/qemu/linux-5.10.7/arch/riscv/boot/Image -gdb tcp::1234 -S -append "rootwait root=/dev/vda ro" -drive file=rootfs.ext2,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -netdev user,id=net0 -device virtio-net-device,netdev=net0 -nographic  ${EXTRA_ARGS} "$@"

gdb脚本:

#!/bin/bash
export PATH=/home/modao/Desktop/qemu/riscv64-lp64d--glibc--stable-2022.08-1/bin:$PATH

cd /home/modao/Desktop/qemu/linux-5.10.7

riscv64-linux-gdb -ex "target remote:1234" vmlinux

需要注意的是:一定不能把vmlinux从linux kernel编译出来的位置拷贝出来 所以脚本里添加了cd 操作。

先启动qemu脚本,再启动gdb脚本,就可以对内核进行调试了。

报错:

riscv64-linux-gdb: error while loading shared libraries: libcrypt.so.1: cannot open shared object file: No such file or directory

解决方法:

sudo pacman -S libxcrypt-compat

链接:https://www.zhihu.com/question/66594120/answer/3016043997