Hig*_*eat 6 linux embedded qemu powerpc linux-kernel
我已经能够使用以下方法来启动基于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"
Run Code Online (Sandbox Code Playgroud)
其中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 }
Run Code Online (Sandbox Code Playgroud)
但是,如果我删除该-s
标志并尝试闯入内核,/dev/ttyS0
则会给我一个权限被拒绝的错误:
(gdb) set remotebaud 115200
(gdb) target remote /dev/ttyS0
permission denied
Run Code Online (Sandbox Code Playgroud)
是因为它被Qemu保留了吗?另外,在互联网上的示例中ttyAMA0
,我已经了解了kgdboc ,该AMBA
总线代表特定于基于ARM的系统的总线。我们对PowerPC有类似的东西吗?我在这里做错什么了吗?
您似乎混淆了客户机的主机串行设备 /dev/ttyS0 和客户机内核中用于 KGDB 的 QEMU 自己的 gdbserver。
QEMU 通常没有理由接触主机的串行端口。真正这样做的唯一原因是,如果您想让一台物理机托管 QEMU,并有效地将其物理串行端口提供给来宾,以便您可以使用通过实际串行电缆连接的不同物理机来调试客人。
当您使用 -s 标志时,您告诉 QEMU 运行它自己的 GDB 服务器(默认情况下侦听主机环回 TCP 端口 1234)允许您闯入来宾上运行的任何程序,无论是内核还是引导加载程序或其他东西. 这与让来宾内核本身通过 KGDB 与调试合作不同。
如果您想使用 KGDB,您将需要在内核构建中配置 KGDB 以使用模拟串行端口的来宾端,然后告诉主机上的 GDB 使用该模拟端口的主机端。该QEMU命令行documenation覆盖了本详细:
调试/专家选项:
'-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 -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 的情况下重新启动。
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
主要步骤是:
使用以下命令编译内核:
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
Run Code Online (Sandbox Code Playgroud)
其中大多数不是强制性的,但这是我测试过的。
添加到您的QEMU命令:
-append 'kgdbwait kgdboc=ttyS0,115200' \
-serial tcp::1234,server,nowait
Run Code Online (Sandbox Code Playgroud)使用以下命令从Linux内核源树的根目录运行GDB:
gdb -ex 'file vmlinux' -ex 'target remote localhost:1234'
Run Code Online (Sandbox Code Playgroud)在GDB中:
(gdb) c
Run Code Online (Sandbox Code Playgroud)
并且启动应该完成。
在QEMU中:
echo g > /proc/sysrq-trigger
Run Code Online (Sandbox Code Playgroud)
GDB应该崩溃了。
现在我们完成了,您可以照常使用GDB:
b sys_write
c
Run Code Online (Sandbox Code Playgroud)在Ubuntu 14.04中测试。
臂
无法正常工作。可能与以下内容有关:如何在ARM上使用kgdb?