This commit is contained in:
Ciro Santilli
2017-05-26 08:54:17 +01:00
parent 36f48aa9c7
commit 6d2bbab19c
6 changed files with 127 additions and 27 deletions

View File

@@ -28,7 +28,7 @@ which are `printk` messages from `init` and `cleanup` methods of those modules.
Each module comes from a C file under `kernel_module/`. For module usage see: Each module comes from a C file under `kernel_module/`. For module usage see:
head kernel_module/*.c head kernel_module/modulename.c
Good bets inside guest are: Good bets inside guest are:
@@ -211,6 +211,62 @@ ARM TODOs:
- <https://github.com/cloudius-systems/osv/issues/49> - <https://github.com/cloudius-systems/osv/issues/49>
- <https://unix.stackexchange.com/questions/167165/how-to-pass-ctrl-c-in-qemu> - <https://unix.stackexchange.com/questions/167165/how-to-pass-ctrl-c-in-qemu>
## KGDB
KGDB is kernel dark magic that allows you to GDB the kernel on real hardware without any extra hardware support.
It is useless with QEMU since we already have full system visibility with `-gdb`, but this is a good way to learn it.
Cheaper than JTAG (free) and easier to setup (no wires), but with less visibility as it depends on the kernel working, so e.g.: dies on panic, does not see boot sequence.
Usage:
./runqemu -k
./rungdb -k
In GDB:
c
In QEMU:
/count.sh &
/kgdb.sh
In GDB:
b sys_write
c
c
c
c
And now you can count from GDB!
If you do: `b sys_write` immediately after `./rungdb -k`, it fails with `KGDB: BP remove failed: <address>`. I think this is because it would break too early on the boot sequence, and KGDB is not yet ready.
See also:
- <https://github.com/torvalds/linux/blob/v4.9/Documentation/DocBook/kgdb.tmpl>
### KGDB kernel modules
In QEMU:
/kgdb-mod.sh
In GDB:
lx-symbols ../kernel_module-1.0/
b fop_write
c
c
c
and you now control the count.
TODO: if I `-ex lx-symbols` to the `gdb` command, just like done for QEMU `-gdb`, the kernel oops. How to automate this step?
## Table of contents ## Table of contents
1. [Introduction](introduction.md) 1. [Introduction](introduction.md)

View File

@@ -5,3 +5,18 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_FS=y CONFIG_DEBUG_FS=y
CONFIG_DEBUG_INFO=y CONFIG_DEBUG_INFO=y
CONFIG_GDB_SCRIPTS=y CONFIG_GDB_SCRIPTS=y
# KGDB.
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

9
rootfs_overlay/kgdb-mod.sh Executable file
View File

@@ -0,0 +1,9 @@
#!/bin/sh
insmod /fops.ko
cd /sys/kernel/debug/kernel_module_cheat
i=0
while true; do
printf "$i" >fops
i=$(($i+1))
done &
/kgdb.sh

2
rootfs_overlay/kgdb.sh Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/sh
echo g > /proc/sysrq-trigger

15
rungdb
View File

@@ -3,11 +3,15 @@
set -e set -e
arch=x86_64 arch=x86_64
while getopts a: OPT; do kgdb=false
while getopts a:k OPT; do
case "$OPT" in case "$OPT" in
a) a)
arch=$OPTARG arch=$OPTARG
;; ;;
k)
kgdb=true
;;
esac esac
done done
shift "$(($OPTIND - 1))" shift "$(($OPTIND - 1))"
@@ -19,6 +23,14 @@ fi
gdb="$(pwd)/buildroot/output/host/usr/bin/${arch}-linux-gdb" gdb="$(pwd)/buildroot/output/host/usr/bin/${arch}-linux-gdb"
cd buildroot/output/build/linux-*.*.*/ cd buildroot/output/build/linux-*.*.*/
if $kgdb; then
cmd="$gdb \
-q \
-ex 'add-auto-load-safe-path $(pwd)' \
-ex 'file vmlinux' \
-ex 'target remote localhost:1234'
"
else
case "$arch" in case "$arch" in
x86_64) x86_64)
# http://stackoverflow.com/questions/11408041/how-to-debug-the-linux-kernel-with-gdb-and-qemu/33203642#33203642 # http://stackoverflow.com/questions/11408041/how-to-debug-the-linux-kernel-with-gdb-and-qemu/33203642#33203642
@@ -48,4 +60,5 @@ case "$arch" in
" "
;; ;;
esac esac
fi
eval "$cmd" eval "$cmd"

View File

@@ -8,7 +8,7 @@ debug=false
nographic=false nographic=false
extra_append='' extra_append=''
extra_flags='' extra_flags=''
while getopts a:dn OPT; do while getopts a:dkn OPT; do
case "$OPT" in case "$OPT" in
a) a)
arch=$OPTARG arch=$OPTARG
@@ -17,6 +17,11 @@ while getopts a:dn OPT; do
debug=true debug=true
extra_flags="$extra_flags -S -s" extra_flags="$extra_flags -S -s"
;; ;;
k)
debug=true
extra_append="$extra_append kgdbwait kgdboc=ttyS0,115200"
extra_flags="$extra_flags -serial tcp::1234,server,nowait"
;;
n) n)
extra_append="$extra_append console=ttyS0" extra_append="$extra_append console=ttyS0"
extra_flags="$extra_flags -nographic" extra_flags="$extra_flags -nographic"