Archlinux使用qemu调试内核
1. 编译RISC-V内核
- 安装qemu
sudo pacman -S qemu-full
- 下载编译链 可以在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
- 解压编译链
tar -xvf riscv64-lp64d--glibc--stable-2022.08-1.tar.bz2
- 安装开发工具
//编译kernel需要
sudo pacman -S base-devel bc
//编译buildroot需要
sudo pacman -S cpio unzip rsync
- 下载内核
wget http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/v5.x/linux-5.10.7.tar.gz
- 解压内核
tar -xvf linux-5.10.7.tar.gz
- 设置编译环境变量
export PATH=/home/modao/Desktop/qemu/riscv64-lp64d--glibc--stable-2022.08-1/bin:$PATH
export ARCH=riscv
export CROSS_COMPILE=riscv64-linux-
- 编译内核
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重复编译。
- 下载buildroot
git clone https://ghproxy.com/https://github.com/buildroot/buildroot.git
- 生成buildroot默认配置
cd buildroot/
make qemu_riscv64_virt_defconfig
- 修改配置
make menuconfig
这里需要修改两个部分:
- 修改使用本地的交叉编译工具链 需要确定下载的编译链版本号:
cd riscv64-lp64d--glibc--stable-2022.08-1/bin
./riscv64-linux-gcc --version
还需要确定内核版本号,交叉编译器类型(glibc)。
选择toolchain
选项,并修改图中用红框标出的部分,其中Toolchain path
需要修改为工具链的绝对地址。
- 取消编译内核 选择
kernel
再把Linux Kernel
选项取消选中。
- 编译
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