Kernel Debugging with QEMU: Difference between revisions

From NixOS Wiki
imported>Luis-Hebendanz
mNo edit summary
imported>Luis-Hebendanz
mNo edit summary
Line 58: Line 58:
Discard the <code>-enable-kvm</code> flag if  
Discard the <code>-enable-kvm</code> flag if  
<code> virtualisation.libvirtd.enable </code> is not set in your configuration.nix.
<code> virtualisation.libvirtd.enable </code> is not set in your configuration.nix.
The <code>nokaslr</code> kernel flag is important to be able to set breakpoints in kernel memory.
<syntaxhighlight lang="console">
<syntaxhighlight lang="console">
  $ qemu-system-x86_64 -s -S \
  $ qemu-system-x86_64 -s -S \
Line 69: Line 70:
== Connect with gdb ==
== Connect with gdb ==
<syntaxhighlight lang="console">
<syntaxhighlight lang="console">
$ echo "add-auto-load-safe-path `pwd`/scripts/gdb/vmlinux-gdb.py" >> ~/.gdbinit
  $ gdb ./vmlinux
  $ gdb ./vmlinux
  (gdb) target remote :1234
  (gdb) target remote :1234
  (gdb) continue
  (gdb) continue
</syntaxhighlight>
</syntaxhighlight>

Revision as of 15:52, 21 March 2020

Setup

Clone the repository

$ git clone https://github.com/torvalds/linux.git

For kernel dependencies, create a shell.nix file in the cloned repo

{ pkgs ? import <nixpkgs> {} }:

(pkgs.buildFHSUserEnv {
  name = "linux-kernel-build";
  targetPkgs = pkgs: (with pkgs;
  [
    getopt
    flex
    bison
    libelf
    ncurses.dev
    openssl.dev
    gcc
    gnumake
    bc

  ]);
  runScript = "bash";
}).env

Generate a config for KVM

$ cd linux
$ nix-shell shell.nix
$ make x86_64_defconfig
$ make kvmconfig
$ scripts/config --set-val DEBUG_INFO y # For gdb debug symbols
$ make -j <number-cpu-cores>

Create a bootable debian image with replaceable kernel

 $ nix-shell -p debootstrap qemu
 $ qemu-img create qemu-image.img
 $ mkfs.ext2 qemu-image.img
 $ mkdir mount-point.dir
 $ sudo mount -o loop qemu-image.img mount-point.dir
 $ sudo debootstrap --arch amd64 buster mount-point.dir
 $ sudo chroot mount-point.dir /bin/bash -i
 $ export PATH=$PATH:/bin
 $ passwd # Set root password
 $ exit
 $ sudo umount mount-point.dir
 $ rmdir mount-point.dir

Launch qemu

Discard the -enable-kvm flag if virtualisation.libvirtd.enable is not set in your configuration.nix. The nokaslr kernel flag is important to be able to set breakpoints in kernel memory.

 $ qemu-system-x86_64 -s -S \
    -kernel ../arch/x86_64/boot/bzImage \
    -hda qemu-img.img \
    -append "root=/dev/sda console=ttyS0 nokaslr" \
    -enable-kvm \
    -nographic

Connect with gdb

 $ echo "add-auto-load-safe-path `pwd`/scripts/gdb/vmlinux-gdb.py" >> ~/.gdbinit
 $ gdb ./vmlinux
 (gdb) target remote :1234
 (gdb) continue