有了qemu后我们可以使用一台电脑就能模拟出多种cpu架构的单板,不需要去进行重复复杂的编译烧写调试工作了,提高开发的效率。
一、主机环境
vmware或者hyper-v安装ubuntu20.04
二、gdb安装
这里我们直接用gdb-multiarch(可以支持多种cpu架构的gdb调试工具,不需要重复的安装各种xxx-linux-gdb了,通过set architecture命令切换不同架构的cpu即可)
sudo apt-get install gdb-multiarch
三、编译kernel和rootfs
注意配置kernel config时打开:
Kernel hacking --->Compile-time checks and compiler options --->[ ] Compile the kernel with debug info
这里我们用vexpress单板做例子,文中修改的命令都基于vexpress。
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- vexpress_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- all -j4
调试运行
linux 上和windows上的命令其实是一样的,如果windows上安装了qemu也是可以直接用的。
Host终端1上执行qemu模拟vexpress-a9开发板:
sudo qemu-system-arm -M vexpress-a9 -m 512M -nographic -dtb linux-5.10.1/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -kernel linux-5.10.1/arch/arm/boot/zImage \
-append "console=ttyAMA0,115200 init=/sbin/init root=/dev/vda rw ip=dhcp" \
-drive format=raw,if=none,file=debian.img,id=ha,index=0 -device virtio-blk-device,drive=ha -s -S
# -s 等价于 -gdb tcp::1234 表示监听 1234 端口,用于 gdb 连接,可以用-gdb tcp::xxxx 取代默认的1234端口
# -S 表示加载后立即暂停,等待调试指令。不设置这个选项内核会直接执行
Host终端2上执行gdb调试:
gdb-multiarch linux-5.10.1/vmlinux
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
Copyright (C) 2020 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 linux-5.10.1/vmlinux...
(gdb) set architecture arm
The target architecture is assumed to be arm
(gdb) target remote:1234
Remote debugging using :1234
0x60000000 in ?? ()
(gdb) b start_kernel
Breakpoint 1 at 0x80a00960: file init/main.c, line 849.
(gdb) c
Continuing.
Breakpoint 1, start_kernel () at init/main.c:849
849 {
(gdb)
主要的流程打通后我们就可以快速的进行源码级的debug了。
扩展问题
调试内核需要确保如下配置
开启CONFIG_GDB_SCRIPTS和CONFIG_FRAME_POINTER(如果存在),关闭CONFIG_DEBUG_INFO_REDUCED和CONFIG_RANDOMIZE_BASE。
如果gdb无法断点可以尝试使用emulator后面添加qemu参数-append nokaslr,并用hb 命令添加硬件断点。