mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
KGDB!
This commit is contained in:
58
README.md
58
README.md
@@ -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)
|
||||||
|
|||||||
@@ -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
9
rootfs_overlay/kgdb-mod.sh
Executable 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
2
rootfs_overlay/kgdb.sh
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
echo g > /proc/sysrq-trigger
|
||||||
63
rungdb
63
rungdb
@@ -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,33 +23,42 @@ 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-*.*.*/
|
||||||
case "$arch" in
|
if $kgdb; then
|
||||||
x86_64)
|
|
||||||
# http://stackoverflow.com/questions/11408041/how-to-debug-the-linux-kernel-with-gdb-and-qemu/33203642#33203642
|
|
||||||
# http://stackoverflow.com/questions/4943857/linux-kernel-live-debugging-how-its-done-and-what-tools-are-used/42316607#42316607
|
|
||||||
# http://stackoverflow.com/questions/28607538/how-to-debug-linux-kernel-modules-with-qemu/44095831#44095831
|
|
||||||
cmd="$gdb \
|
cmd="$gdb \
|
||||||
-q \
|
-q \
|
||||||
-ex 'add-auto-load-safe-path $(pwd)' \
|
-ex 'add-auto-load-safe-path $(pwd)' \
|
||||||
-ex 'file vmlinux' \
|
-ex 'file vmlinux' \
|
||||||
-ex 'set arch i386:x86-64:intel' \
|
-ex 'target remote localhost:1234'
|
||||||
-ex 'target remote localhost:1234' \
|
|
||||||
$brk \
|
|
||||||
-ex 'continue' \
|
|
||||||
-ex 'disconnect' \
|
|
||||||
-ex 'set arch i386:x86-64' \
|
|
||||||
-ex 'target remote localhost:1234' \
|
|
||||||
-ex 'lx-symbols ../kernel_module-1.0/'
|
|
||||||
"
|
"
|
||||||
;;
|
else
|
||||||
arm)
|
case "$arch" in
|
||||||
cmd="$gdb \
|
x86_64)
|
||||||
-q \
|
# http://stackoverflow.com/questions/11408041/how-to-debug-the-linux-kernel-with-gdb-and-qemu/33203642#33203642
|
||||||
-ex 'add-auto-load-safe-path $(pwd)' \
|
# http://stackoverflow.com/questions/4943857/linux-kernel-live-debugging-how-its-done-and-what-tools-are-used/42316607#42316607
|
||||||
-ex 'file vmlinux' \
|
# http://stackoverflow.com/questions/28607538/how-to-debug-linux-kernel-modules-with-qemu/44095831#44095831
|
||||||
-ex 'target remote localhost:1234' \
|
cmd="$gdb \
|
||||||
-ex 'lx-symbols ../kernel_module-1.0/'
|
-q \
|
||||||
"
|
-ex 'add-auto-load-safe-path $(pwd)' \
|
||||||
;;
|
-ex 'file vmlinux' \
|
||||||
esac
|
-ex 'set arch i386:x86-64:intel' \
|
||||||
|
-ex 'target remote localhost:1234' \
|
||||||
|
$brk \
|
||||||
|
-ex 'continue' \
|
||||||
|
-ex 'disconnect' \
|
||||||
|
-ex 'set arch i386:x86-64' \
|
||||||
|
-ex 'target remote localhost:1234' \
|
||||||
|
-ex 'lx-symbols ../kernel_module-1.0/'
|
||||||
|
"
|
||||||
|
;;
|
||||||
|
arm)
|
||||||
|
cmd="$gdb \
|
||||||
|
-q \
|
||||||
|
-ex 'add-auto-load-safe-path $(pwd)' \
|
||||||
|
-ex 'file vmlinux' \
|
||||||
|
-ex 'target remote localhost:1234' \
|
||||||
|
-ex 'lx-symbols ../kernel_module-1.0/'
|
||||||
|
"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
eval "$cmd"
|
eval "$cmd"
|
||||||
|
|||||||
7
runqemu
7
runqemu
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user