繁体   English   中英

如何使用QEMU和KGDB调试Linux内核?

[英]How to debug the Linux kernel with QEMU and KGDB?

我已经能够使用以下方式启动基于powerpc的系统(MPC8544DS具体)来调用qemu(v1.7.0)

qemu-system-ppc -M mpc8544ds -m 512 -kernel zImage -s -nographic -initrd busyboxfs.img -append "root=/dev/ram rdinit=/bin/sh kgdboc=ttyS0,115200 kgdbwait"

其中zImage是一个自定义交叉编译的Linux内核(v2.6.32),它启用并编译了KGDB(用于启动代码调试), busyboxfs.img是基于busybox的rootfs。

因为我正在使用-s标志到Qemu,所以我可以使用交叉gdb进入内核,如下所示:

(gdb) target remote localhost:1234
Remote debugging using localhost:1234
mem_serial_in (p=<value optimized out>, offset=5) at drivers/serial/8250.c:405
405  }

但是,如果我删除-s标志并尝试通过/dev/ttyS0闯入内核,它会给我一个权限被拒绝错误:

(gdb) set remotebaud 115200
(gdb) target remote /dev/ttyS0
permission denied 

是因为它被Qemu控制了吗? 另外在互联网上的示例中,kgdboc已经设置为ttyAMA0 ,我已经理解为代表基于ARM的系统的AMBA总线。 我们有类似PowerPC的东西吗? 我在这里做错了吗?

KGDB + QEMU一步一步

首先,QEMU的-gdb选项比KGDB强大得多,所以您可能想要使用它: 如何使用GDB和QEMU调试Linux内核? 然而,QEMU是一种简单的方法来使用KGDB来准备真正的硬件。 我已经发布了一些Raspberry Pi KGDB指针: Linux内核实时调试,它是如何完成的以及使用了什么工具?

如果你想从头开始快速入门,我在以下网址制作了一个最小的全自动Buildroot示例: https//github.com/cirosantilli/linux-kernel-module-cheat/tree/d424380fe62351358d21406280bc7588d795209c#kgdb

主要步骤是:

  1. 用以下内容编译内核:

     CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_INFO=y CONFIG_CONSOLE_POLL=y CONFIG_KDB_CONTINUE_CATASTROPHIC=0 CONFIG_KDB_DEFAULT_ENABLE=0x1 CONFIG_KDB_KEYBOARD=y CONFIG_KGDB=y CONFIG_KGDB_KDB=y CONFIG_KGDB_LOW_LEVEL_TRAP=y CONFIG_KGDB_SERIAL_CONSOLE=y CONFIG_KGDB_TESTS=y CONFIG_KGDB_TESTS_ON_BOOT=n CONFIG_MAGIC_SYSRQ=y CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 CONFIG_SERIAL_KGDB_NMI=n 

    其中大部分都不是强制性的,但这是我测试过的。

  2. 添加到您的QEMU命令:

     -append 'kgdbwait kgdboc=ttyS0,115200' \\ -serial tcp::1234,server,nowait 
  3. 使用以下命令从Linux内核源代码树的根目录运行GDB:

     gdb -ex 'file vmlinux' -ex 'target remote localhost:1234' 
  4. 在GDB中:

     (gdb) c 

    并且靴子应该完成。

  5. 在QEMU:

     echo g > /proc/sysrq-trigger 

    并且GDB应该打破。

  6. 现在我们完成了,您可以像往常一样使用GDB:

     b sys_write c 

在Ubuntu 14.04中测试过。

无法让它发挥作用。 可能与以下内容有关: 如何在ARM上使用kgdb?

您似乎混淆了guest虚拟机的主机串行设备/ dev / ttyS0,以及客户机内核中QEMU自己的KGDB gdbserver。

QEMU通常没有理由触摸主机的串口。 这样做的唯一原因是,如果您想拥有一台物理机主机QEMU,并有效地将其物理串口提供给客户机,那么您就可以使用通过实际串行电缆连接的不同物理机来调试客人。

当您使用-s标志时,您告诉QEMU运行自己的GDB服务器(默认情况下侦听主机环回TCP端口1234),允许您进入客户端上运行的任何程序, 无论是内核还是引导程序或其他内容。 这与guest虚拟机内核本身配合通过KGDB进行调试不同。

如果你想使用KGDB,你需要在内核版本中配置KGDB以使用模拟串行端口的客户端,然后告诉主机上的GDB使用该模拟端口的主机端。 QEMU命令行文档详细介绍了这一点:

调试/专家选项:

'-serial dev'将虚拟串行端口重定向到主机字符设备dev。 默认设备是图形模式下的vc和非图形模式下的stdio。

此选项可多次使用,以模拟最多4个串行端口。

一些更有趣的选项的缩略列表:

'pty'[仅限Linux] Pseudo TTY(自动分配新的PTY)

'/ dev / XXX'[仅限Linux]使用主机tty,例如'/ dev / ttyS0'。 主机串口参数根据模拟的参数设置。

这是您不想要的 - 除非您想将串行电缆用于运行GDB的其他物理机器。

'tcp:[host]:port [,server] [,nowait] [,nodelay]'TCP Net Console有两种操作模式。 它可以将串行I / O发送到某个位置或等待来自某个位置的连接。 默认情况下,TCP Net Console将发送到端口的主机。 如果使用服务器选项,QEMU将在继续之前等待客户端套接字应用程序连接到端口,除非指定了nowait选项。 nodelay选项禁用Nagle缓冲算法。 如果省略host,则假定为0.0.0.0。 一次只能接受一个TCP连接。 您可以使用telnet连接到相应的字符设备。

将tcp控制台发送到192.168.0.2端口4444 -serial tcp:192.168.0.2:4444的示例

在端口4444上侦听并等待连接-serial tcp :: 4444,server的示例

示例不等待并侦听ip 192.168.0.100端口4444 -serial tcp:192.168.0.100:4444,server,nowait

这是一个很好的常见选择。 您可以使用基本相同的GDB语法,例如,如果指定环回接口地址127.0.0.1和端口1234,则可以使用与以前完全相同的GDB命令。

'unix:path [,server] [,nowait]'使用unix域套接字而不是tcp套接字。 该选项的工作方式与指定-serial tcp的情况相同,只是unix域套接字路径用于连接。

假设您的GDB支持它,这也是一个不错的选择。

您可能需要首先配置其中一个选项,在没有KGDB的情况下运行并获取shell并确定调用模拟设备的客户端的内容,然后使用配置为使用它的KGDB重新启动。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM