1. 前言
限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。
2. 测试环境
本文使用 Ubuntu 16.04.4 LTS + QEMU
环境进行调试。
3. 用 GDB 调试 QEMU 内程序
3.1 编写用来调试的程序
我们用 ARM32
来进行调试,下面是用来测试的程序代码:
/*
* start.S
*/
.text
.global _start
_start:
mov r0, #8
1:
b 1b
编译用的 Makefile
:
CROSS_COMPILE ?= arm-linux-gnueabi-
CC := ${CROSS_COMPILE}gcc
LD := ${CROSS_COMPILE}gcc
.PHONY: all clean
all: test.elf
test.elf: start.S
$(CC) -nostdlib -g -o $@ $<
clean:
-rm -fr test.elf
3.2 工具安装
3.2.1 安装 arm-linux-gnueabi-gcc
sudo apt-get install gcc-arm-linux-gnueabi
3.2.2 安装 gdb
sudo apt install gdb-multiarch
gdb-multiarch
支持多种目标架构,另外一种选择是交叉编译 ARM 平台的 gdb ,本篇不做展开。
3.2.3 安装 qemu
sudo apt-get install qemu
3.3 编译和调试
3.3.1 编译
将 start.S
和 Makefile
放在同一目录下,然后运行:
make
将在目录下生成 test.elf
文件。
3.3.2 调试
我们调试程序,需要启动两个终端。第一个终端,QEMU
模拟 ARM 开发板 vexpress-a9
环境,用来运行程序 test.elf
:
sudo qemu-system-arm \
-M vexpress-a9 -m 512M \
-kernel test.elf -S -s -nographic
其中 -s
选项告诉 qemu-system-arm
启动内置的 gdb-server
,监听在 TCP 端口 1234
上;-S
选项告诉 qemu-system-arm
不要启动程序执行,等待 gdb
的指令。目前程序 test.elf 处于停止状态, qemu-system-arm
等待 gdb 客户端连接它,发送进一步的指令。现在用 gdb
连接 qemu-system-arm
:
$ gdb-multiarch test.elf
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test.elf...done.
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
_start () at start.S:5
5 mov r0, #8
(gdb) info registers
r0 0x0 0
r1 0x0 0
r2 0x0 0
r3 0x0 0
r4 0x0 0
r5 0x0 0
r6 0x0 0
r7 0x0 0
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x0 0
r12 0x0 0
sp 0x0 0x0
lr 0x0 0
pc 0x10098 0x10098 <_start>
cpsr 0x400001d3 1073742291
(gdb)
现在我们可以用 gdb
来调试程序 test.elf
了。当前状况下,gdb
和 qemu-system-arm
的关系可以用下图来描述:
-------------------------
| qemu-system-arm |
| ----------------- | -----
| | gdb-server:1234 |<---|-----> | gdb |
| ----------------- | -----
-------------------------
4. 用 gdb 调试内核
# 启动内核,等待 gdb 的连接
sudo qemu-system-arm \
-s -S \
-M vexpress-a9 -smp 4 -m 512M \
-kernel zImage -dtb vexpress-v2p-ca9.dtb \
-nographic \
-append "root=/dev/mmcblk0 rw rootfstype=ext4 console=ttyAMA0" -sd rootfs.img
# 调试内核
gdb-multiarch vmlinux
Linux 内核调试的细节可参考博文:Linux: 内核启动代码调试 。
5. 参考资料
https://www.qemu.org/docs/master/system/gdb.html