How to debug Linux kernel modules with QEMU?

2019-01-12 02:07发布

问题:

I am working on academic project that modifies some Kernel Networking code as well as include a new Kernel module.

I am using QEMU to load modified kernel and test.

However, i find that a complete OS is required in some .img to debug.
Is it possible without it ?

Or, which is the distro that can be used with Kernel 2.6 for system. The distro need not have any features, except ability to run programs, including networking support.

回答1:

The easiest way in my opinion is to use buildroot http://buildroot.uclibc.org/

clone it, configure it to use your custom kernel (default userspace is fine for a start, you might want to change it later).

it will build your kernel and root filesystem. the entire process takes about half an hour, twenty minutes of which is compiling the monster

my run line looks something: qemu-system-i386 -hda rootfs.ext2 -kernel bzImage -m 512M -append "root=/dev/sda console=ttyS0" -localtime -serial stdio

and some more options regarding a tap device



回答2:

Minimal fully automated QEMU + GDB + Buildroot example

QEMU + GDB on non-module Linux kernel is covered in detail at: How to debug the Linux kernel with GDB and QEMU? and building the kernel modules inside QEMU at: How to add Linux driver as a Buildroot package Get those working first.

Next, I have also fully automated GDB module debugging at: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/1c29163c3919d4168d5d34852d804fd3eeb3ba67#kernel-module-debugging

These are the main steps you have to take:

  1. Compile the kernel module with debug symbols:

    ccflags-y += -g -DDEBUG
    

    as mentioned at: kernel module no debugging symbols found

  2. Stop GDB with Ctrl + C and run:

    lx-symbols path/to/parent/of/modules/
    

    This amazing command, which is defined in a GDB Python script inside the Linux kernel source tree, automatically loads symbols for loaded modules present under the given directory recursively whenever GDB stops.

    The best way to make that command available is to use:

    gdb -ex add-auto-load-safe-path /full/path/to/linux/kernel
    

    as explained at: GDB: lx-symbols undefined command

  3. insmod the kernel module.

    This must be done before setting breakpoints, because we don't know where the kernel will insert the module in memory beforehand.

    lx-symbols automatically takes care of finding the module location (in host filesystem and guest memory!) for us.

  4. Break GDB again with Ctrl + C, set breakpoints, and enjoy.

If were feeling hardcore, you could also drop lx-symbols entirely, and find the module location after insmod with:

cat /proc/modules

and then add the .ko manually with:

add-symbol-file path/to/mymodule.ko 0xfffffffa00000000