如何用QEMU和KGDBdebuggingLinux内核?

我已经能够使用以下方式启动一个基于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 Kernel(v2.6.32),它已经启用并编译了KGDB(用于启动代码debugging),而busyboxfs.img是基于busybox的rootfs。

因为我使用-s标志到Qemu,所以我可以使用cross 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 ,我已经理解了代表AMBA总线,这是基于ARM的系统特有的。 我们有类似的PowerPC吗? 我在这里做错了什么?

Solutions Collecting From Web of "如何用QEMU和KGDBdebuggingLinux内核?"

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

QEMU通常没有理由触摸主机的串口。 真的是这样做的唯一原因是,如果你想有一个物理机主机QEMU,并有效地将其物理串行端口给客人,这样你就可以使用一个不同的物理机连接到一个实际的串行电缆调试客人。

当你使用-s标志的时候,你告诉QEMU运行它自己的GDB服务器(默认监听主机回环的TCP端口1234),允许你闯入客户机上运行的任何程序,是一个内核或引导程序或其他的东西。 这和客户机内核本身配合通过KGDB进行调试是不一样的。

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

调试/专家选项:

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

该选项可以多次使用来模拟多达4个串行端口。

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

'pty'[只限于Linux]伪TTY(一个新的PTY被自动分配)

'/ dev / XXX'[仅Linux]使用主机tty,例如'/ dev / ttyS0'。 主机串口参数按照仿真的参数进行设置。

这是你不想要的东西 – 除非你想使用串口线连接到运行GDB的不同物理机。

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

将tcp控制台发送到192.168.0.2端口4444的示例 – 串行tcp:192.168.0.2:4444

示例来监听和等待端口4444连接-serial tcp :: 4444,服务器

示例不等待和侦听ip 192.168.0.100端口4444 -serial tcp:192.168.0.100:4444,服务器,nowait

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

'unix:path [,server] [,nowait]'使用unix域套接字而不是tcp套接字。 该选项与您指定的-serial tcp相同,除了unix域套接字路径用于连接。

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

您可能需要首先配置其中一个选项,在没有KGDB的情况下运行并获取一个shell并找出被调用的设备的客户端是什么,然后重新启动配置的KGDB以使用它。

KGDB + QEMU一步一步

首先,QEMU的-gdb选项比KGDB严格得多,所以你可能想用它来代替: 如何用GDB和QEMU调试Linux内核? 然而,QEMU是一个简单的方法来与KGDB一起玩,准备真正的硬件。 我已经发布了一些树莓派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?