Kernel Debugging with QEMU: Difference between revisions
m Add link for more info about patching and configuring the kernel |
m style fixes |
||
| Line 62: | Line 62: | ||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
users.motd = | |||
let | |||
gdbScript = pkgs.writeScript "attach-gdb.sh" '' | |||
mkdir -p /tmp/gdb | |||
cd /tmp/gdb | |||
rm -rf * | |||
ls ${pkgs.srcOnly config.boot.kernelPackages.kernel} | while read line ; do ln -s ${pkgs.srcOnly config.boot.kernelPackages.kernel}/$line $line ; done | |||
mkdir kos | |||
cd kos | |||
cp ${config.boot.kernelPackages.kernel}/lib/modules/*/kernel/fs/netfs/* . | |||
cp ${config.boot.kernelPackages.kernel}/lib/modules/*/kernel/fs/9p/* . | |||
cp ${config.boot.kernelPackages.kernel}/lib/modules/*/kernel/net/9p/* . | |||
xz -d * | |||
GDB_SCRIPT_DIR=$(echo ${config.boot.kernelPackages.kernel.dev}/lib/modules/*/build/scripts/gdb) | |||
gdb \ | |||
-ex "python import sys; sys.path.insert(0, '$GDB_SCRIPT_DIR')" \ | |||
-ex "target remote :1234" \ | |||
-ex "source $GDB_SCRIPT_DIR/vmlinux-gdb.py" \ | |||
-ex "lx-symbols" \ | |||
${config.boot.kernelPackages.kernel.dev}/vmlinux | |||
''; | |||
in '' | |||
look at /repro/default.json | |||
kernel at ${config.boot.kernelPackages.kernel} | |||
kernel dev at ${config.boot.kernelPackages.kernel.dev} | |||
attach gdb with ${gdbScript} on the host | |||
''; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
| Line 166: | Line 166: | ||
$ scripts/config --set-val GDB_SCRIPTS y | $ scripts/config --set-val GDB_SCRIPTS y | ||
$ scripts/config --set-val DEBUG_DRIVER y # Enable printk messages in drivers | $ scripts/config --set-val DEBUG_DRIVER y # Enable printk messages in drivers | ||
# everything as one command for copy'n'paste | $ # everything as one command for copy'n'paste | ||
$ scripts/config --set-val DEBUG_INFO y --set-val DEBUG y --set-val GDB_SCRIPTS y --set-val DEBUG_DRIVER y | $ scripts/config --set-val DEBUG_INFO y --set-val DEBUG y --set-val GDB_SCRIPTS y --set-val DEBUG_DRIVER y | ||
# this might ask for further options, just press enter for every question | $ # this might ask for further options, just press enter for every question | ||
$ make -j$(nproc) | $ make -j$(nproc) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| Line 231: | Line 231: | ||
<syntaxhighlight lang="console"> | <syntaxhighlight lang="console"> | ||
$ nix-build | $ nix-build | ||
# copy out | $ # copy out | ||
$ install -m644 result/nixos.qcow2 qemu-image.img | $ install -m644 result/nixos.qcow2 qemu-image.img | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| Line 241: | Line 241: | ||
<syntaxhighlight lang="console"> | <syntaxhighlight lang="console"> | ||
$ nix-shell -p debootstrap qemu | |||
$ qemu-img create qemu-image.img 5G | |||
$ 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 | |||
</syntaxhighlight> | </syntaxhighlight> | ||
| Line 257: | Line 257: | ||
The filesystem is mounted read only so to add tools like lspci. Mount and chroot then use apt to install the needed binaries. | The filesystem is mounted read only so to add tools like lspci. Mount and chroot then use apt to install the needed binaries. | ||
<syntaxhighlight lang="console"> | <syntaxhighlight lang="console"> | ||
$ sudo mount -o loop qemu-image.img mount-point.dir | |||
$ sudo chroot mount-point.dir /bin/bash -i | |||
$ export PATH=$PATH:/bin | |||
$ apt install pciutils tree | |||
$ sudo umount mount-point.dir | |||
</syntaxhighlight> | </syntaxhighlight> | ||
| Line 270: | Line 270: | ||
<syntaxhighlight lang="console"> | <syntaxhighlight lang="console"> | ||
$ qemu-system-x86_64 -s -S \ | |||
-kernel arch/x86/boot/bzImage \ | |||
-hda qemu-image.img \ | |||
-append "root=/dev/sda console=ttyS0 nokaslr" \ | |||
-enable-kvm \ | |||
-nographic | |||
</syntaxhighlight> | </syntaxhighlight> | ||
==== 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 -ex "target remote :1234" ./vmlinux | |||
(gdb) continue | |||
</syntaxhighlight> | </syntaxhighlight> | ||
| Line 300: | Line 300: | ||
Make sure the driver you want to inspect is not compiled into the kernel, look for the option to enable compilation of your driver, to do this execute: | Make sure the driver you want to inspect is not compiled into the kernel, look for the option to enable compilation of your driver, to do this execute: | ||
<syntaxhighlight lang="console"> | <syntaxhighlight lang="console"> | ||
$ make nconfig | |||
</syntaxhighlight> | </syntaxhighlight> | ||
press <code>F8</code> and search for your driver, and check if it is set to "Module" with <code><M></code>. After compilation copy the driver.ko into the mounted <code>qemu-image.img</code>. Unmount start the kernel and break at the <code>load_module</code> function and <code>insmod driver.ko</code>. Happy hacking! | press <code>F8</code> and search for your driver, and check if it is set to "Module" with <code><M></code>. After compilation copy the driver.ko into the mounted <code>qemu-image.img</code>. Unmount start the kernel and break at the <code>load_module</code> function and <code>insmod driver.ko</code>. Happy hacking! | ||