http://tipc.wiki.sourceforge.net/QEMU+Cheat+Sheet
QEMU Cheat Sheet
- author: Allan Stephens
- last updated: 29 August 2008
Installing QEMU on a Linux host
- Method 1: use pre-compiled software
- Method 2: compile software from source (see NOTE below)
- get latest stable version
- (alternatively) get latest development version
- cd <qemu root directory>
- ./configure (usually no options are required)
- (root) make install (seems to do both "make" and "make
install")
- NOTE: you must have GCC version 3 available, as QEMU
won't work right under GCC v4
- if needed, can install GCC v3 as follows:
- download GCC v3.4 module (Google located
compat-gcc-34-3.4.6-4.i386.rpm)
- rpm -ivh compat-gcc-34-3.4.6-4.i386.rpm (must be root
user)
- (optional) install QEMU accelerator module (see NOTEs below to
check if it's worthwhile)
- download http://fabrice.bellard.free.fr/qemu/kqemu-1.3.0pre11.tar.gz
- gunzip kqemu-1.3.0pre11.tar.gz
- tar xf kqemu-1.3.0pre11.tar
- cd kqemu-1.3.0pre11
- ./configure (usually no options are required)
- make (got a warning at the end, but didn't seem to matter …)
- (root) make install
- (root) /sbin/modprobe kqemu (can also set up system to do
this automatically)
- NOTE: KQEMU is incompatible with a Linux target built with GCC
v4 (gives boot errors!)
- NOTE: KQEMU source code builds properly with GCC version 4
(unlike QEMU)
- NOTE: KQEMU may provide significant benefits (when used with a
GCC v3 Linux target)
eg. time to boot system (from start up until login prompt):
- with no acceleration (invoke QEMU with -no-kqemu option):
36 sec
- with user mode acceleration (invoke QEMU normally): 25 sec
- with user mode & kernel acceleration (invoke QEMU with
-kernel-kqemu option): 21 sec
Starting up a QEMU Linux guest on a Linux
host
- there is a lengthy User Guide at http://fabrice.bellard.free.fr/qemu/user-doc.html
- WARNING:
this document contains a lot of useful information, but it is more of a
reference guide than a tutorial—it's not the easiest thing in the world
to learn from!
- QEMU guest is invoked by: (root) qemu <options>
- NOTE:
you don't always have to be "root" on host, but I found this convenient
to avoid running into permission problems when trying to access host
system resources from a QEMU guest
- typical invocation uses the following options:
- -kernel <bzImage>
- overrides the default kernel supplied with guest's
filesystem (see below)
- this is handy if you are developing Linux kernel code
- to create a bzImage file:
- go to top level Linux source directory
- make [ARCH=<arch>] menuconfig
- make [ARCH=<arch>] bzImage
- output file is stored in
arch/<arch>/boot/bzImage
- NOTE: can omit ARCH if Linux host and target
architectures are the same
- -append "root=/dev/hda console=ttyS0"
- passes startup options to Linux kernel
- NOTE: there are additional options—see Linux kernel
documentation …
- "root=" specifies location of Linux filesystem
- can omit this if not using "-kernel" option
- "console=" directs console output to guest machine's
serial port
- can omit this if not using "-nographic"
option (see below)
- -hda <filesystem>
- tells QEMU to make Linux filesystem visible to guest OS
as /dev/hda
- see "How to create or modify a QEMU guest's filesystem"
for help on setting this up
- -snapshot
- tells QEMU to use COW-file approach for Linux filesystem;
COW = "copy on write"
- QEMU won't modify filesystem unless specifically told to
by user
- -no-kqemu
- tells QEMU not to use hardware accelerator (even if it is
installed)
- -nographic
- tells QEMU not to fire up VGA display window
- -smp <N>
- tells QEMU how many CPUs to run—only useful when using an
SMP-enabled kernel
- specify 1 CPU unless you have a good reason not to (more
CPUs = slower QEMU runs)
- this will cause your shell to enter the QEMU monitor (see
below), and then immediately start up the QEMU guest and display the
output of its serial port
- the serial port will display the start up messages for your
Linux guest's console
- NOTE: you won't be able to log in to your Linux guest
unless the guest's filesystem has been configured to support this (see
below)
A useful shell script for invoking a QEMU
Linux guest on a Linux host
#! /bin/csh -f
# Standard script for initializing a QEMU session
#
# - typically invoked from top level directory of Linux kernel source tree
# for kernel image to be used
# - requires a single argument to identify the session (a digit from 1 to 9);
# this is used to generate:
# - unique MAC addresses for Ethernet ports
# - a unique serial port that can be used to login via telnet
# - define KERNEL below to identify kernel image to use
# - define ROOTFS below to identify Linux filesystem that image uses
# - define ALTFS below to identify secondary filesystem that image uses
# [NOTE: can omit 2nd filesystem if not needed]
set N = $argv[1]
set KERNEL = "./arch/i386/boot/bzImage"
set ROOTFS = "/home/<your userid>/<main filesystem>"
set ALTFS = "/home/<your userid>/<secondary filesystem>"
# System is configured to use:
# - kernel at location specified by KERNEL
# - /dev/hda1 is main Linux filesystem (at location specified by ROOTFS)
# - /dev/hdb1 is secondary filesystem (at location specified by ALTFS)
# - eth0 and eth1 are configured with (hopefully unique) MAC addresses;
# they communicate with other guests using host UDP multicasting on VLANs
# (in a UML-compatible manner)
# - ttyS0 is the system console
# - to get login prompt, enable "getty" for ttyS0 in guest's /etc/inittab
# - ttyS1 is accessed via telnet on host's port 44xx
# - to connect, enter "telnet localhost 44xx" on host
# - to get login prompt, enable "getty" for ttyS1 in guest's /etc/inittab
# - to allow root logins, add ttyS1 to guest's /etc/securetty
qemu \
-kernel ${KERNEL} \
-append "root=/dev/hda console=ttyS0" \
-snapshot \
-hda ${ROOTFS} \
-hdb ${ALTFS} \
-net nic,vlan=0,model=rtl8139,macaddr=02:00:${N}:${N}:${N}:02 \
-net socket,vlan=0,mcast=239.192.168.1:1102 \
-net nic,vlan=1,model=rtl8139,macaddr=02:00:${N}:${N}:${N}:03 \
-net socket,vlan=1,mcast=239.192.168.1:1103 \
-serial stdio \
-serial telnet:localhost:4${N}${N}0,server,nowait \
-smp 1 \
-no-kqemu \
-nographic \
# OTHER USEFUL OPTIONS
# To enable floppy disk usage:
# -fda /dev/fd0 \
# To activate gdb server:
# -s \
Running a QEMU Linux guest
- QEMU provides 2 window buffers when invoked with "-nographic"
- the QEMU monitor
- can use this for various control/debugging operations
(see QEMU documentation)
- the guest's serial port (typically /dev/ttyS0)
- allows you to log in to QEMU guest, and to see console
output
- NOTE: you won't be able to log in to your Linux
guest unless the guest's filesystem has been configured to support this
(see below)
- important key sequences to know:
- Ctrl-a c
- switch between serial port and QEMU monitor window buffers
- Ctrl-a x
- terminate QEMU
- alternate method: enter "quit" in the QEMU monitor window
buffer
- Ctrl-a s
- save disk data back to file (overrides "-snapshot" option)
- to enable logins via the guest's serial port:
- ensure the Linux guest's /etc/inittab file has a line like
the following:
- T0:23:respawn:/sbin/getty -L ttyS0 38400 vt100
- this tells Linux to listen for logins on /dev/ttyS0
- there was already a line like this in the filesystem I was
using, but it was commented out
- to login to a Linux guest
- Ubuntu provides default user of "root", with no password
(i.e. just hit enter when prompted)
- NOTE: this process can vary, depending on the Linux
distribution your guest's filesystem has
How to create or modify a QEMU guest's
filesystem
- QEMU requires a Linux filesystem image for your QEMU guest to use
- easiest approach is to get a pre-built filesystem image from
another QEMU user!
- if none is available, http://uml.nagafix.co.uk/
has filesystems for a variety of Linux distributions
- you can use a filesystem for a different distribution
than the one your host uses
- the
Ubuntu Breezy [Badger] distribution worked for me (even though I was
running on a Fedora core host), but I had to manually add in developer
packages to allow the guest to compile applications
- download a copy of filesystem to a directory that isn't
your kernel source tree
- use "bunzip2" to decompress filesystem
- the filesystem file can be very large (eg. 2G file
for Ubuntu!)
- specify the filesystem file as the "-hda" argument when
invoking QEMU
- using QEMU's "-snapshot" option means that any changes made by
Linux guest are not written back to the filesystem image on the
host, unless requested
- this allows multiple guests to share a single filesystem image
- a guest sees any changes it makes while running, but not
changes made by other guests
- when a guest terminates, all of its changes are lost
- guest changes can be forceably written back to
filesystem image via QEMU monitor commands
- i.e. "Ctrl-a s" in non-graphical mode, or "commit hda" in
graphical mode
- IMPORTANT: don't do this if multiple guests are sharing
the filesystem image!
- if desired, you can make changes to the filesystem image from
your host
- IMPORTANT: QEMU guest won't pick up filesystem
changes that are made after it starts up
- best policy is terminate QEMU guests before making any
changes
- IMPORTANT: you need administrator privileges to do this
- typical steps:
- mkdir <mount_dir>
- creates a mount point for host to mount the
filesystem on
- (root) mount <filesystem_image> <mount_dir>
-o loop
- alternate form: mount -oloop=/dev/loop0
<filesystem_image> <mount_dir>
- cd <mount_dir>
- can now look at/manipulate files in filesystem
- (root) umount <mount_dir>
- now safe to start up QEMU guest(s)
- VERY IMPORTANT!!!
- Linux increments a
filesystem's "mount count" each time it is mounted (either by the host
or a guest); after a certain number of mounts Linux checks if the
filesystem has become corrupted
- if a QEMU guest
reports a problem with the integrity of its filesystem, terminate the
guest and fix the filesystem image on the host
- (root) losetup /dev/loop0 <filesystem_image>
- (root) fsck /dev/loop0
- this checks the filesystem; you may be asked to OK
the fixes it wants to make
- you might want to backup the filesystem image before
checking it, just to be safe
- (root) losetup -d /dev/loop0
Using a secondary filesystem with a QEMU
guest
- it is sometime desirable to supply a Linux guest with a second
filesystem
- eg. allow guest to use tipc-config, TIPC test suite, or other
standard applications
- eg. allow multiple guests to share main filesystem in
read-only manner, but have their own writeable files (or vice versa)
- invoke QEMU with "-hdb <disk_image>" option
- this maps <disk_image> file on host to target's /dev/hdb
- tell QEMU to mount disk image
- (qemu) mkdir host_fs
- (qemu) mount /dev/hdb1 host_fs
- (qemu) ls host_fs [this should display files that are present
in the disk image]
- how to create a disk image from scratch
- info taken from: http://www.osdev.org/osfaq2/index.php/Disk%20Images%20Under%20Linux
- IMPORTANT! you need administrator privileges to do this
- create a 500MB disk image file called "disk.img"
- (root) dd if=/dev/zero of=disk.img bs=516096c count=1000
- (root) losetup /dev/loop0 disk.img
- (root) fdisk -u -C1000 -S63 -H16 /dev/loop0
- [command prompts for disk formatting commands—ignore
errors/warnings]
- o (create empty partition table)
- n (create a new partition, called #1)
- w (write out results & exit)
- (root) losetup -d /dev/loop0
- convert disk image into a Linux ext2 filesystem
- (root) losetup -o32256 /dev/loop0 disk.img
- (root) mke2fs -b1024 /dev/loop0 503968
- add files to disk image
- (root) mkdir <mount directory>
- (root) mount -text2 /dev/loop0 <mount directory>
- (root) cd <mount directory>
- … add files …
- (root) umount /dev/loop0
- (root) losetup -d /dev/loop0
- subsequent host updates to disk image can be done in a
simpler manner
- (root) mount -text2 -oloop=/dev/loop0,offset=32256
disk.img <mount directory>
- … play with files …
- (root) umount disk.img
- IMPORTANT!
- any changes to disk image by guest OS are lost unless they
are written back to disk image
- (qemu) umount hostfs
- (qemu monitor) commit hdb
Using a floppy drive with a QEMU guest
- in some case it may be desirable to allow a Linux guest to access
a floppy drive (either real or simulated)
- eg. allow a running Linux guest to get new files from host
system
- IMPORTANT!
you need administrator privileges to do this
- when invoking QEMU use "-fda /dev/fd0" option
- this maps host's /dev/fd0 to target's /dev/fda
- once QEMU is running mount /dev/fda
- (qemu) mkdir floppy
- (qemu) mount /dev/fda floppy
- IMPORTANT!
you need to use QEMU Monitor to tell QEMU when floppy disk is
inserted/ejected/changed
- (qemu monitor) change fda /dev/fd0
- QEMU should now access disk contents
- you should now be able to access files on floppy drive
- (qemu) ls floppy
- should see list of files on host's floppy drive
- CAUTION!
QEMU changes contents of floppy disk even when running with "-snapshot"
option!
- I'm not sure if this is true if you do "-fda <floppy image
file>", but you can change a real disk if you specify "-fda
/dev/fd0"
Setting up networking for a QEMU guest
- can easily set up simple multicast-based networking (à la UML)
- this form of networking allows your QEMU and UML guests to
communicate with each other, but not with your host and/or the
Internet
- "real" networking is possible, but isn't (yet) documented
here—see QEMU documentation …
- specify both of the following options when invoking QEMU:
-net
nic[,vlan=<N>][,model=<type>][,macaddr=xx:xx:xx:xx:xx:xx]
-net socket,mcast=239.192.1681.1:1102
- the first option specifies the NIC to use
- the optional "vlan" field let you to have multiple NICs,
if desired; the default <N> is 0
- NOTE:
it's unclear if you can have multiple NICs on the same VLAN or not;
this might conceivably work if you use different multicast ports (eg.
1103, 1104, etc.); I'm also unsure how to tell UML which VLAN to use …
- the second option indicates that UDP multicasting is used as
transport
- IMPORTANT!
make sure your target kernel supports the model of Ethernet card you
are using
- specifying a model of "rtl8139" gives an RTL 8139-based card,
whose driver is included in the default Linux kernel
configuration
- omitting the model info gives an NE2000-based card, whose
driver isn't included in the default Linux kernel
configuration; you can include the driver by following the menuconfig
path:
- >> device drivers --> network device support -->
Ethernet (10 or 100Mbit) --> PCI NE2000 and clone support
Running QEMU in graphical mode
- if desired, you can run QEMU in graphical mode, which emulates a
VGA display
- this is handy for people who want to run Windows on a Linux
host (or vice versa)
- not particularly useful for a typical developer who is making
changes to the Linux kernel
- to obtain graphical mode
- ensure QEMU has been built with graphical capabilities (which
is the default)
- NOTE: host must support SDL development library
- invoke QEMU without "-nographic" option
- QEMU should pop up a virtual console window when it is
invoked
- you should probably remove the "console=ttyS0" part of the
"-append" option, too
- ensures the Linux guest's startup messages appear in main
virtual console window,
- >> >>> rather than the (initially hidden) serial
port window
- QEMU's virtual console provides 3 window buffers:
- main window buffer is the target's virtual console
- provides simulated VGA display and keyboard
- use CTL-ALT-1 to select this window
- use SHIFT-PageUp/PageDown to scroll back and forth in
this window
- secondary window buffer is the QEMU Monitor
- can use this for various control/debugging operations
(see QEMU documentation)
- use CTL-ALT-2 to select this window
- use CTL-Up/Down/PageUp/PageDown to scroll back and forth
in this window
- third window buffer is the target's serial port (typically
/dev/ttyS0)
- use CTL-ALT-3 to select this window
- use CTL-Up/Down/PageUp/PageDown to scroll back and forth
in this window
- fourth window buffer is the target's parallel port
- use CTL-ALT-4 to select this window
- if serial port has been redirected, use CTL-ALT-3
instead …
- use CTL-Up/Down/PageUp/PageDown to scroll back and forth
in this window
- use CTL-ALT to toggle mouse/keyboard focus out of virtual console
- allows you to access other windows on host in normal manner
Debugging with QEMU on Linux host
- can use GDB to debug target (in the same way as with UML)
- NOTE:
I haven't figured out how to debug an SMP target with more than 1 CPU
using GDB; how does GDB know which CPU it's talking to/about?;
hopefully, when UML support for SMP is added it will be possible to
simply attach GDB to the process representing each CPU …
- IMPORTANT!
make sure you compile target kernel with debugging symbols enabled
- symbols aren't included in the default Linux kernel
configuration; to include them, follow the menuconfig path:
- >> Kernel hacking --> Compile the kernel with debugging
info
- start QEMU with "-s" option
- this tells QEMU to listen for gdb on port 1234 when it tries
to connect later on
- you can also use QEMU Monitor to do this if you didn't do it
at startup
- start GDB
- (host) gdb vmlinux
- (gdb) … [set breakpoints, etc.]
- (gdb) target remote localhost:1234
- (gdb) c [to continue execution of QEMU]
- IMPORTANT!
- I encountered problems in
getting QEMU to resume from a breakpoint on my first host (although
things seemed to work properly on a different host that uses a later
kernel)
- I'm not sure if there was a problem with the
host system or with the target kernel being tested— there was an error
message from the target about NMI not working properly that may relate
to this …
- only known workaround was to disable
breakpoint, continue execution to next breakpoint, then re-enable the
disabled breakpoint—this is tiresome, but it works (note: couldn't use
"step" and "next", since they didn't work either)
Redirecting console output with QEMU on
a Linux host
- this may be useful if you need to capture "oops" information or
boot time messages when running QEMU in graphical mode
- to simply read the info, use SHIFT-PageUp/PageDown in
the main virtual console window
- there
may be some way to get the host's windowing system to cut-n-paste info
in the main virtual console window, but I haven't found it …
- tell QEMU to redirect console output to /dev/ttyS0, rather than
the main virtual console window
- add "console=ttyS0" to the -append option when invoking QEMU
- IMPORTANT!
- >> you won't see most normal boot messages displayed in the
virtual console anymore,
- >> but if you wait long enough you should eventually see
the normal login prompt
- to see redirected console output, switch to virtual console's
serial port "window" via CTL-ALT-3
- can now see console output
- can scroll up using CTL-Up and CTL-PageUp, etc., as described
in documentation
- toggle back to main virtual console window via CTL-ALT-1 when
done
- to capture console output, must also redirect QEMU's serial port
output to a Telnet session
- add "console=ttyS0" to the -append option, as described above
- add "-serial tcp::1235,server" option
- tells QEMU to wait for connection on host port 1235
before booting up
- can use a different port number, if desired
- once QEMU begins booting it will stop and wait for you to
connect to serial port
- connect to target's serial port from another window
- telnet localhost 1235
- QEMU should now continue booting
- telnet window will display console output
- can use this window's scroll bar to see previous out; can cut
& paste to save output; etc.
- QEMU provides a variety of other ways of capturing console
output, such as saving it to a file, etc.
- see QEMU documentation for further details
QEMU Internals
- QEMU uses the following physical memory map for i386 guests
- physical address 0000 0000: RAM (ram_size = 128MB)
- physical address 0800 0000: VGA RAM (vga_ram_size = 8MB)
- physical address 0880 0000: BIOS (bios_size = 320KB)
- QEMU uses a 4KB page size for physical memory, plus a 2-stage
page table
- upper 10 bits of physical address = array index in L1 paging
array
- each array entry is a pointer to a L2 paging array
- next 10 bits of physical address = array index in L2 paging
array
- L2 paging arrays are dynamically allocated; only created
if QEMU registers some use of that memory region
- each
array entry specifies offset of page from start of physical memory
array in upper 20 bits; lower 12 bits are 0 for normal physical memory,
but non-zero for I/O memory—this allows QEMU to recognize when it is
accessing memory associated with an I/O device (in which case it
invokes the callback routine for the associated device to handle the
read or write operation, rather than simply reading or storing the data
in the physical memory array)
- low 12 bits of physical address = offset within a 4096 byte
page of physical memory array
- physical memory array is dynamically allocated
- phys_ram_size = 128MB + 8MB + 320KB, by default
Installing QEMU on a Windows host
- obtain QEMU pre-compiled software from http://www1.interq.or.jp/~t-takeda/qemu/
- download qemu-0.9.0-windows.zip file
- unzip file to create qemu-0.9.0-windows folder
- that's it! (no need to run an installer)
- to test installation, double click "qemu-win.bat" file
- should boot up a very basic Linux installation using supplied
"linux.img" filesystem
- to exit, type "CTL-ALT-2" to enter QEMU Monitor, then enter
"quit"
- to install the optional QEMU accelerator module, do the following:
- get software from http://fabrice.bellard.free.fr/qemu/download.html
- decompress & untar the software
- in Windows Explorer, right click on "kqemu.inf" and select
"Install"
- you can uninstall it using the normal Add/Remove softwre
control panel
- open a DOS command window and enter "net start kqemu"
- NOTE: I'm not sure if you need to restart this if you
reboot your Windows host, or whether it will restart automatically …
- you can also stop it via "net stop kqemu"
- add the "-kernel-kqemu" when invoking QEMU (see below)
- if things don't seem to work properly try adding the
"-no-acpi" option as well
- NOTE:
when I tried this, QEMU didn't seem to enable the accelerator
properly—it's unclear if the precompiled Windows code has the
accelerator capability enabled; the accelerator documentation says you
don't get much improvement when running Linux 2.6 targets anyway
(although maybe this only applies to Linux hosts?), so I haven't
bothered pursuing things further
Running QEMU Linux target on a Windows
host
- create shortcut for "qemu.exe", then modify start up properties
so that "Target" is:
"<QEMU folder>\qemu.exe" -L . -kernel <bzImage> -append
"root=/dev/hda" -snapshot -hda <filesystem>
- -L option tells QEMU to look for BIOS file in main QEMU folder
- -kernel <bzImage> allows you to replace default kernel
supplied with Linux filesystem
- to create a bzImage file:
- go to top level Linux source directory
- make [ARCH=<arch>] menuconfig
- make [ARCH=<arch>] bzImage
- output file is stored in arch/<arch>/boot/bzImage
- note:
I built Linux kernels on my Linux host, then copied them to my Windows
host; since both machines are 386-based, there was no need to specify
ARCH when building
- -append option tells QEMU where to find root of filesystem
- do this if using -kernel option
- -hda option tells QEMU where to find Linux's filesystem
- can use same filesystem as with UML (eg. a Ubuntu-based
one)
- -snapshot tells QEMU to use COW-file approach for Linux
filesystem
- i.e. don't modify original filesystem—safest approach to
take
- example:
- copy bzImage file to QEMU folder
- copy Ubuntu_buildtools_fs to QEMU folder
- create shortcut with properties:
- >> "C:\Documents and
Settings\astephen\Desktop\qemu-0.9.0-windows\qemu.exe" -L . -kernel
bzImage -append "root=/dev/hda" -snapshot -hda Ubuntu_buildtools_fs
Running QEMU in SMP mode on Windows host
- ensure that you have built an SMP-enabled kernel
- when invoking QEMU use "-smp <N>" option to specify # of
CPUs to start up
- note:
you may be able to get a faster startup by adding something like
"lpj=10000000" to the -append option string; this tells QEMU how many
"loops per jiffy" the host executes, so it doesn't have to run a test
to figure this out for itself
- WARNING: currently seem to be able to bring up at most 2 CPUs
- may be caused by use of hyperthreading on Windows host—need
to disable this to confirm …
Accessing filesystem on Windows host
- ensure Linux kernel has support for Windows filesystem
- in my case, needed to add support for NTFS filesystem
- >> (Linux support for this is somewhat rudimentary—probably
best to use in read-only fashion)
- add "-hdb" to -append option when invoking QEMU
- this maps C: drive (on my Windows PC) to /dev/hdb
- once QEMU is running, mount /dev/hdb1 (note: the extra '1' at the
end is required)
- (qemu) mkdir hostfs
- (qemu) mount /dev/hdb1 hostfs
- (qemu) ls hostfs
- should see list of files on C: drive
- CAUTION:
QEMU seems to cache its view of the filesystem when it is mounted, so
if you add files to the C: drive you won't be able to see them until
you unmount and remount things (ugh!)
|