diff --git a/README.adoc b/README.adoc index 8136561..dfc806c 100644 --- a/README.adoc +++ b/README.adoc @@ -51,7 +51,49 @@ hello2 cleanup which are `printk` messages from `init` and `cleanup` methods of those modules. -image:screenshot.png[image] +Once you use <> and <>, your terminal will look a bit like this: + +.... +[ 1.451857] input: AT Translated Set 2 keyboard as /devices/platform/i8042/s1│loading @0xffffffffc0000000: ../kernel_module-1.0//timer.ko +[ 1.454310] ledtrig-cpu: registered to indicate activity on CPUs │(gdb) b lkmc_timer_callback +[ 1.455621] usbcore: registered new interface driver usbhid │Breakpoint 1 at 0xffffffffc0000000: file /home/ciro/bak/git/linux-kernel-module +[ 1.455811] usbhid: USB HID core driver │-cheat/out/x86_64/buildroot/build/kernel_module-1.0/./timer.c, line 28. +[ 1.462044] NET: Registered protocol family 10 │(gdb) c +[ 1.467911] Segment Routing with IPv6 │Continuing. +[ 1.468407] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver │ +[ 1.470859] NET: Registered protocol family 17 │Breakpoint 1, lkmc_timer_callback (data=0xffffffffc0002000 ) +[ 1.472017] 9pnet: Installing 9P2000 support │ at /home/ciro/bak/git/linux-kernel-module-cheat/out/x86_64/buildroot/build/ +[ 1.475461] sched_clock: Marking stable (1473574872, 0)->(1554017593, -80442)│kernel_module-1.0/./timer.c:28 +[ 1.479419] ALSA device list: │28 { +[ 1.479567] No soundcards found. │(gdb) c +[ 1.619187] ata2.00: ATAPI: QEMU DVD-ROM, 2.5+, max UDMA/100 │Continuing. +[ 1.622954] ata2.00: configured for MWDMA2 │ +[ 1.644048] scsi 1:0:0:0: CD-ROM QEMU QEMU DVD-ROM 2.5+ P5│Breakpoint 1, lkmc_timer_callback (data=0xffffffffc0002000 ) +[ 1.741966] tsc: Refined TSC clocksource calibration: 2904.010 MHz │ at /home/ciro/bak/git/linux-kernel-module-cheat/out/x86_64/buildroot/build/ +[ 1.742796] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x29dc0f4s│kernel_module-1.0/./timer.c:28 +[ 1.743648] clocksource: Switched to clocksource tsc │28 { +[ 2.072945] input: ImExPS/2 Generic Explorer Mouse as /devices/platform/i8043│(gdb) bt +[ 2.078641] EXT4-fs (vda): couldn't mount as ext3 due to feature incompatibis│#0 lkmc_timer_callback (data=0xffffffffc0002000 ) +[ 2.080350] EXT4-fs (vda): mounting ext2 file system using the ext4 subsystem│ at /home/ciro/bak/git/linux-kernel-module-cheat/out/x86_64/buildroot/build/ +[ 2.088978] EXT4-fs (vda): mounted filesystem without journal. Opts: (null) │kernel_module-1.0/./timer.c:28 +[ 2.089872] VFS: Mounted root (ext2 filesystem) readonly on device 254:0. │#1 0xffffffff810ab494 in call_timer_fn (timer=0xffffffffc0002000 , +[ 2.097168] devtmpfs: mounted │ fn=0xffffffffc0000000 ) at kernel/time/timer.c:1326 +[ 2.126472] Freeing unused kernel memory: 1264K │#2 0xffffffff810ab71f in expire_timers (head=, +[ 2.126706] Write protecting the kernel read-only data: 16384k │ base=) at kernel/time/timer.c:1363 +[ 2.129388] Freeing unused kernel memory: 2024K │#3 __run_timers (base=) at kernel/time/timer.c:1666 +[ 2.139370] Freeing unused kernel memory: 1284K │#4 run_timer_softirq (h=) at kernel/time/timer.c:1692 +[ 2.246231] EXT4-fs (vda): warning: mounting unchecked fs, running e2fsck isd│#5 0xffffffff81a000cc in __do_softirq () at kernel/softirq.c:285 +[ 2.259574] EXT4-fs (vda): re-mounted. Opts: block_validity,barrier,user_xatr│#6 0xffffffff810577cc in invoke_softirq () at kernel/softirq.c:365 +hello S98 │#7 irq_exit () at kernel/softirq.c:405 + │#8 0xffffffff818021ba in exiting_irq () at ./arch/x86/include/asm/apic.h:541 +Apr 15 23:59:23 login[49]: root login on 'console' │#9 smp_apic_timer_interrupt (regs=) +hello /root/.profile │ at arch/x86/kernel/apic/apic.c:1052 +# insmod /timer.ko │#10 0xffffffff8180190f in apic_timer_interrupt () +[ 6.791945] timer: loading out-of-tree module taints kernel. │ at arch/x86/entry/entry_64.S:857 +# [ 7.821621] 4294894248 │#11 0xffffffff82003df8 in init_thread_union () +[ 8.851385] 4294894504 │#12 0x0000000000000000 in ?? () + │(gdb) +.... All available modules can be found in the link:kernel_module/[`kernel_module` directory]. @@ -673,14 +715,47 @@ And you now control the counting on the first shell from GDB! When you hit `Ctrl-C`, if we happen to be inside kernel code at that point, which is very likely if there are no heavy background tasks waiting, and we are just waiting on a `sleep` type system call of the command prompt, we can already see the source for the random place inside the kernel where we stopped. -=== tmux multi terminal +=== tmux -tmux just makes things even more fun by allowing us to see both terminals at once without dragging windows around! https://unix.stackexchange.com/questions/152738/how-to-split-a-new-window-and-run-a-command-in-this-new-window-using-tmux/432111#432111 +https://unix.stackexchange.com/questions/152738/how-to-split-a-new-window-and-run-a-command-in-this-new-window-using-tmux/432111#432111 + +tmux just makes things even more fun by allowing us to see both terminals at once without dragging windows around! .... -./tmu ./rungdb && ./run -d +./run -du .... +Gives two panes: + +* left: usual QEMU +* right: gdb + +and focuses on the GDB pane. + +To start again, switch back to the QEMU (`-o`) pane, and re-run: + +.... +./run -du +.... + +This automatically kills the GDB pane. + +To quit for good, exit GDB, and quit the right shell with `Ctrl-D`. + +Pass extra GDB arguments with: + +.... +./run -du -U start_kernel +.... + +If you are using gem5 instead of QEMU, `-u` has a different effect: it opens the gem5 terminal instead of the debugger: + +.... +./run -gu +.... + +If you also want to use the debugger with gem5, you will need to create your own panes or windows. + === GDB step debug kernel module http://stackoverflow.com/questions/28607538/how-to-debug-linux-kernel-modules-with-qemu/44095831#44095831 diff --git a/run b/run index 52987dc..925b541 100755 --- a/run +++ b/run @@ -27,11 +27,13 @@ initramfs=false memory=256M nographic=true root= +tmux=false +tmux_args= # A dummy value that is already turned on by default and does not produce large output, # just to prevent QEMU from emitting a warning that '' is not valid. trace_enable=pr_manager_run vnc= -while getopts a:c:DdE:e:f:G:ghIiKkm:T:Vx OPT; do +while getopts a:c:DdE:e:f:G:ghIiKkm:T:U:uVx OPT; do case "$OPT" in a) arch="$OPTARG" @@ -91,6 +93,12 @@ while getopts a:c:DdE:e:f:G:ghIiKkm:T:Vx OPT; do T) trace_enable="$OPTARG" ;; + U) + tmux_args="$OPTARG" + ;; + u) + tmux=true + ;; x) nographic=false ;; @@ -281,5 +289,12 @@ ${extra_flags} \ ;; esac fi +if "$tmux"; then + if "$debug"; then + eval "./tmu ./rungdb -a "${arch}" ${tmux_args}" + elif "$gem5"; then + eval "./tmu 'sleep 1;./gem5-shell'" + fi +fi echo "$cmd" | tee "${out_arch_dir}/run.sh" eval "$cmd" diff --git a/run-usage.adoc b/run-usage.adoc index 11a708e..49bc1f8 100644 --- a/run-usage.adoc +++ b/run-usage.adoc @@ -35,7 +35,7 @@ |`-K` | |Use KVM. Only works if guest arch == host arch. |`-k` | |Enable KGDB. |`-m` | |Set the memory size of the guest. E.g.: `-m 512M`. Default: `256M`. - The default is the minimum ammount that boots all archs without extra + The default is the minimum amount that boots all archs without extra options added. Anything lower will lead some arch to fail to boot. Any |`-T` | |Enable extra QEMU trace events. @@ -43,6 +43,13 @@ some by default, e.g. `pr_manager_run`, and I don't know how to get rid of them. But those events are rare and should not impact performance, so we just ignore them for now. +|`-U` | |Pass extra parameters to the program running on the `-u` tmux split. +|`-u` | |Create a tmUx split the window. + You must already be inside of a `tmux` session to use this option. + * on the main window, run the emulator as usual + * on the split: + ** if on QEMU and `-d` is given, GDB + ** if on gem5, the gem5 terminal |`-V` | |Run QEMU with VNC instead of the default SDL. Connect to it with: `vinagre localhost:5900`. |`-x` | |Run in graphic mode. Mnemonic: X11. diff --git a/screenshot.png b/screenshot.png deleted file mode 100644 index 71a4cb1..0000000 Binary files a/screenshot.png and /dev/null differ diff --git a/tmu b/tmu index 97d7e35..7a92a97 100755 --- a/tmu +++ b/tmu @@ -1,2 +1,5 @@ #!/usr/bin/env bash +if [ "$(tmux list-panes | wc -l | cut -d' ' -f1)" -ne 1 ]; then + tmux kill-pane -t 1 +fi tmux split-window -h "bash --rcfile <(echo '. ~/.bashrc;$*')"