This commit is contained in:
Ciro Santilli
2017-06-30 23:28:36 +01:00
parent 3e0b03fc75
commit b5cafc8481
5 changed files with 53 additions and 35 deletions

View File

@@ -1,5 +1,11 @@
# CONTRIBUTING # CONTRIBUTING
Testing you should do before pushing: Testing you should do before pushing: new modules:
- `/insrm.sh module 5`. Helps catch simple insert remove problems. - `/insrm.sh module 5`. Helps catch simple insert remove problems.
New arch:
- `./run -a ARCH`
- `wget google.com` for Internet
- `./runqemu -a ARCH -d` and `./rungdb -a ARCH`

View File

@@ -1,6 +1,6 @@
# Linux Kernel Module Cheat # Linux Kernel Module Cheat
Run one command, get into QEMU Buildroot BusyBox virtual machine with several minimal Linux kernel 4.9 module development example tutorials with GDB and KGDB debug. Tested in x86 and ARM guests, Ubuntu 14.04 - 16.10 hosts. Run one command, get a QEMU Buildroot BusyBox virtual machine with several minimal Linux kernel 4.9 module development example tutorials with GDB and KGDB debug. Tested in x86, ARM and MIPS guests, Ubuntu 14.04 - 17.04 hosts.
![](screenshot.png) ![](screenshot.png)
@@ -139,9 +139,7 @@ To GDB the Linux kernel, first run:
./runqemu -d ./runqemu -d
This starts QEMU on the background of the shell, to prepare for running GDB. If you want to break immediately at a symbol, e.g. `start_kernel` of the boot sequence, run on another shell:
If you want to break immediately at a symbol, e.g. `start_kernel` of the boot sequence, run:
./rungdb start_kernel ./rungdb start_kernel
@@ -234,11 +232,13 @@ And then tell GDB where the module was loaded with:
Ctrl + C Ctrl + C
add-symbol-file ../kernel_module-1.0/fops.ko 0xfffffffa00000000 add-symbol-file ../kernel_module-1.0/fops.ko 0xfffffffa00000000
## ARM ## Other architectures
The portability of the kernel and toolchains is amazing. The portability of the kernel and toolchains is amazing: change an option and most things magically work on completely different hardware.
First ARM build: ### ARM
First build:
./run -a arm ./run -a arm
@@ -252,11 +252,15 @@ Debug:
# On another terminal. # On another terminal.
./rungdb -a arm ./rungdb -a arm
ARM TODOs: TODOs:
- only managed to run in the terminal interface (but weirdly a blank QEMU window is still opened) - only managed to run in the terminal interface (but weirdly a blank QEMU window is still opened)
- GDB not connecting to KGDB. Possibly linked to `-serial stdio`. See also: <https://stackoverflow.com/questions/14155577/how-to-use-kgdb-on-arm> - GDB not connecting to KGDB. Possibly linked to `-serial stdio`. See also: <https://stackoverflow.com/questions/14155577/how-to-use-kgdb-on-arm>
### MIPS
./run -a mips64
## KGDB ## KGDB
KGDB is kernel dark magic that allows you to GDB the kernel on real hardware without any extra hardware support. KGDB is kernel dark magic that allows you to GDB the kernel on real hardware without any extra hardware support.

13
run
View File

@@ -4,19 +4,22 @@ arch='x86_64'
while getopts a: OPT > /dev/null 2>&1; do while getopts a: OPT > /dev/null 2>&1; do
case "$OPT" in case "$OPT" in
'a') 'a')
arch=$OPTARG arch="$OPTARG"
;; ;;
esac esac
done done
case "$arch" in case "$arch" in
'x86_64') 'x86_64')
defconfig=qemu_x86_64_defconfig defconfig='qemu_x86_64_defconfig'
;; ;;
'arm') 'arm')
# qemu_arm_vexpress_defconfig required a newer QEMU than 2.0.0 on a Ubuntu host. # qemu_arm_vexpress_defconfig required a newer QEMU than 2.0.0 on a Ubuntu host.
# so let's stick to versatile for now. # so let's stick to versatile for now.
defconfig=qemu_arm_versatile_defconfig defconfig='qemu_arm_versatile_defconfig'
;; ;;
'mips64')
defconfig='qemu_mips64r6_malta_defconfig'
;;
esac esac
cd buildroot cd buildroot

13
rungdb
View File

@@ -7,7 +7,7 @@ kgdb=false
while getopts a:k OPT; do while getopts a:k OPT; do
case "$OPT" in case "$OPT" in
a) a)
arch=$OPTARG arch="$OPTARG"
;; ;;
k) k)
kgdb=true kgdb=true
@@ -18,7 +18,7 @@ shift "$(($OPTIND - 1))"
if [ "$#" -gt 0 ]; then if [ "$#" -gt 0 ]; then
brk="-ex 'break $1'" brk="-ex 'break $1'"
else else
brk="" brk=''
fi fi
buildroot_out_dir="$(pwd)/buildroot/output.${arch}~" buildroot_out_dir="$(pwd)/buildroot/output.${arch}~"
@@ -50,16 +50,17 @@ else
-ex 'target remote localhost:1234' \ -ex 'target remote localhost:1234' \
-ex 'lx-symbols ../kernel_module-1.0/' -ex 'lx-symbols ../kernel_module-1.0/'
" "
;; ;;
'arm') 'arm'|'mips64')
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 'target remote localhost:1234' \ -ex 'target remote localhost:1234' \
-ex 'lx-symbols ../kernel_module-1.0/' -ex 'lx-symbols ../kernel_module-1.0/' \
$brk \
" "
;; ;;
esac esac
fi fi
eval "$cmd" eval "$cmd"

34
runqemu
View File

@@ -3,7 +3,7 @@
set -e set -e
# CLI handling. # CLI handling.
arch=x86_64 arch='x86_64'
debug=false debug=false
debug_qemu='' debug_qemu=''
kgdb=false kgdb=false
@@ -13,7 +13,7 @@ extra_flags=''
while getopts a:de:knq OPT; do while getopts a:de:knq OPT; do
case "$OPT" in case "$OPT" in
a) a)
arch=$OPTARG arch="$OPTARG"
;; ;;
d) d)
debug=true debug=true
@@ -47,14 +47,15 @@ buildroot_out_dir="./buildroot/output.${arch}~"
images_dir="$buildroot_out_dir/images" images_dir="$buildroot_out_dir/images"
qemu_common="\ qemu_common="\
$debug_qemu \ $debug_qemu \
$buildroot_out_dir/host/usr/bin/qemu-system-$arch \ $buildroot_out_dir/host/usr/bin/qemu-system-${arch} \
-m 128M \ -m 128M \
-monitor telnet::45454,server,nowait \ -monitor telnet::45454,server,nowait \
-net user \ -net user \
-smp 1 \ -smp 1 \
" "
# The base QEMU commands are found under board/qemu/*/readme.tx
case "$arch" in case "$arch" in
x86_64) 'x86_64')
if $kgdb; then if $kgdb; then
extra_append="$extra_append kgdboc=ttyS0,115200" extra_append="$extra_append kgdboc=ttyS0,115200"
fi fi
@@ -68,7 +69,7 @@ case "$arch" in
$extra_flags $extra_flags
" "
;; ;;
arm) 'arm')
if $kgdb; then if $kgdb; then
extra_append="$extra_append kgdboc=ttyAMA0,115200" extra_append="$extra_append kgdboc=ttyAMA0,115200"
fi fi
@@ -83,14 +84,17 @@ case "$arch" in
$extra_flags $extra_flags
" "
;; ;;
'mips64')
cmd="$qemu_common \
-M malta \
-append 'root=/dev/hda $extra_append' \
-cpu I6400 \
-drive file=${images_dir}/rootfs.ext2,format=raw \
-kernel ${images_dir}/vmlinux \
-nographic \
-net nic,model=pcnet \
$extra_flags
"
;;
esac esac
if "$debug" && ! "$nographic" && [ ! "$arch" = 'arm' ]; then eval "$cmd"
eval "$cmd" &>/dev/null &
# TODO: Ctrl +C gets sent to QEMU? Why? Does not happen if I run
# ./rungdb manually from outside this script!!! But why?!?!
# eval has nothing to do with it, minimized example with explicit
# commands also fails in the same way...
#./rungdb
else
eval "$cmd"
fi