diff options
-rw-r--r-- | qemu-doc.texi | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/qemu-doc.texi b/qemu-doc.texi new file mode 100644 index 0000000000..a7b0ce9f70 --- /dev/null +++ b/qemu-doc.texi @@ -0,0 +1,305 @@ +\input texinfo @c -*- texinfo -*- + +@settitle QEMU x86 Emulator Reference Documentation +@titlepage +@sp 7 +@center @titlefont{QEMU x86 Emulator Reference Documentation} +@sp 3 +@end titlepage + +@chapter Introduction + +QEMU is an x86 processor emulator. Its purpose is to run x86 Linux +processes on non-x86 Linux architectures such as PowerPC or ARM. By +using dynamic translation it achieves a reasonnable speed while being +easy to port on new host CPUs. An obviously interesting x86 only process +is 'wine' (Windows emulation). + +QEMU features: + +@itemize + +@item User space only x86 emulator. + +@item Currently ported on i386 and PowerPC. + +@item Using dynamic translation for reasonnable speed. + +@item The virtual x86 CPU supports 16 bit and 32 bit addressing with segmentation. +User space LDT and GDT are emulated. + +@item Generic Linux system call converter, including most ioctls. + +@item clone() emulation using native CPU clone() to use Linux scheduler for threads. + +@item Accurate signal handling by remapping host signals to virtual x86 signals. + +@item The virtual x86 CPU is a library (@code{libqemu}) which can be used +in other projects. + +@item An extensive Linux x86 CPU test program is included @file{tests/test-i386}. +It can be used to test other x86 virtual CPUs. + +@end itemize + +Current QEMU Limitations: + +@itemize + +@item Not all x86 exceptions are precise (yet). [Very few programs need that]. + +@item Not self virtualizable (yet). [You cannot launch qemu with qemu on the same CPU]. + +@item No support for self modifying code (yet). [Very few programs need that, a notable exception is QEMU itself !]. + +@item No VM86 mode (yet), althought the virtual +CPU has support for most of it. [VM86 support is useful to launch old 16 +bit DOS programs with dosemu or wine]. + +@item No SSE/MMX support (yet). + +@item No x86-64 support. + +@item Some Linux syscalls are missing. + +@item The x86 segment limits and access rights are not tested at every +memory access (and will never be to have good performances). + +@item On non x86 host CPUs, @code{double}s are used instead of the non standard +10 byte @code{long double}s of x86 for floating point emulation to get +maximum performances. + +@end itemize + +@chapter Invocation + +In order to launch a Linux process, QEMU needs the process executable +itself and all the target (x86) dynamic libraries used by it. Currently, +QEMU is not distributed with the necessary packages so that you can test +it easily on non x86 CPUs. + +However, the statically x86 binary 'tests/hello' can be used to do a +first test: + +@example +qemu tests/hello +@end example + +@code{Hello world} should be printed on the terminal. + +If you are testing it on a x86 CPU, then you can test it on any process: + +@example +qemu /bin/ls -l +@end example + +@chapter QEMU Internals + +@section QEMU compared to other emulators + +Unlike bochs [3], QEMU emulates only a user space x86 CPU. It means that +you cannot launch an operating system with it. The benefit is that it is +simpler and faster due to the fact that some of the low level CPU state +can be ignored (in particular, no virtual memory needs to be emulated). + +Like Valgrind [2], QEMU does user space emulation and dynamic +translation. Valgrind is mainly a memory debugger while QEMU has no +support for it (QEMU could be used to detect out of bound memory accesses +as Valgrind, but it has no support to track uninitialised data as +Valgrind does). Valgrind dynamic translator generates better code than +QEMU (in particular it does register allocation) but it is closely tied +to an x86 host. + +EM86 [4] is the closest project to QEMU (and QEMU still uses some of its +code, in particular the ELF file loader). EM86 was limited to an alpha +host and used a proprietary and slow interpreter (the interpreter part +of the FX!32 Digital Win32 code translator [5]). + +@section Portable dynamic translation + +QEMU is a dynamic translator. When it first encounters a piece of code, +it converts it to the host instruction set. Usually dynamic translators +are very complicated and highly CPU dependant. QEMU uses some tricks +which make it relatively easily portable and simple while achieving good +performances. + +The basic idea is to split every x86 instruction into fewer simpler +instructions. Each simple instruction is implemented by a piece of C +code (see @file{op-i386.c}). Then a compile time tool (@file{dyngen}) +takes the corresponding object file (@file{op-i386.o}) to generate a +dynamic code generator which concatenates the simple instructions to +build a function (see @file{op-i386.h:dyngen_code()}). + +In essence, the process is similar to [1], but more work is done at +compile time. + +A key idea to get optimal performances is that constant parameters can +be passed to the simple operations. For that purpose, dummy ELF +relocations are generated with gcc for each constant parameter. Then, +the tool (@file{dyngen}) can locate the relocations and generate the +appriopriate C code to resolve them when building the dynamic code. + +That way, QEMU is no more difficult to port than a dynamic linker. + +To go even faster, GCC static register variables are used to keep the +state of the virtual CPU. + +@section Register allocation + +Since QEMU uses fixed simple instructions, no efficient register +allocation can be done. However, because RISC CPUs have a lot of +register, most of the virtual CPU state can be put in registers without +doing complicated register allocation. + +@section Condition code optimisations + +Good CPU condition codes emulation (@code{EFLAGS} register on x86) is a +critical point to get good performances. QEMU uses lazy condition code +evaluation: instead of computing the condition codes after each x86 +instruction, it store justs one operand (called @code{CC_CRC}), the +result (called @code{CC_DST}) and the type of operation (called +@code{CC_OP}). + +@code{CC_OP} is almost never explicitely set in the generated code +because it is known at translation time. + +In order to increase performances, a backward pass is performed on the +generated simple instructions (see +@code{translate-i386.c:optimize_flags()}). When it can be proved that +the condition codes are not needed by the next instructions, no +condition codes are computed at all. + +@section Translation CPU state optimisations + +The x86 CPU has many internal states which change the way it evaluates +instructions. In order to achieve a good speed, the translation phase +considers that some state information of the virtual x86 CPU cannot +change in it. For example, if the SS, DS and ES segments have a zero +base, then the translator does not even generate an addition for the +segment base. + +[The FPU stack pointer register is not handled that way yet]. + +@section Translation cache + +A 2MByte cache holds the most recently used translations. For +simplicity, it is completely flushed when it is full. A translation unit +contains just a single basic block (a block of x86 instructions +terminated by a jump or by a virtual CPU state change which the +translator cannot deduce statically). + +[Currently, the translated code is not patched if it jumps to another +translated code]. + +@section Exception support + +longjmp() is used when an exception such as division by zero is +encountered. The host SIGSEGV and SIGBUS signal handlers are used to get +invalid memory accesses. + +[Currently, the virtual CPU cannot retrieve the exact CPU state in some +exceptions, although it could except for the @code{EFLAGS} register]. + +@section Linux system call translation + +QEMU includes a generic system call translator for Linux. It means that +the parameters of the system calls can be converted to fix the +endianness and 32/64 bit issues. The IOCTLs are converted with a generic +type description system (see @file{ioctls.h} and @file{thunk.c}). + +@section Linux signals + +Normal and real-time signals are queued along with their information +(@code{siginfo_t}) as it is done in the Linux kernel. Then an interrupt +request is done to the virtual CPU. When it is interrupted, one queued +signal is handled by generating a stack frame in the virtual CPU as the +Linux kernel does. The @code{sigreturn()} system call is emulated to return +from the virtual signal handler. + +Some signals (such as SIGALRM) directly come from the host. Other +signals are synthetized from the virtual CPU exceptions such as SIGFPE +when a division by zero is done (see @code{main.c:cpu_loop()}). + +The blocked signal mask is still handled by the host Linux kernel so +that most signal system calls can be redirected directly to the host +Linux kernel. Only the @code{sigaction()} and @code{sigreturn()} system +calls need to be fully emulated (see @file{signal.c}). + +@section clone() system call and threads + +The Linux clone() system call is usually used to create a thread. QEMU +uses the host clone() system call so that real host threads are created +for each emulated thread. One virtual CPU instance is created for each +thread. + +The virtual x86 CPU atomic operations are emulated with a global lock so +that their semantic is preserved. + +@section Bibliography + +@table @asis + +@item [1] +@url{http://citeseer.nj.nec.com/piumarta98optimizing.html}, Optimizing +direct threaded code by selective inlining (1998) by Ian Piumarta, Fabio +Riccardi. + +@item [2] +@url{http://developer.kde.org/~sewardj/}, Valgrind, an open-source +memory debugger for x86-GNU/Linux, by Julian Seward. + +@item [3] +@url{http://bochs.sourceforge.net/}, the Bochs IA-32 Emulator Project, +by Kevin Lawton et al. + +@item [4] +@url{http://www.cs.rose-hulman.edu/~donaldlf/em86/index.html}, the EM86 +x86 emulator on Alpha-Linux. + +@item [5] +@url{http://www.usenix.org/publications/library/proceedings/usenix-nt97/full_papers/chernoff/chernoff.pdf}, +DIGITAL FX!32: Running 32-Bit x86 Applications on Alpha NT, by Anton +Chernoff and Ray Hookway. + +@end table + +@chapter Regression Tests + +In the directory @file{tests/}, various interesting x86 testing programs +are available. There are used for regression testing. + +@section @file{hello} + +Very simple statically linked x86 program, just to test QEMU during a +port to a new host CPU. + +@section @file{test-i386} + +This program executes most of the 16 bit and 32 bit x86 instructions and +generates a text output. It can be compared with the output obtained with +a real CPU or another emulator. The target @code{make test} runs this +program and a @code{diff} on the generated output. + +The Linux system call @code{modify_ldt()} is used to create x86 selectors +to test some 16 bit addressing and 32 bit with segmentation cases. + +@section @file{testsig} + +This program tests various signal cases, including SIGFPE, SIGSEGV and +SIGILL. + +@section @file{testclone} + +Tests the @code{clone()} system call (basic test). + +@section @file{testthread} + +Tests the glibc threads (more complicated than @code{clone()} because signals +are also used). + +@section @file{sha1} + +It is a simple benchmark. Care must be taken to interpret the results +because it mostly tests the ability of the virtual CPU to optimize the +@code{rol} x86 instruction and the condition code computations. + |