From bad30f513c46c1b0995d3a10c0d9bc2a33dc4fa0 Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Sat, 26 May 2018 22:12:36 +0100 Subject: [PATCH] qemumonitor: fix for qemu v2.12 Must use expect now for some reason, and I only know how to make it work nicely if the arguments come from CLI arguments instead of stdin. Document it on a dedicated section. Fix #29 --- README.adoc | 99 +++++++++++++++++++++++++++++++++++++---------------- configure | 1 + qemumonitor | 29 +++++++++++++--- 3 files changed, 94 insertions(+), 35 deletions(-) diff --git a/README.adoc b/README.adoc index ba70cc3..6e2cc0e 100644 --- a/README.adoc +++ b/README.adoc @@ -228,32 +228,9 @@ https://superuser.com/questions/1087859/how-to-quit-the-qemu-monitor-when-not-us Alternative methods: -* `echo quit | ./qemumonitor` -* `Ctrl-A C` then `quit` +* `quit` command on the <> * `pkill qemu` -Toggle between QEMU monitor and the shell: - -.... -Ctrl-A C -.... - -* http://stackoverflow.com/questions/14165158/how-to-switch-to-qemu-monitor-console-when-running-with-curses -* https://superuser.com/questions/488263/how-to-switch-to-the-qemu-control-panel-with-nographics - -But doing: - -.... -echo quit | ./qemumonitor -.... - -is generally more practical since you can use host shell functionality like shell history. - -Getting everything to work requires careful choice of QEMU command line options: - -* https://stackoverflow.com/questions/49716931/how-to-run-qemu-with-nographic-and-monitor-but-still-be-able-to-send-ctrlc-to/49751144#49751144 -* https://unix.stackexchange.com/questions/167165/how-to-pass-ctrl-c-to-the-guest-when-running-qemu-with-nographic/436321#436321 - TODO: if you hit `Ctrl-C` several times while `arm` or `aarch64` are booting, after boot the userland shell does not show any updates when you type, this seems to be a bug on the Linux kernel v4.16: http://lists.nongnu.org/archive/html/qemu-discuss/2018-04/msg00027.html === Graphic mode @@ -280,7 +257,7 @@ Text mode has the following limitations over graphics mode: `x86_64` has a VGA device enabled by default, as can be seen as: .... -echo 'info qtree' | ./qemumonitor +./qemumonitor info qtree .... and the Linux kernel picks it up through the link:https://en.wikipedia.org/wiki/Linux_framebuffer[fbdev] graphics system as can be seen from: @@ -2898,6 +2875,12 @@ which shows: so only `1` has `myirqhandler0` attached but not `0`. +The <> also has some interrupt statistics for x86_64: + +.... +./qemumonitor info irq +.... + TODO: properly understand how each IRQ maps to what number. ==== dummy-irq @@ -3757,7 +3740,7 @@ and run: On another shell, take a snapshot: .... -echo 'savevm my_snap_id' | ./qemumonitor +./qemumonitor savevm my_snap_id .... The counting continues. @@ -3765,7 +3748,7 @@ The counting continues. Restore the snapshot: .... -echo 'loadvm my_snap_id' | ./qemumonitor +./qemumonitor loadvm my_snap_id .... and the counting goes back to where we saved. This shows that CPU and memory states were reverted. @@ -3785,7 +3768,7 @@ echo 0 >f Monitor: .... -echo 'savevm my_snap_id' | ./qemumonitor +./qemumonitor savevm my_snap_id .... Guest: @@ -3797,7 +3780,7 @@ echo 1 >f Monitor: .... -echo 'loadvm my_snap_id' | ./qemumonitor +./qemumonitor loadvm my_snap_id .... Guest: @@ -3965,7 +3948,7 @@ which we identify as being `edu` and `pci_min` respectively by the magic numbers Alternatively, we can also do use the QEMU monitor: .... -echo 'info qtree' | ./qemumonitor +./qemumonitor info qtree .... which gives: @@ -4562,6 +4545,62 @@ The current FAQ says it is not possible to use dynamic executables: http://gem5. but I could not find how to actually use it. +=== QEMU monitor + +The QEMU monitor is a terminal that allows you to send text commands to the QEMU VM: https://en.wikibooks.org/wiki/QEMU/Monitor + +Accessed it in either <> and <>: + +.... +./qemumonitor +.... + +or send one command such as `info qtree` and quit the monitor: + +.... +./qemumonitor info qtree +.... + +Source: link:qemumonitor[] + +`qemumonitor` uses the `-monitor` QEMU command line option, which makes the monitor listen from a socket. + +`qemumonitor` does not support input from an stdin pipe currently, see comments on the source for rationale. + +Alternatively, from text mode: + +.... +Ctrl-A C +.... + +and go back to the terminal with: + +.... +Ctrl-A C +.... + +* http://stackoverflow.com/questions/14165158/how-to-switch-to-qemu-monitor-console-when-running-with-curses +* https://superuser.com/questions/488263/how-to-switch-to-the-qemu-control-panel-with-nographics + +And in graphic mode from the GUI: + +.... +Ctrl-Alt ? +.... + +where `?` is a digit `1`, or `2`, or, `3`, etc. depending on what else is available on the GUI: serial, parallel and frame buffer. + +In general, `./qemumonitor` is the best option, as it: + +* works on both modes +* allows to use the host Bash history to re-run one off commands +* allows you to search the output of commands on your host shell even when in graphic mode + +Getting everything to work required careful choice of QEMU command line options: + +* https://stackoverflow.com/questions/49716931/how-to-run-qemu-with-nographic-and-monitor-but-still-be-able-to-send-ctrlc-to/49751144#49751144 +* https://unix.stackexchange.com/questions/167165/how-to-pass-ctrl-c-to-the-guest-when-running-qemu-with-nographic/436321#436321 + === Debug the emulator When you start hacking QEMU or gem5, it is useful to see what is going on inside the emulator themselves. diff --git a/configure b/configure index a759851..6f5d9a0 100755 --- a/configure +++ b/configure @@ -32,6 +32,7 @@ bc \ build-essential \ coreutils \ cpio \ +expect \ git \ unzip \ vinagre \ diff --git a/qemumonitor b/qemumonitor index 30bfb3a..9ef4aed 100755 --- a/qemumonitor +++ b/qemumonitor @@ -1,5 +1,24 @@ -#!/usr/bin/env bash -# We could also use Ctrl + Alt + 2 on the SDL GUI, -# but that opens up a tiny window which can't scroll up or be searched. -# And this is the only way when running in -noscreen. -telnet localhost 45454 +#!/usr/bin/env expect +# Ee have to use expect since QEMU 2.12: just piping commands +# into telnet stopped working at that version. +spawn telnet localhost 45454 +set prompt "\n(qemu) " +expect $prompt +if {$argc > 0} { + send "[concat [join $argv " "]]\r" + expect $prompt +} else { + interact +} + +# In order to treat input from stdin, we would need to differentiate between input from pipe vs terminal. +# For bash we can do it as: +# https://stackoverflow.com/questions/911168/how-to-detect-if-my-shell-script-is-running-through-a-pipe +# but no one knows for Tcl: +# https://stackoverflow.com/questions/43660612/how-to-check-if-stdin-stdout-are-connected-to-a-terminal-in-tcl +# One option would also be to have a bash wrapper that calls this tcl script. +# Related: https://stackoverflow.com/questions/10237872/expect-redirect-stdin +#while {[gets stdin line] > 0} { + #expect $prompt + #send "$line\r" +#}