如何使用 QEMU 调试 Linux 内核模块?

Vik*_*uri 2 linux qemu kernel-module linux-kernel

我正在从事学术项目,修改一些Kernel Networking代码并包含一个新的Kernel module.

我正在使用 QEMU 加载修改后的内核并进行测试。

但是,我发现某些系统需要完整的操作系统.img才能进行调试。
没有它可能吗?

或者,这是可以与 Kernel 2.6 系统一起使用的发行版。除了运行程序的能力(包括网络支持)之外,发行版不需要具有任何功能。

tal*_*rer 5

我认为最简单的方法是使用 buildroot http://buildroot.uclibc.org/

克隆它,将其配置为使用您的自定义内核(默认用户空间一开始就很好,您可能想稍后更改它)。

它将构建您的内核和根文件系统。整个过程大约需要半个小时,其中二十分钟是在编译怪物

我的运行行看起来像: qemu-system-i386 -hda rootfs.ext2 -kernel bzImage -m 512M -append "root=/dev/sda console=ttyS0" -localtime -serial stdio

以及有关点击设备的更多选项


Cir*_*四事件 5

最小的全自动 QEMU + GDB + Buildroot 示例

非模块 Linux 内核上的 QEMU + GDB 详细介绍于: How to debug the Linux kernel with GDB and QEMU? 并在 QEMU 内构建内核模块,地址:How to add Linux driver as a Buildroot package首先让这些工作起来。

接下来,我还在以下位置进行了完全自动化的 GDB 模块调试:https://github.com/cirosantilli/linux-kernel-module-cheat/tree/1c29163c3919d4168d5d34852d804fd3eeb3ba67#kernel-module-debugging

以下是您必须采取的主要步骤:

  1. 使用调试符号编译内核模块:

    ccflags-y += -g -DDEBUG
    
    Run Code Online (Sandbox Code Playgroud)

    如所述:内核模块未找到调试符号

  2. 停止 GDB 并Ctrl + C运行:

    lx-symbols path/to/parent/of/modules/
    
    Run Code Online (Sandbox Code Playgroud)

    这个令人惊奇的命令是在 Linux 内核源代码树内的 GDB Python 脚本中定义的,每当 GDB 停止时,它会自动递归地加载给定目录下存在的已加载模块的符号。

    使该命令可用的最佳方法是使用:

    gdb -ex add-auto-load-safe-path /full/path/to/linux/kernel
    
    Run Code Online (Sandbox Code Playgroud)

    如解释:GDB: lx-symbols undefined command

  3. insmod内核模块。

    这必须在设置断点之前完成,因为我们事先不知道内核将把模块插入到内存中的哪个位置。

    lx-symbols自动为我们查找模块位置(在主机文件系统和来宾内存中!)。

  4. 使用 再次中断 GDB Ctrl + C,设置断点,然后享受吧。

如果感觉很硬核,您也可以lx-symbols完全放弃,然后使用以下命令找到模块位置insmod

cat /proc/modules
Run Code Online (Sandbox Code Playgroud)

然后.ko手动添加:

add-symbol-file path/to/mymodule.ko 0xfffffffa00000000    
Run Code Online (Sandbox Code Playgroud)