mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-28 12:34:26 +01:00
Almost working
This commit is contained in:
33
README.md
33
README.md
@@ -1,6 +1,6 @@
|
|||||||
# Linux Kernel Module Cheat
|
# Linux Kernel Module Cheat
|
||||||
|
|
||||||
Run one command, get into QEMU Buildroot BusyBox with several minimal Linux kernel 4.9 module example tutorials with GDB debug support. Tested in Ubuntu 14.04 - 16.10 hosts.
|
Run one command, get into QEMU Buildroot BusyBox with several minimal Linux kernel 4.9 module example tutorials with GDB debug support. x86 and ARM guests supported. Tested in Ubuntu 14.04 - 16.10 hosts.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
|
|
||||||
@@ -164,6 +164,37 @@ 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
|
||||||
|
|
||||||
|
The portability of the kernel and toolchains is amazing.
|
||||||
|
|
||||||
|
If you already have an x86 build present, first:
|
||||||
|
|
||||||
|
cd buildroot
|
||||||
|
mv output output.x86~
|
||||||
|
|
||||||
|
First ARM build:
|
||||||
|
|
||||||
|
./run -a arm
|
||||||
|
|
||||||
|
Run without build:
|
||||||
|
|
||||||
|
./runqemu -a arm
|
||||||
|
|
||||||
|
Debug:
|
||||||
|
|
||||||
|
./runqemu -a arm -d
|
||||||
|
# On another terminal.
|
||||||
|
./rungdb -a arm
|
||||||
|
|
||||||
|
ARM TODOs:
|
||||||
|
|
||||||
|
- only managed to run in the terminal interface (but weirdly an blank QEMU window is still opened)
|
||||||
|
- Ctrl + C kills the emulator, not sent to guest. See:
|
||||||
|
- <https://github.com/cloudius-systems/osv/issues/49>
|
||||||
|
- <https://unix.stackexchange.com/questions/167165/how-to-pass-ctrl-c-in-qemu>
|
||||||
|
- `fops.ko`, `printf a >fops` crashes with `BUG: recent printk recursion!`
|
||||||
|
|
||||||
## Table of contents
|
## Table of contents
|
||||||
|
|
||||||
1. [Introduction](introduction.md)
|
1. [Introduction](introduction.md)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ int main(int argc, char **argv) {
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
if (delete_module(argv[1], O_NONBLOCK) != 0) {
|
if (delete_module(argv[1], O_NONBLOCK) != 0) {
|
||||||
perror("delete_modul");
|
perror("delete_module");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|||||||
22
run
22
run
@@ -1,9 +1,25 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -e
|
set -e
|
||||||
cd buildroot
|
cd buildroot
|
||||||
#make BR2_EXTERNAL="$(pwd)/../kernel_module" qemu_x86_64_defconfig
|
arch='x86_64'
|
||||||
#make BR2_EXTERNAL="$(pwd)/../kernel_module" qemu_arm_vexpress_defconfig
|
while getopts a: OPT; do
|
||||||
make BR2_EXTERNAL="$(pwd)/../kernel_module" qemu_arm_versatile_defconfig
|
case "$OPT" in
|
||||||
|
a)
|
||||||
|
arch=$OPTARG
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
case "$arch" in
|
||||||
|
x86_64)
|
||||||
|
defconfig=qemu_x86_64_defconfig
|
||||||
|
;;
|
||||||
|
arm)
|
||||||
|
# qemu_arm_vexpress_defconfig required a newer QEMU than 2.0.0 on a Ubuntu host.
|
||||||
|
# so let's stick to versatile for now.
|
||||||
|
defconfig=qemu_arm_versatile_defconfig
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
make BR2_EXTERNAL="$(pwd)/../kernel_module" "$defconfig"
|
||||||
# Can't get rid of this for now.
|
# Can't get rid of this for now.
|
||||||
# http://stackoverflow.com/questions/44078245/is-it-possible-to-use-config-fragments-with-buildroots-config
|
# http://stackoverflow.com/questions/44078245/is-it-possible-to-use-config-fragments-with-buildroots-config
|
||||||
cat ../buildroot_config_fragment >> .config
|
cat ../buildroot_config_fragment >> .config
|
||||||
|
|||||||
52
rungdb
52
rungdb
@@ -1,17 +1,51 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
arch=x86_64
|
||||||
|
while getopts a: OPT; do
|
||||||
|
case "$OPT" in
|
||||||
|
a)
|
||||||
|
arch=$OPTARG
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
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
|
||||||
gdb="$(pwd)/buildroot/output/host/usr/bin/arm-linux-gdb"
|
|
||||||
|
gdb="$(pwd)/buildroot/output/host/usr/bin/${arch}-linux-gdb"
|
||||||
cd buildroot/output/build/linux-*.*.*/
|
cd buildroot/output/build/linux-*.*.*/
|
||||||
cmd="$gdb \
|
case "$arch" in
|
||||||
-q \
|
x86_64)
|
||||||
-ex 'add-auto-load-safe-path $(pwd)' \
|
# http://stackoverflow.com/questions/11408041/how-to-debug-the-linux-kernel-with-gdb-and-qemu/33203642#33203642
|
||||||
-ex 'file vmlinux' \
|
# http://stackoverflow.com/questions/4943857/linux-kernel-live-debugging-how-its-done-and-what-tools-are-used/42316607#42316607
|
||||||
-ex 'target remote localhost:1234' \
|
# http://stackoverflow.com/questions/28607538/how-to-debug-linux-kernel-modules-with-qemu/44095831#44095831
|
||||||
-ex 'lx-symbols ../kernel_module-1.0/'
|
cmd="$gdb \
|
||||||
"
|
-q \
|
||||||
#-ex 'set arch i386:x86-64:intel' \
|
-ex 'add-auto-load-safe-path $(pwd)' \
|
||||||
|
-ex 'file vmlinux' \
|
||||||
|
-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
|
||||||
eval "$cmd"
|
eval "$cmd"
|
||||||
|
|||||||
64
runqemu
64
runqemu
@@ -3,12 +3,16 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
# CLI handling.
|
# CLI handling.
|
||||||
|
arch=x86_64
|
||||||
debug=false
|
debug=false
|
||||||
nographic=false
|
nographic=false
|
||||||
extra_append=''
|
extra_append=''
|
||||||
extra_flags=''
|
extra_flags=''
|
||||||
while getopts dn OPT; do
|
while getopts a:dn OPT; do
|
||||||
case "$OPT" in
|
case "$OPT" in
|
||||||
|
a)
|
||||||
|
arch=$OPTARG
|
||||||
|
;;
|
||||||
d)
|
d)
|
||||||
debug=true
|
debug=true
|
||||||
extra_flags="$extra_flags -S -s"
|
extra_flags="$extra_flags -S -s"
|
||||||
@@ -21,31 +25,41 @@ while getopts dn OPT; do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
# If we turn on buildroot host QEMU some day.
|
images_dir='buildroot/output/images'
|
||||||
#cmd="./buildroot/output/host/usr/bin/qemu-system-x86_64 \
|
case "$arch" in
|
||||||
#cmd="qemu-system-arm \
|
x86_64)
|
||||||
#cmd="qemu-system-x86_64 \
|
# If we turn on buildroot host QEMU some day.
|
||||||
#-M pc \
|
#cmd="./buildroot/output/host/usr/bin/qemu-system-x86_64 \
|
||||||
#-append 'root=/dev/vda $extra_append' \
|
cmd="qemu-system-x86_64 \
|
||||||
#-drive file=buildroot/output/images/rootfs.ext2,if=virtio,format=raw \
|
-M pc \
|
||||||
#-kernel buildroot/output/images/zImage \
|
-append 'root=/dev/vda $extra_append' \
|
||||||
#-m 128M \
|
-drive file=${images_dir}/rootfs.ext2,if=virtio,format=raw \
|
||||||
#-net user \
|
-kernel ${images_dir}/bzImage \
|
||||||
#-smp 1 \
|
-m 128M \
|
||||||
#$extra_flags \
|
-net nic,model=virtio \
|
||||||
#-M pc \
|
-net user \
|
||||||
#-net nic,model=virtio \
|
-smp 1 \
|
||||||
#-kernel buildroot/output/images/bzImage \
|
$extra_flags
|
||||||
#;
|
"
|
||||||
#"
|
;;
|
||||||
|
arm)
|
||||||
|
cmd="qemu-system-arm \
|
||||||
|
-M versatilepb \
|
||||||
|
-append 'root=/dev/sda console=ttyAMA0,115200' \
|
||||||
|
-drive file=${images_dir}/rootfs.ext2,if=scsi,format=raw \
|
||||||
|
-dtb ${images_dir}/versatile-pb.dtb \
|
||||||
|
-kernel ${images_dir}/zImage \
|
||||||
|
-m 128M \
|
||||||
|
-net nic,model=rtl8139 \
|
||||||
|
-net user \
|
||||||
|
-serial stdio \
|
||||||
|
-smp 1 \
|
||||||
|
$extra_flags"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if "$debug" && ! "$nographic" && [ ! "$arch" = 'arm' ]; then
|
||||||
cmd='qemu-system-arm -M versatilepb -kernel buildroot/output/images/zImage -dtb buildroot/output/images/versatile-pb.dtb -drive file=buildroot/output/images/rootfs.ext2,if=scsi,format=raw -append "root=/dev/sda console=ttyAMA0,115200" -serial stdio -net nic,model=rtl8139 -net user -nographic'
|
eval "$cmd" &>/dev/null &
|
||||||
#cmd='/data/git/buildroot/output/host/usr/bin/qemu-system-arm -M vexpress-a9 -smp 1 -m 256 -kernel buildroot/output/images/zImage -dtb buildroot/output/images/vexpress-v2p-ca9.dtb -drive file=buildroot/output/images/rootfs.ext2,if=sd,format=raw -append "console=ttyAMA0,115200 root=/dev/mmcblk0" -serial stdio -net nic,model=lan9118 -net user'
|
|
||||||
#cmd='qemu-system-arm -M vexpress-a9 -smp 1 -m 256 -kernel buildroot/output/images/zImage -dtb buildroot/output/images/vexpress-v2p-ca9.dtb -drive file=buildroot/output/images/rootfs.ext2,if=sd,format=raw -append "console=ttyAMA0,115200 root=/dev/mmcblk0" -serial stdio -net nic,model=lan9118 -net user'
|
|
||||||
|
|
||||||
if $debug && ! $nographic; then
|
|
||||||
eval nohup "$cmd" &>/dev/null &
|
|
||||||
# TODO: Ctrl +C gets sent to QEMU? Why? Does not happen if I run
|
# TODO: Ctrl +C gets sent to QEMU? Why? Does not happen if I run
|
||||||
# ./rungdb manually from outside this script!!! But why?!?!
|
# ./rungdb manually from outside this script!!! But why?!?!
|
||||||
# eval has nothing to do with it, minimized example with explicit
|
# eval has nothing to do with it, minimized example with explicit
|
||||||
|
|||||||
Reference in New Issue
Block a user