如何使用 QEMU 和 KGDB 调试 Linux 内核? [英] How to debug the Linux kernel with QEMU and KGDB?

查看:16
本文介绍了如何使用 QEMU 和 KGDB 调试 Linux 内核?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经能够使用以下方式启动基于 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.

由于我对 Qemu 使用了 -s 标志,所以我可以像这样使用跨 gdb 闯入内核:

(gdb) 目标远程 localhost:1234使用 localhost:1234 进行远程调试mem_serial_in(p=<值优化输出>,偏移=5)在drivers/serial/8250.c:405第405话

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

(gdb) 设置远程波特率 115200(gdb) 目标远程/dev/ttyS0没有权限

是不是因为已经被Qemu控制了?此外,在 Internet 上的示例中,kgdboc 已设置为 ttyAMA0,我开始理解它代表 AMBA 总线,它特定于基于 ARM 的系统.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/d424380fe62351358d21477658d2147758d21409dbc5

主要步骤是:

  1. 编译内核:

    CONFIG_DEBUG_KERNEL=yCONFIG_DEBUG_INFO=yCONFIG_CONSOLE_POLL=yCONFIG_KDB_CONTINUE_CATASTROPHIC=0CONFIG_KDB_DEFAULT_ENABLE=0x1CONFIG_KDB_KEYBOARD=yCONFIG_KGDB=yCONFIG_KGDB_KDB=yCONFIG_KGDB_LOW_LEVEL_TRAP=yCONFIG_KGDB_SERIAL_CONSOLE=yCONFIG_KGDB_TESTS=yCONFIG_KGDB_TESTS_ON_BOOT=nCONFIG_MAGIC_SYSRQ=yCONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1CONFIG_SERIAL_KGDB_NMI=n

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

  2. 添加到您的 QEMU 命令:

    -append 'kgdbwait kgdboc=ttyS0,115200' -串行 tcp::1234,服务器,nowait

  3. 使用以下命令从 Linux 内核源代码树的根运行 GDB:

    gdb -ex 'file vmlinux' -ex 'target remote localhost:1234'

  4. 在 GDB 中:

    (gdb) c

    启动应该完成.

  5. 在 QEMU 中:

    echo g >/proc/sysrq-触发器

    GDB 应该会崩溃.

  6. 现在我们完成了,您可以照常使用 GDB:

    b sys_writeC

在 Ubuntu 14.04 中测试.

ARM

无法正常工作.可能与:如何在ARM上使用kgdb?

有关

I have been able to boot a powerpc based system (MPC8544DS to be specific) using the following way to invoke 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"

where zImage is a custom cross compiled Linux Kernel (v2.6.32) which has KGDB enabled and compiled in (for startupcode debugging) and busyboxfs.img is the busybox based rootfs.

Since I'm using the -s flag to Qemu, I can break-in to the kernel using cross gdb like so:

(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  }

However if I remove the -s flag and try to break in to the kernel over /dev/ttyS0 it gives me a permission denied error:

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

Is it because it has been held over by Qemu? Additionally in example across the internet, kgdboc has been set to ttyAMA0 which I've come to understand stands for the AMBAbus which is specific to ARM based systems. Do we have something similar for PowerPC? Am I doing something wrong here?

解决方案

KGDB + QEMU step-by-step

First, QEMU's -gdb option is strictly more powerful than KGDB, so you might want to use that instead: How to debug the Linux kernel with GDB and QEMU? QEMU is however an easy way to play around with KGDB in preparation for real hardware. I have posted some Raspberry Pi KGDB pointers at: Linux kernel live debugging, how it's done and what tools are used?

If you want to get started quickly from scratch, I've made a minimal fully automated Buildroot example at: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/d424380fe62351358d21406280bc7588d795209c#kgdb

The main steps are:

  1. Compile the kernel with:

    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
    

    Most of those are not mandatory, but this is what I've tested.

  2. Add to your QEMU command:

    -append 'kgdbwait kgdboc=ttyS0,115200' 
    -serial tcp::1234,server,nowait
    

  3. Run GDB with from the root of the Linux kernel source tree with:

    gdb -ex 'file vmlinux' -ex 'target remote localhost:1234'
    

  4. In GDB:

    (gdb) c
    

    and the boot should finish.

  5. In QEMU:

    echo g > /proc/sysrq-trigger
    

    And GDB should break.

  6. Now we are done, you can use GDB as usual:

    b sys_write
    c
    

Tested in Ubuntu 14.04.

ARM

Can't get it work. Possibly related to: How to use kgdb on ARM??

这篇关于如何使用 QEMU 和 KGDB 调试 Linux 内核?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆