GDB+QEMU 调试 64 位 RISC-V LINUX ¶
约 798 个字 29 行代码 预计阅读时间 3 分钟
Abstract
计算机系统 Ⅱ lab3 实验报告(2022.10.27 ~ 2022.11.10)
Warning
仅供学习参考,请勿抄袭
实验内容 ¶
- 搭建实验环境
- 安装 risc-v 工具链和 qemu 模拟器
- 获取 Linux 源码和已经编译好的文件系统
- 从 kernel.org 下载最新的 Linux 源码
- 从课程仓库克隆文件系统镜像
- 编译 Linux 内核
- 使用 QEMU 运行内核
- 使用 GDB 对内核进行调试
- 思考题
- 使用 riscv64-linux-gnu-gcc 编译单个 .c 文件
- 使用 riscv64-linux-gnu-objdump 反汇编前面得到的编译产物
- 调试 Linux 时:
- 在 GDB 中查看汇编代码
- 在 0x80000000 处下断点
- 查看所有已下的断点
- 在 0x80200000 处下断点
- 清除 0x80000000 处的断点
- 继续运行直到触发 0x80200000 处的断点
- 单步调试一次
- 退出 QEMU
- 学习 Makefile 的基本使用
- 观察可用的 target,应该使用 make ? 来清除 Linux 的构建产物?
- 默认情况下,内核编译显示的是简略信息(例如:CC init/main.o
) ,应该使用 make ? 来显示 Linux 详细的编译过程呢?
环境搭建 ¶
安装 risc-v 工具链和 qemu 模拟器 ¶
命令行运行:
检查版本:安装其它后续需要的软件包 ¶
Ubuntu 不自带 make、gcc 等工具,需要手动安装:
在后面编译内核的过程中会出现 /bin/sh: 1: flex: not found 以及 bison: not found 的错误,需要安装 flex 和 bison:
获取、编译源码 ¶
获取 Linux 源码 ¶
在 kernel.org 上查找源码,选择 6.0.5 版本下载(6.1 版本中含有 rust,不选)并解压:
克隆课程仓库:
编译 Linux 内核 ¶
进入解压后的 Linux 源码文件夹,进行编译:
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- defconfig
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- -j4
运行、调试内核 ¶
使用 QEMU 运行内核 ¶
进入 sys2lab-22fall-stu/src/lab3 目录中,运行:
qemu-system-riscv64 -nographic -machine virt \
-kernel ~/Desktop/linux-6.0.5/arch/riscv/boot/Image \
-device virtio-blk-device,drive=hd0 \
-append "root=/dev/vda ro console=ttyS0" \
-bios fw_jump.bin -drive file=rootfs.img,format=raw,id=hd0
然后 exit 退出 shell,Ctrl+A、X 退出 QEMU。
使用 GDB 调试内核 ¶
在一个终端运行下面命令启用一个内核并等待调试:
qemu-system-riscv64 -nographic -machine virt \
-kernel ~/Desktop/linux-6.0.5/arch/riscv/boot/Image \
-device virtio-blk-device,drive=hd0 \
-append "root=/dev/vda ro console=ttyS0" \
-bios fw_jump.bin -drive file=rootfs.img,format=raw,id=hd0 \
-S -s
查看汇编、查看寄存器值、单指令运行:
查看帧栈信息:
layout asm(使用 Ctrl+X、A 退出
思考题 ¶
编译 c 语言文件并反汇编 ¶
和系统一中的实验一样,使用 riscv64-linux-gnu-gcc 编译、-objdump 反汇编即可。源文件:
先静态编译(方便运行),然后动态编译并使用 objdump 反汇编:调试 Linux ¶
查看汇编、在 0x80000000 下断点、查看断点、在 0x80200000 下断点、取消 0x80000000 处的断点、继续运行:
Makefile 相关 ¶
- 观察可用的 target,应该使用 make ? 来清除 Linux 的构建产物?
应该使用 make clean 来清除构建产物
- 默认情况下,内核编译显示的是简略信息(例如:CC init/main.o
) ,应该使用 make ? 来显示 Linux 详细的编译过程呢?
make help 可以看到:
make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build
make V=2 [targets] 2 => give reason for rebuild of target
最后更新:
2022年11月29日 15:52:39
创建日期: 2022年11月29日 15:52:39
创建日期: 2022年11月29日 15:52:39