Skip to content

Instantly share code, notes, and snippets.

@jtpaasch
Last active January 29, 2024 23:18
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save jtpaasch/cb7da88c890a002ab3ae464ca98c7445 to your computer and use it in GitHub Desktop.
Save jtpaasch/cb7da88c890a002ab3ae464ca98c7445 to your computer and use it in GitHub Desktop.
A quick cheatsheet/tutorial for using QEMU (on macOS, but should work on Linux too).

QEMU

Some quick tips for using QEMU from the command line (on macOS, but should work on Linux too).

Creating and booting an image

Download an OS ISO, e.g., the netinstall Debian 9.7 ISO:

wget https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-9.7.0-amd64-netinst.iso

Create a virtual disk:

qemu-img create -f raw -o size=5G debian.9.7.netinst.img

Install the ISO onto the virtual disk:

qemu-system-x86_64 \
    -boot d \
    -cdrom debian-9.7.0-amd64-netinst.iso \
    -m 1024M \
    -hda debian.9.7.netinst.img

This will open a graphical window where you can install the OS off the ISO.

Now boot it:

qemu-system-x86_64 \
    -m 1024M \
    -hda debian.9.7.netinst.img

Using SSH

Start the image, with no VNC server, and connect its port 22 to your host's port 2200:

qemu-system-x86_64 \
    -m 1024M \
    -net nic \
    -net user,hostfwd=tcp::2200-:22 \
    -hda debian.9.7.netinst.img

Connect to it from another terminal:

ssh -p 2200 USER@IP/HOSTNAME

For example:

ssh -p 2200 guest@localhost

Snapshots

Create a snapshot of the image:

qemu-img create \
    -f qcow2 \
    -b debian.9.7.netinst.img \
    debian.9.7.netinst.snapshot.2019-01-11.1118.img

Boot it:

qemu-system-x86_64
    -m 1024M \
    -net nic \
    -net user,hostfwd=tcp::2200-:22 \
    -hda debian.9.7.netinst.snapshot.2019-01-11.1118.img

Headless

To run headless, boot with -vnc set to none:

qemu-system-x86_64 \
    -m 1024M \
    -vnc none \
    -net nic \
    -net user,hostfwd=tcp::2200-:22 \
    -hda debian.9.7.netinst.img

Wait a few minutes for the system to boot, then connect via SSH:

ssh -p 2200 USER@IP/HOSTNAME

Monitor

To send the monitor to your terminal:

qemu-system-x86_64 \
    -m 1024M \
    -net nic \
    -net user,hostfwd=tcp::2200-:22 \
    -hda debian.9.7.netinst.img \
    -monitor stdio

Then issue monitor commands directly:

info version
info status
system_powerdown

To send the monitor to TCP:

qemu-system-x86_64 \
    -m 1024M \
    -net nic \
    -net user,hostfwd=tcp::2200-:22 \
    -hda debian.9.7.netinst.img \
    -monitor tcp:127.0.0.1:55555,server,nowait

Then send monitor commands over TCP with, say, netcat:

echo "info version" | nc 127.0.0.1 55555
echo "info status" | nc 127.0.0.1 55555
echo "system_powerdown" | nc 127.0.0.1 55555

You can also do it with unix sockets.

Cross-compiling OpenSSL for use with qemu-arm:

apt install -y qemu binutils-arm-linux-gnueabi gcc-arm-linux-gnueabi {gcc,g++}-arm-linux-gnueabi cmake
git clone https://github.com/openssl/openssl
git checkout OpenSSL_1_1_1-stable

export CROSS=arm-linux-gnueabi # or arm-linux-gnueabihf
export AR=${CROSS}-ar
export AS=${CROSS}-as
export CC=${CROSS}-gcc
export CXX=${CROSS}-g++
export LD=${CROSS}-ld

./Configure --prefix=/usr/${CROSS} linux-armv4
make
sudo make install
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment