diff options
28 files changed, 8 insertions, 9868 deletions
@@ -566,9 +566,7 @@ 428d0d82EdPp1TqJBembLgyB1y413w tools/ioemu/COPYING.LIB 428d0d82fd6-QydvFfHmeQBGrKnrrA tools/ioemu/Changelog 428d0d82xvTj4yzPYiurazyGj1PaEw tools/ioemu/Makefile -428d0d82dUmXkgIy11G-hoKTkhvkfQ tools/ioemu/Makefile.target 428d0d82HvgRPoyU3f60_u_t1L28Ag tools/ioemu/README -428d0d820gXmfIVHub7p9VbT7bQcMw tools/ioemu/README.distrib 428d0d82aoWewa_6Z5kNUTgkRw0wNg tools/ioemu/TODO 428d0d82WYi8vrG7RKKyIJw01DAnGg tools/ioemu/VERSION 428d0d82wB05ibBxTCSsAhz3qRO7Gg tools/ioemu/block-cloop.c @@ -680,36 +678,14 @@ 428d0d89GgbrVx4Ov3Zg-SFX_0BRdw tools/ioemu/pc-bios/vgabios-cirrus.bin 428d0d89h9nqxPIgDpPMXZIWkdosNw tools/ioemu/pc-bios/vgabios.bin 428d0d8908B65zMmhdGVME3jv7gpww tools/ioemu/qemu-binfmt-conf.sh -428d0d89eKfKJmNEURTxLUtIjclvDw tools/ioemu/qemu-doc.html -428d0d89jF9HlGboO7nLco-tqjLJqQ tools/ioemu/qemu-doc.texi 428d0d89taY6NPlnIyOAMQd_Ww5qUw tools/ioemu/qemu-img.c -428d0d89uGqd5VkBf5j3HFIkQMxsNA tools/ioemu/qemu-mkcow.1 -428d0d8941iGGM85zXzn4wSj6zgbQg tools/ioemu/qemu-tech.html -428d0d89IkHVfdVTilpTpxDvOCOiIw tools/ioemu/qemu-tech.texi -428d0d89ME4klwpFGjbiKXQrj2KF7A tools/ioemu/qemu.1 428d0d89FY-g4UPH-ZW7t5ZCqvQVTQ tools/ioemu/readline.c 428d0d89dLURbktZFufDKSHan01GFg tools/ioemu/sdl.c +428d0d82dUmXkgIy11G-hoKTkhvkfQ tools/ioemu/target-i386-dm/Makefile 428d0d8atdIE_8ACJPPii5_asQNafw tools/ioemu/target-i386-dm/device-model 428d0d8ahpRAYl6s_itBxnTcxyMHaQ tools/ioemu/target-i386-dm/helper2.c 428d0d8aU3Moaq4zNW5QMV_NxD-4XA tools/ioemu/target-i386-dm/qemu-ifup 428d0d8aqidj8n5H2_2qhBV0mIIJzA tools/ioemu/target-i386-dm/qemu-vgaram-bin.gz -428d0d8ahJ-jctJYDXyAMh91-ifrmg tools/ioemu/tests/Makefile -428d0d8ax12h3Jd3Vhw4nh-eG99-iQ tools/ioemu/tests/hello-arm.c -428d0d8acsBcsGQPd0qQllU-4c9fXw tools/ioemu/tests/hello-i386.c -428d0d8aSEf5Q4wB3iaEThUssfFH8w tools/ioemu/tests/linux-test.c -428d0d8a_orWq4Mg5EasDj2l6f4a0w tools/ioemu/tests/pi_10.com -428d0d8aBv9VBjblSU8iAaVojF4qqw tools/ioemu/tests/qruncom.c -428d0d8az-0qSZDA45Mt6y2SdsqF4w tools/ioemu/tests/runcom.c -428d0d8aSf3jnF_aFvwAemDeROZcKQ tools/ioemu/tests/sha1.c -428d0d8aBZGfRZ662SQIuXLdpmih0w tools/ioemu/tests/test-i386-code16.S -428d0d8a8DbLZWzSyVQ_wX1RGr9SVQ tools/ioemu/tests/test-i386-muldiv.h -428d0d8aaMQbnc_vqyQyOcUzyVrXyg tools/ioemu/tests/test-i386-shift.h -428d0d8aKYkFtFSCFHFUivErvx0iqg tools/ioemu/tests/test-i386-vm86.S -428d0d8aHx2CzT77VEsXouep7lZaYQ tools/ioemu/tests/test-i386.c -428d0d8aDSIoqxC4_zr2z8vxMKrmeA tools/ioemu/tests/test-i386.h -428d0d8ajPT5QfGuunOvjNibmURtqQ tools/ioemu/tests/test_path.c -428d0d8bPccWrah4Y_zICBNZ5exhDw tools/ioemu/tests/testthread.c -428d0d8b5F7EB4JnUbdTi_SZvF2wXg tools/ioemu/texi2pod.pl 428d0d8bMq0ZpccpHb1iVvSNbJjRxg tools/ioemu/thunk.c 428d0d8b2PYfwKLLShlnWcM3VWq9ag tools/ioemu/thunk.h 428d0d8bfvbYQwj6MgDr958m4_SfRA tools/ioemu/vgafont.h diff --git a/tools/ioemu/Makefile b/tools/ioemu/Makefile index fc38fde186..391193e73b 100644 --- a/tools/ioemu/Makefile +++ b/tools/ioemu/Makefile @@ -14,7 +14,7 @@ TOOLS=qemu-img ifdef CONFIG_STATIC LDFLAGS+=-static endif -DOCS=qemu-doc.html qemu-tech.html qemu.1 +#DOCS=qemu-doc.html qemu-tech.html qemu.1 all: $(DOCS) HEADERS for d in $(TARGET_DIRS); do \ @@ -31,7 +31,7 @@ clean: # avoid old build problems by removing potentially incorrect old files rm -f config.mak config.h op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS qemu.pod *~ */*~ - $(MAKE) -C tests clean + #$(MAKE) -C tests clean for d in $(TARGET_DIRS); do \ $(MAKE) -C $$d $@ || exit 1 ; \ done @@ -58,11 +58,11 @@ endif pc-bios/ppc_rom.bin \ pc-bios/proll.bin \ pc-bios/linux_boot.bin "$(DESTDIR)/$(datadir)" - mkdir -p "$(DESTDIR)/$(docdir)" - install -m 644 qemu-doc.html qemu-tech.html "$(DESTDIR)/$(docdir)" + #mkdir -p "$(DESTDIR)/$(docdir)" + #install -m 644 qemu-doc.html qemu-tech.html "$(DESTDIR)/$(docdir)" ifndef CONFIG_WIN32 - mkdir -p "$(DESTDIR)/$(mandir)/man1" - install qemu.1 qemu-mkcow.1 "$(DESTDIR)/$(mandir)/man1" + #mkdir -p "$(DESTDIR)/$(mandir)/man1" + #install qemu.1 qemu-mkcow.1 "$(DESTDIR)/$(mandir)/man1" mkdir -p "$(DESTDIR)/$(datadir)/keymaps" install -m 644 $(addprefix keymaps/,$(KEYMAPS)) "$(DESTDIR)/$(datadir)/keymaps" endif diff --git a/tools/ioemu/README.distrib b/tools/ioemu/README.distrib deleted file mode 100644 index a1598a2998..0000000000 --- a/tools/ioemu/README.distrib +++ /dev/null @@ -1,16 +0,0 @@ -Information about the various packages used to build the current qemu -x86 binary distribution: - -* gcc 2.95.2 was used for the build. A glibc 2.1.3 Debian distribution - was used to get most of the binary packages. - -* wine-20020411 tarball - - ./configure --prefix=/usr/local/wine-i386 - - All exe and libs were stripped. Some compile time tools and the - includes were deleted. - -* ldconfig was launched to build the library links: - - qemu-i386 /usr/gnemul/qemu-i386/bin/ldconfig-i386 -C /usr/gnemul/qemu-i386/etc/ld.so.cache diff --git a/tools/ioemu/configure b/tools/ioemu/configure index ea9d039aa4..ce11ed3de5 100755 --- a/tools/ioemu/configure +++ b/tools/ioemu/configure @@ -504,7 +504,7 @@ if test "$target_user_only" = "no" ; then mkdir -p $target_dir/slirp fi -ln -sf $source_path/Makefile.target $target_dir/Makefile +#ln -sf $source_path/Makefile.target $target_dir/Makefile echo "# Automatically generated by configure - do not modify" > $config_mak echo "/* Automatically generated by configure - do not modify */" > $config_h diff --git a/tools/ioemu/qemu-doc.html b/tools/ioemu/qemu-doc.html deleted file mode 100644 index 2192530827..0000000000 --- a/tools/ioemu/qemu-doc.html +++ /dev/null @@ -1,1793 +0,0 @@ -<HTML> -<HEAD> -<!-- Created by texi2html 1.56k from qemu-doc.texi on 19 May 2005 --> - -<TITLE>QEMU CPU Emulator User Documentation</TITLE> -</HEAD> -<BODY> -<H1>QEMU CPU Emulator User Documentation</H1> -<P> -<P><HR><P> -<H1>Table of Contents</H1> -<UL> -<LI><A NAME="TOC1" HREF="qemu-doc.html#SEC1">1. Introduction</A> -<UL> -<LI><A NAME="TOC2" HREF="qemu-doc.html#SEC2">1.1 Features</A> -</UL> -<LI><A NAME="TOC3" HREF="qemu-doc.html#SEC3">2. Installation</A> -<UL> -<LI><A NAME="TOC4" HREF="qemu-doc.html#SEC4">2.1 Linux</A> -<LI><A NAME="TOC5" HREF="qemu-doc.html#SEC5">2.2 Windows</A> -<LI><A NAME="TOC6" HREF="qemu-doc.html#SEC6">2.3 Mac OS X</A> -</UL> -<LI><A NAME="TOC7" HREF="qemu-doc.html#SEC7">3. QEMU PC System emulator invocation</A> -<UL> -<LI><A NAME="TOC8" HREF="qemu-doc.html#SEC8">3.1 Introduction</A> -<LI><A NAME="TOC9" HREF="qemu-doc.html#SEC9">3.2 Quick Start</A> -<LI><A NAME="TOC10" HREF="qemu-doc.html#SEC10">3.3 Invocation</A> -<LI><A NAME="TOC11" HREF="qemu-doc.html#SEC11">3.4 Keys</A> -<LI><A NAME="TOC12" HREF="qemu-doc.html#SEC12">3.5 QEMU Monitor</A> -<UL> -<LI><A NAME="TOC13" HREF="qemu-doc.html#SEC13">3.5.1 Commands</A> -<LI><A NAME="TOC14" HREF="qemu-doc.html#SEC14">3.5.2 Integer expressions</A> -</UL> -<LI><A NAME="TOC15" HREF="qemu-doc.html#SEC15">3.6 Disk Images</A> -<UL> -<LI><A NAME="TOC16" HREF="qemu-doc.html#SEC16">3.6.1 Raw disk images</A> -<LI><A NAME="TOC17" HREF="qemu-doc.html#SEC17">3.6.2 Snapshot mode</A> -<LI><A NAME="TOC18" HREF="qemu-doc.html#SEC18">3.6.3 Copy On Write disk images</A> -<LI><A NAME="TOC19" HREF="qemu-doc.html#SEC19">3.6.4 Convert VMware disk images to raw disk images</A> -</UL> -<LI><A NAME="TOC20" HREF="qemu-doc.html#SEC20">3.7 Network emulation</A> -<UL> -<LI><A NAME="TOC21" HREF="qemu-doc.html#SEC21">3.7.1 Using tun/tap network interface</A> -<LI><A NAME="TOC22" HREF="qemu-doc.html#SEC22">3.7.2 Using the user mode network stack</A> -</UL> -<LI><A NAME="TOC23" HREF="qemu-doc.html#SEC23">3.8 Direct Linux Boot</A> -<LI><A NAME="TOC24" HREF="qemu-doc.html#SEC24">3.9 Linux Kernel Compilation</A> -<LI><A NAME="TOC25" HREF="qemu-doc.html#SEC25">3.10 GDB usage</A> -<LI><A NAME="TOC26" HREF="qemu-doc.html#SEC26">3.11 Target OS specific information</A> -<UL> -<LI><A NAME="TOC27" HREF="qemu-doc.html#SEC27">3.11.1 Linux</A> -<LI><A NAME="TOC28" HREF="qemu-doc.html#SEC28">3.11.2 Windows</A> -<UL> -<LI><A NAME="TOC29" HREF="qemu-doc.html#SEC29">3.11.2.1 SVGA graphic modes support</A> -<LI><A NAME="TOC30" HREF="qemu-doc.html#SEC30">3.11.2.2 CPU usage reduction</A> -<LI><A NAME="TOC31" HREF="qemu-doc.html#SEC31">3.11.2.3 Windows 2000 disk full problems</A> -<LI><A NAME="TOC32" HREF="qemu-doc.html#SEC32">3.11.2.4 Windows XP security problems</A> -</UL> -<LI><A NAME="TOC33" HREF="qemu-doc.html#SEC33">3.11.3 MS-DOS and FreeDOS</A> -<UL> -<LI><A NAME="TOC34" HREF="qemu-doc.html#SEC34">3.11.3.1 CPU usage reduction</A> -</UL> -</UL> -</UL> -<LI><A NAME="TOC35" HREF="qemu-doc.html#SEC35">4. QEMU PowerPC System emulator invocation</A> -<LI><A NAME="TOC36" HREF="qemu-doc.html#SEC36">5. QEMU User space emulator invocation</A> -<UL> -<LI><A NAME="TOC37" HREF="qemu-doc.html#SEC37">5.1 Quick Start</A> -<LI><A NAME="TOC38" HREF="qemu-doc.html#SEC38">5.2 Wine launch</A> -<LI><A NAME="TOC39" HREF="qemu-doc.html#SEC39">5.3 Command line options</A> -</UL> -<LI><A NAME="TOC40" HREF="qemu-doc.html#SEC40">6. Compilation from the sources</A> -<UL> -<LI><A NAME="TOC41" HREF="qemu-doc.html#SEC41">6.1 Linux/BSD</A> -<LI><A NAME="TOC42" HREF="qemu-doc.html#SEC42">6.2 Windows</A> -<LI><A NAME="TOC43" HREF="qemu-doc.html#SEC43">6.3 Cross compilation for Windows with Linux</A> -<LI><A NAME="TOC44" HREF="qemu-doc.html#SEC44">6.4 Mac OS X</A> -</UL> -</UL> -<P><HR><P> - -<P> -QEMU CPU Emulator User Documentation - - - - -<H1><A NAME="SEC1" HREF="qemu-doc.html#TOC1">1. Introduction</A></H1> - - - -<H2><A NAME="SEC2" HREF="qemu-doc.html#TOC2">1.1 Features</A></H2> - -<P> -QEMU is a FAST! processor emulator using dynamic translation to -achieve good emulation speed. - - -<P> -QEMU has two operating modes: - - - -<UL> - -<LI> - -Full system emulation. In this mode, QEMU emulates a full system (for -example a PC), including a processor and various peripherials. It can -be used to launch different Operating Systems without rebooting the -PC or to debug system code. - -<LI> - -User mode emulation (Linux host only). In this mode, QEMU can launch -Linux processes compiled for one CPU on another CPU. It can be used to -launch the Wine Windows API emulator (<A HREF="http://www.winehq.org">http://www.winehq.org</A>) or -to ease cross-compilation and cross-debugging. - -</UL> - -<P> -As QEMU requires no host kernel driver to run, it is very safe and -easy to use. - - -<P> -For system emulation, the following hardware targets are supported: - -<UL> -<LI>PC (x86 processor) - -<LI>PREP (PowerPC processor) - -<LI>PowerMac (PowerPC processor, in progress) - -</UL> - -<P> -For user emulation, x86, PowerPC, ARM, and SPARC CPUs are supported. - - - - -<H1><A NAME="SEC3" HREF="qemu-doc.html#TOC3">2. Installation</A></H1> - -<P> -If you want to compile QEMU yourself, see section <A HREF="qemu-doc.html#SEC40">6. Compilation from the sources</A>. - - - - -<H2><A NAME="SEC4" HREF="qemu-doc.html#TOC4">2.1 Linux</A></H2> - -<P> -Download the binary distribution (<TT>`qemu-XXX-i386.tar.gz'</TT>) and -untar it as root in <TT>`/'</TT>: - - - -<PRE> -su -cd / -tar zxvf /tmp/qemu-XXX-i386.tar.gz -</PRE> - - - -<H2><A NAME="SEC5" HREF="qemu-doc.html#TOC5">2.2 Windows</A></H2> - -<P> -Download the experimental binary installer at -<A HREF="http://www.freeoszoo.org/download.php">http://www.freeoszoo.org/download.php</A>. - - - - -<H2><A NAME="SEC6" HREF="qemu-doc.html#TOC6">2.3 Mac OS X</A></H2> - -<P> -Download the experimental binary installer at -<A HREF="http://www.freeoszoo.org/download.php">http://www.freeoszoo.org/download.php</A>. - - - - -<H1><A NAME="SEC7" HREF="qemu-doc.html#TOC7">3. QEMU PC System emulator invocation</A></H1> - - - -<H2><A NAME="SEC8" HREF="qemu-doc.html#TOC8">3.1 Introduction</A></H2> - -<P> -The QEMU System emulator simulates a complete PC. - - -<P> -In order to meet specific user needs, two versions of QEMU are -available: - - - -<OL> - -<LI> - -<CODE>qemu-fast</CODE> uses the host Memory Management Unit (MMU) to -simulate the x86 MMU. It is <EM>fast</EM> but has limitations because -the whole 4 GB address space cannot be used and some memory mapped -peripherials cannot be emulated accurately yet. Therefore, a specific -guest Linux kernel can be used (See section <A HREF="qemu-doc.html#SEC24">3.9 Linux Kernel Compilation</A>) as guest -OS. - -Moreover there is no separation between the host and target address -spaces, so it offers no security (the target OS can modify the -<CODE>qemu-fast</CODE> code by writing at the right addresses). - -<LI> - -<CODE>qemu</CODE> uses a software MMU. It is about <EM>two times slower</EM> -but gives a more accurate emulation and a complete separation between -the host and target address spaces. - -</OL> - -<P> -QEMU emulates the following PC peripherials: - - - -<UL> -<LI> - -i440FX host PCI bridge and PIIX3 PCI to ISA bridge -<LI> - -Cirrus CLGD 5446 PCI VGA card or dummy VGA card with Bochs VESA -extensions (hardware level, including all non standard modes). -<LI> - -PS/2 mouse and keyboard -<LI> - -2 PCI IDE interfaces with hard disk and CD-ROM support -<LI> - -Floppy disk -<LI> - -NE2000 PCI network adapters -<LI> - -Serial ports -<LI> - -Soundblaster 16 card -</UL> - -<P> -QEMU uses the PC BIOS from the Bochs project and the Plex86/Bochs LGPL -VGA BIOS. - - - - -<H2><A NAME="SEC9" HREF="qemu-doc.html#TOC9">3.2 Quick Start</A></H2> - -<P> -Download and uncompress the linux image (<TT>`linux.img'</TT>) and type: - - - -<PRE> -qemu linux.img -</PRE> - -<P> -Linux should boot and give you a prompt. - - - - -<H2><A NAME="SEC10" HREF="qemu-doc.html#TOC10">3.3 Invocation</A></H2> - - -<PRE> -usage: qemu [options] [disk_image] -</PRE> - -<P> -<VAR>disk_image</VAR> is a raw hard disk image for IDE hard disk 0. - - -<P> -General options: -<DL COMPACT> - -<DT>@option{-fda file} -<DD> -<DT>@option{-fdb file} -<DD> -Use <VAR>file</VAR> as floppy disk 0/1 image (See section <A HREF="qemu-doc.html#SEC15">3.6 Disk Images</A>). You can -use the host floppy by using <TT>`/dev/fd0'</TT> as filename. - -<DT>@option{-hda file} -<DD> -<DT>@option{-hdb file} -<DD> -<DT>@option{-hdc file} -<DD> -<DT>@option{-hdd file} -<DD> -Use <VAR>file</VAR> as hard disk 0, 1, 2 or 3 image (See section <A HREF="qemu-doc.html#SEC15">3.6 Disk Images</A>). - -<DT>@option{-cdrom file} -<DD> -Use <VAR>file</VAR> as CD-ROM image (you cannot use @option{-hdc} and and -@option{-cdrom} at the same time). You can use the host CD-ROM by -using <TT>`/dev/cdrom'</TT> as filename. - -<DT>@option{-boot [a|c|d]} -<DD> -Boot on floppy (a), hard disk (c) or CD-ROM (d). Hard disk boot is -the default. - -<DT>@option{-snapshot} -<DD> -Write to temporary files instead of disk image files. In this case, -the raw disk image you use is not written back. You can however force -the write back by pressing <KBD>C-a s</KBD> (See section <A HREF="qemu-doc.html#SEC15">3.6 Disk Images</A>). - -<DT>@option{-m megs} -<DD> -Set virtual RAM size to <VAR>megs</VAR> megabytes. Default is 128 MB. - -<DT>@option{-nographic} -<DD> -Normally, QEMU uses SDL to display the VGA output. With this option, -you can totally disable graphical output so that QEMU is a simple -command line application. The emulated serial port is redirected on -the console. Therefore, you can still use QEMU to debug a Linux kernel -with a serial console. - -<DT>@option{-enable-audio} -<DD> -The SB16 emulation is disabled by default as it may give problems with -Windows. You can enable it manually with this option. - -<DT>@option{-localtime} -<DD> -Set the real time clock to local time (the default is to UTC -time). This option is needed to have correct date in MS-DOS or -Windows. - -<DT>@option{-full-screen} -<DD> -Start in full screen. - -</DL> - -<P> -Network options: - - -<DL COMPACT> - -<DT>@option{-n script} -<DD> -Set TUN/TAP network init script [default=/etc/qemu-ifup]. This script -is launched to configure the host network interface (usually tun0) -corresponding to the virtual NE2000 card. - -<DT>@option{-macaddr addr} -<DD> -Set the mac address of the first interface (the format is -aa:bb:cc:dd:ee:ff in hexa). The mac address is incremented for each -new network interface. - -<DT>@option{-tun-fd fd} -<DD> -Assumes <VAR>fd</VAR> talks to a tap/tun host network interface and use -it. Read <A HREF="http://bellard.org/qemu/tetrinet.html">http://bellard.org/qemu/tetrinet.html</A> to have an -example of its use. - -<DT>@option{-user-net} -<DD> -Use the user mode network stack. This is the default if no tun/tap -network init script is found. - -<DT>@option{-tftp prefix} -<DD> -When using the user mode network stack, activate a built-in TFTP -server. All filenames beginning with <VAR>prefix</VAR> can be downloaded -from the host to the guest using a TFTP client. The TFTP client on the -guest must be configured in binary mode (use the command <CODE>bin</CODE> of -the Unix TFTP client). The host IP address on the guest is as usual -10.0.2.2. - -<DT>@option{-smb dir} -<DD> -When using the user mode network stack, activate a built-in SMB -server so that Windows OSes can access to the host files in <TT>`dir'</TT> -transparently. - -In the guest Windows OS, the line: - -<PRE> -10.0.2.4 smbserver -</PRE> - -must be added in the file <TT>`C:\WINDOWS\LMHOSTS'</TT> (for windows 9x/Me) -or <TT>`C:\WINNT\SYSTEM32\DRIVERS\ETC\LMHOSTS'</TT> (Windows NT/2000). - -Then <TT>`dir'</TT> can be accessed in <TT>`\\smbserver\qemu'</TT>. - -Note that a SAMBA server must be installed on the host OS in -<TT>`/usr/sbin/smbd'</TT>. QEMU was tested succesfully with smbd version -2.2.7a from the Red Hat 9. - -<DT>@option{-redir [tcp|udp]:host-port:[guest-host]:guest-port} -<DD> -When using the user mode network stack, redirect incoming TCP or UDP -connections to the host port <VAR>host-port</VAR> to the guest -<VAR>guest-host</VAR> on guest port <VAR>guest-port</VAR>. If <VAR>guest-host</VAR> -is not specified, its value is 10.0.2.15 (default address given by the -built-in DHCP server). - -For example, to redirect host X11 connection from screen 1 to guest -screen 0, use the following: - - -<PRE> -# on the host -qemu -redir tcp:6001::6000 [...] -# this host xterm should open in the guest X11 server -xterm -display :1 -</PRE> - -To redirect telnet connections from host port 5555 to telnet port on -the guest, use the following: - - -<PRE> -# on the host -qemu -redir tcp:5555::23 [...] -telnet localhost 5555 -</PRE> - -Then when you use on the host <CODE>telnet localhost 5555</CODE>, you -connect to the guest telnet server. - -<DT>@option{-dummy-net} -<DD> -Use the dummy network stack: no packet will be received by the network -cards. - -</DL> - -<P> -Linux boot specific. When using this options, you can use a given -Linux kernel without installing it in the disk image. It can be useful -for easier testing of various kernels. - - -<DL COMPACT> - -<DT>@option{-kernel bzImage} -<DD> -Use <VAR>bzImage</VAR> as kernel image. - -<DT>@option{-append cmdline} -<DD> -Use <VAR>cmdline</VAR> as kernel command line - -<DT>@option{-initrd file} -<DD> -Use <VAR>file</VAR> as initial ram disk. - -</DL> - -<P> -Debug/Expert options: -<DL COMPACT> - -<DT>@option{-serial dev} -<DD> -Redirect the virtual serial port to host device <VAR>dev</VAR>. Available -devices are: -<DL COMPACT> - -<DT><CODE>vc</CODE> -<DD> -Virtual console -<DT><CODE>pty</CODE> -<DD> -[Linux only] Pseudo TTY (a new PTY is automatically allocated) -<DT><CODE>null</CODE> -<DD> -void device -<DT><CODE>stdio</CODE> -<DD> -[Unix only] standard input/output -</DL> -The default device is <CODE>vc</CODE> in graphical mode and <CODE>stdio</CODE> in -non graphical mode. - -This option can be used several times to simulate up to 4 serials -ports. - -<DT>@option{-monitor dev} -<DD> -Redirect the monitor to host device <VAR>dev</VAR> (same devices as the -serial port). -The default device is <CODE>vc</CODE> in graphical mode and <CODE>stdio</CODE> in -non graphical mode. - -<DT>@option{-s} -<DD> -Wait gdb connection to port 1234 (See section <A HREF="qemu-doc.html#SEC25">3.10 GDB usage</A>). -<DT>@option{-p port} -<DD> -Change gdb connection port. -<DT>@option{-S} -<DD> -Do not start CPU at startup (you must type 'c' in the monitor). -<DT>@option{-d} -<DD> -Output log in /tmp/qemu.log -<DT>@option{-isa} -<DD> -Simulate an ISA-only system (default is PCI system). -<DT>@option{-std-vga} -<DD> -Simulate a standard VGA card with Bochs VBE extensions (default is -Cirrus Logic GD5446 PCI VGA) -<DT>@option{-loadvm file} -<DD> -Start right away with a saved state (<CODE>loadvm</CODE> in monitor) -</DL> - - - -<H2><A NAME="SEC11" HREF="qemu-doc.html#TOC11">3.4 Keys</A></H2> - -<P> -During the graphical emulation, you can use the following keys: -<DL COMPACT> - -<DT><KBD>Ctrl-Alt-f</KBD> -<DD> -Toggle full screen - -<DT><KBD>Ctrl-Alt-n</KBD> -<DD> -Switch to virtual console 'n'. Standard console mappings are: -<DL COMPACT> - -<DT><EM>1</EM> -<DD> -Target system display -<DT><EM>2</EM> -<DD> -Monitor -<DT><EM>3</EM> -<DD> -Serial port -</DL> - -<DT><KBD>Ctrl-Alt</KBD> -<DD> -Toggle mouse and keyboard grab. -</DL> - -<P> -In the virtual consoles, you can use <KBD>Ctrl-Up</KBD>, <KBD>Ctrl-Down</KBD>, -<KBD>Ctrl-PageUp</KBD> and <KBD>Ctrl-PageDown</KBD> to move in the back log. - - -<P> -During emulation, if you are using the @option{-nographic} option, use -<KBD>Ctrl-a h</KBD> to get terminal commands: - - -<DL COMPACT> - -<DT><KBD>Ctrl-a h</KBD> -<DD> -Print this help -<DT><KBD>Ctrl-a x</KBD> -<DD> -Exit emulatior -<DT><KBD>Ctrl-a s</KBD> -<DD> -Save disk data back to file (if -snapshot) -<DT><KBD>Ctrl-a b</KBD> -<DD> -Send break (magic sysrq in Linux) -<DT><KBD>Ctrl-a c</KBD> -<DD> -Switch between console and monitor -<DT><KBD>Ctrl-a Ctrl-a</KBD> -<DD> -Send Ctrl-a -</DL> - - - -<H2><A NAME="SEC12" HREF="qemu-doc.html#TOC12">3.5 QEMU Monitor</A></H2> - -<P> -The QEMU monitor is used to give complex commands to the QEMU -emulator. You can use it to: - - - -<UL> - -<LI> - -Remove or insert removable medias images -(such as CD-ROM or floppies) - -<LI> - -Freeze/unfreeze the Virtual Machine (VM) and save or restore its state -from a disk file. - -<LI>Inspect the VM state without an external debugger. - -</UL> - - - -<H3><A NAME="SEC13" HREF="qemu-doc.html#TOC13">3.5.1 Commands</A></H3> - -<P> -The following commands are available: - - -<DL COMPACT> - -<DT>@option{help or ? [cmd]} -<DD> -Show the help for all commands or just for command <VAR>cmd</VAR>. - -<DT>@option{commit} -<DD> -Commit changes to the disk images (if -snapshot is used) - -<DT>@option{info subcommand} -<DD> -show various information about the system state - -<DL COMPACT> - -<DT>@option{info network} -<DD> -show the network state -<DT>@option{info block} -<DD> -show the block devices -<DT>@option{info registers} -<DD> -show the cpu registers -<DT>@option{info history} -<DD> -show the command line history -</DL> - -<DT>@option{q or quit} -<DD> -Quit the emulator. - -<DT>@option{eject [-f] device} -<DD> -Eject a removable media (use -f to force it). - -<DT>@option{change device filename} -<DD> -Change a removable media. - -<DT>@option{screendump filename} -<DD> -Save screen into PPM image <VAR>filename</VAR>. - -<DT>@option{log item1[,...]} -<DD> -Activate logging of the specified items to <TT>`/tmp/qemu.log'</TT>. - -<DT>@option{savevm filename} -<DD> -Save the whole virtual machine state to <VAR>filename</VAR>. - -<DT>@option{loadvm filename} -<DD> -Restore the whole virtual machine state from <VAR>filename</VAR>. - -<DT>@option{stop} -<DD> -Stop emulation. - -<DT>@option{c or cont} -<DD> -Resume emulation. - -<DT>@option{gdbserver [port]} -<DD> -Start gdbserver session (default port=1234) - -<DT>@option{x/fmt addr} -<DD> -Virtual memory dump starting at <VAR>addr</VAR>. - -<DT>@option{xp /fmt addr} -<DD> -Physical memory dump starting at <VAR>addr</VAR>. - -<VAR>fmt</VAR> is a format which tells the command how to format the -data. Its syntax is: @option{/{count}{format}{size}} - -<DL COMPACT> - -<DT><VAR>count</VAR> -<DD> -is the number of items to be dumped. - -<DT><VAR>format</VAR> -<DD> -can be x (hexa), d (signed decimal), u (unsigned decimal), o (octal), -c (char) or i (asm instruction). - -<DT><VAR>size</VAR> -<DD> -can be b (8 bits), h (16 bits), w (32 bits) or g (64 bits). On x86, -<CODE>h</CODE> or <CODE>w</CODE> can be specified with the <CODE>i</CODE> format to -respectively select 16 or 32 bit code instruction size. - -</DL> - -Examples: - -<UL> -<LI> - -Dump 10 instructions at the current instruction pointer: - -<PRE> -(qemu) x/10i $eip -0x90107063: ret -0x90107064: sti -0x90107065: lea 0x0(%esi,1),%esi -0x90107069: lea 0x0(%edi,1),%edi -0x90107070: ret -0x90107071: jmp 0x90107080 -0x90107073: nop -0x90107074: nop -0x90107075: nop -0x90107076: nop -</PRE> - -<LI> - -Dump 80 16 bit values at the start of the video memory. - -<PRE> -(qemu) xp/80hx 0xb8000 -0x000b8000: 0x0b50 0x0b6c 0x0b65 0x0b78 0x0b38 0x0b36 0x0b2f 0x0b42 -0x000b8010: 0x0b6f 0x0b63 0x0b68 0x0b73 0x0b20 0x0b56 0x0b47 0x0b41 -0x000b8020: 0x0b42 0x0b69 0x0b6f 0x0b73 0x0b20 0x0b63 0x0b75 0x0b72 -0x000b8030: 0x0b72 0x0b65 0x0b6e 0x0b74 0x0b2d 0x0b63 0x0b76 0x0b73 -0x000b8040: 0x0b20 0x0b30 0x0b35 0x0b20 0x0b4e 0x0b6f 0x0b76 0x0b20 -0x000b8050: 0x0b32 0x0b30 0x0b30 0x0b33 0x0720 0x0720 0x0720 0x0720 -0x000b8060: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 -0x000b8070: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 -0x000b8080: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 -0x000b8090: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 -</PRE> - -</UL> - -<DT>@option{p or print/fmt expr} -<DD> -Print expression value. Only the <VAR>format</VAR> part of <VAR>fmt</VAR> is -used. - -<DT>@option{sendkey keys} -<DD> -Send <VAR>keys</VAR> to the emulator. Use <CODE>-</CODE> to press several keys -simultaneously. Example: - -<PRE> -sendkey ctrl-alt-f1 -</PRE> - -This command is useful to send keys that your graphical user interface -intercepts at low level, such as <CODE>ctrl-alt-f1</CODE> in X Window. - -<DT>@option{system_reset} -<DD> -Reset the system. - -</DL> - - - -<H3><A NAME="SEC14" HREF="qemu-doc.html#TOC14">3.5.2 Integer expressions</A></H3> - -<P> -The monitor understands integers expressions for every integer -argument. You can use register names to get the value of specifics -CPU registers by prefixing them with <EM>$</EM>. - - - - -<H2><A NAME="SEC15" HREF="qemu-doc.html#TOC15">3.6 Disk Images</A></H2> - - - -<H3><A NAME="SEC16" HREF="qemu-doc.html#TOC16">3.6.1 Raw disk images</A></H3> - -<P> -The disk images can simply be raw images of the hard disk. You can -create them with the command: - -<PRE> -dd of=myimage bs=1024 seek=mysize count=0 -</PRE> - -<P> -where <VAR>myimage</VAR> is the image filename and <VAR>mysize</VAR> is its size -in kilobytes. - - - - -<H3><A NAME="SEC17" HREF="qemu-doc.html#TOC17">3.6.2 Snapshot mode</A></H3> - -<P> -If you use the option @option{-snapshot}, all disk images are -considered as read only. When sectors in written, they are written in -a temporary file created in <TT>`/tmp'</TT>. You can however force the -write back to the raw disk images by pressing <KBD>C-a s</KBD>. - - -<P> -NOTE: The snapshot mode only works with raw disk images. - - - - -<H3><A NAME="SEC18" HREF="qemu-doc.html#TOC18">3.6.3 Copy On Write disk images</A></H3> - -<P> -QEMU also supports user mode Linux -(<A HREF="http://user-mode-linux.sourceforge.net/">http://user-mode-linux.sourceforge.net/</A>) Copy On Write (COW) -disk images. The COW disk images are much smaller than normal images -as they store only modified sectors. They also permit the use of the -same disk image template for many users. - - -<P> -To create a COW disk images, use the command: - - - -<PRE> -qemu-mkcow -f myrawimage.bin mycowimage.cow -</PRE> - -<P> -<TT>`myrawimage.bin'</TT> is a raw image you want to use as original disk -image. It will never be written to. - - -<P> -<TT>`mycowimage.cow'</TT> is the COW disk image which is created by -<CODE>qemu-mkcow</CODE>. You can use it directly with the @option{-hdx} -options. You must not modify the original raw disk image if you use -COW images, as COW images only store the modified sectors from the raw -disk image. QEMU stores the original raw disk image name and its -modified time in the COW disk image so that chances of mistakes are -reduced. - - -<P> -If the raw disk image is not read-only, by pressing <KBD>C-a s</KBD> you -can flush the COW disk image back into the raw disk image, as in -snapshot mode. - - -<P> -COW disk images can also be created without a corresponding raw disk -image. It is useful to have a big initial virtual disk image without -using much disk space. Use: - - - -<PRE> -qemu-mkcow mycowimage.cow 1024 -</PRE> - -<P> -to create a 1 gigabyte empty COW disk image. - - -<P> -NOTES: - -<OL> -<LI> - -COW disk images must be created on file systems supporting -<EM>holes</EM> such as ext2 or ext3. -<LI> - -Since holes are used, the displayed size of the COW disk image is not -the real one. To know it, use the <CODE>ls -ls</CODE> command. -</OL> - - - -<H3><A NAME="SEC19" HREF="qemu-doc.html#TOC19">3.6.4 Convert VMware disk images to raw disk images</A></H3> - -<P> -You can use the tool <TT>`vmdk2raw'</TT> to convert VMware disk images to -raw disk images directly usable by QEMU. The syntax is: - -<PRE> -vmdk2raw vmware_image output_image -</PRE> - - - -<H2><A NAME="SEC20" HREF="qemu-doc.html#TOC20">3.7 Network emulation</A></H2> - -<P> -QEMU simulates up to 6 networks cards (NE2000 boards). Each card can -be connected to a specific host network interface. - - - - -<H3><A NAME="SEC21" HREF="qemu-doc.html#TOC21">3.7.1 Using tun/tap network interface</A></H3> - -<P> -This is the standard way to emulate network. QEMU adds a virtual -network device on your host (called <CODE>tun0</CODE>), and you can then -configure it as if it was a real ethernet card. - - -<P> -As an example, you can download the <TT>`linux-test-xxx.tar.gz'</TT> -archive and copy the script <TT>`qemu-ifup'</TT> in <TT>`/etc'</TT> and -configure properly <CODE>sudo</CODE> so that the command <CODE>ifconfig</CODE> -contained in <TT>`qemu-ifup'</TT> can be executed as root. You must verify -that your host kernel supports the TUN/TAP network interfaces: the -device <TT>`/dev/net/tun'</TT> must be present. - - -<P> -See section <A HREF="qemu-doc.html#SEC23">3.8 Direct Linux Boot</A> to have an example of network use with a -Linux distribution. - - - - -<H3><A NAME="SEC22" HREF="qemu-doc.html#TOC22">3.7.2 Using the user mode network stack</A></H3> - -<P> -By using the option @option{-user-net} or if you have no tun/tap init -script, QEMU uses a completely user mode network stack (you don't need -root priviledge to use the virtual network). The virtual network -configuration is the following: - - - -<PRE> - -QEMU Virtual Machine <------> Firewall/DHCP server <-----> Internet - (10.0.2.x) | (10.0.2.2) - | - ----> DNS server (10.0.2.3) - | - ----> SMB server (10.0.2.4) -</PRE> - -<P> -The QEMU VM behaves as if it was behind a firewall which blocks all -incoming connections. You can use a DHCP client to automatically -configure the network in the QEMU VM. - - -<P> -In order to check that the user mode network is working, you can ping -the address 10.0.2.2 and verify that you got an address in the range -10.0.2.x from the QEMU virtual DHCP server. - - -<P> -Note that <CODE>ping</CODE> is not supported reliably to the internet as it -would require root priviledges. It means you can only ping the local -router (10.0.2.2). - - -<P> -When using the built-in TFTP server, the router is also the TFTP -server. - - -<P> -When using the @option{-redir} option, TCP or UDP connections can be -redirected from the host to the guest. It allows for example to -redirect X11, telnet or SSH connections. - - - - -<H2><A NAME="SEC23" HREF="qemu-doc.html#TOC23">3.8 Direct Linux Boot</A></H2> - -<P> -This section explains how to launch a Linux kernel inside QEMU without -having to make a full bootable image. It is very useful for fast Linux -kernel testing. The QEMU network configuration is also explained. - - - -<OL> -<LI> - -Download the archive <TT>`linux-test-xxx.tar.gz'</TT> containing a Linux -kernel and a disk image. - -<LI>Optional: If you want network support (for example to launch X11 examples), you - -must copy the script <TT>`qemu-ifup'</TT> in <TT>`/etc'</TT> and configure -properly <CODE>sudo</CODE> so that the command <CODE>ifconfig</CODE> contained in -<TT>`qemu-ifup'</TT> can be executed as root. You must verify that your host -kernel supports the TUN/TAP network interfaces: the device -<TT>`/dev/net/tun'</TT> must be present. - -When network is enabled, there is a virtual network connection between -the host kernel and the emulated kernel. The emulated kernel is seen -from the host kernel at IP address 172.20.0.2 and the host kernel is -seen from the emulated kernel at IP address 172.20.0.1. - -<LI>Launch <CODE>qemu.sh</CODE>. You should have the following output: - - -<PRE> -> ./qemu.sh -Connected to host network interface: tun0 -Linux version 2.4.21 (bellard@voyager.localdomain) (gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) #5 Tue Nov 11 18:18:53 CET 2003 -BIOS-provided physical RAM map: - BIOS-e801: 0000000000000000 - 000000000009f000 (usable) - BIOS-e801: 0000000000100000 - 0000000002000000 (usable) -32MB LOWMEM available. -On node 0 totalpages: 8192 -zone(0): 4096 pages. -zone(1): 4096 pages. -zone(2): 0 pages. -Kernel command line: root=/dev/hda sb=0x220,5,1,5 ide2=noprobe ide3=noprobe ide4=noprobe ide5=noprobe console=ttyS0 -ide_setup: ide2=noprobe -ide_setup: ide3=noprobe -ide_setup: ide4=noprobe -ide_setup: ide5=noprobe -Initializing CPU#0 -Detected 2399.621 MHz processor. -Console: colour EGA 80x25 -Calibrating delay loop... 4744.80 BogoMIPS -Memory: 28872k/32768k available (1210k kernel code, 3508k reserved, 266k data, 64k init, 0k highmem) -Dentry cache hash table entries: 4096 (order: 3, 32768 bytes) -Inode cache hash table entries: 2048 (order: 2, 16384 bytes) -Mount cache hash table entries: 512 (order: 0, 4096 bytes) -Buffer-cache hash table entries: 1024 (order: 0, 4096 bytes) -Page-cache hash table entries: 8192 (order: 3, 32768 bytes) -CPU: Intel Pentium Pro stepping 03 -Checking 'hlt' instruction... OK. -POSIX conformance testing by UNIFIX -Linux NET4.0 for Linux 2.4 -Based upon Swansea University Computer Society NET3.039 -Initializing RT netlink socket -apm: BIOS not found. -Starting kswapd -Journalled Block Device driver loaded -Detected PS/2 Mouse Port. -pty: 256 Unix98 ptys configured -Serial driver version 5.05c (2001-07-08) with no serial options enabled -ttyS00 at 0x03f8 (irq = 4) is a 16450 -ne.c:v1.10 9/23/94 Donald Becker (becker@scyld.com) -Last modified Nov 1, 2000 by Paul Gortmaker -NE*000 ethercard probe at 0x300: 52 54 00 12 34 56 -eth0: NE2000 found at 0x300, using IRQ 9. -RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize -Uniform Multi-Platform E-IDE driver Revision: 7.00beta4-2.4 -ide: Assuming 50MHz system bus speed for PIO modes; override with idebus=xx -hda: QEMU HARDDISK, ATA DISK drive -ide0 at 0x1f0-0x1f7,0x3f6 on irq 14 -hda: attached ide-disk driver. -hda: 20480 sectors (10 MB) w/256KiB Cache, CHS=20/16/63 -Partition check: - hda: -Soundblaster audio driver Copyright (C) by Hannu Savolainen 1993-1996 -NET4: Linux TCP/IP 1.0 for NET4.0 -IP Protocols: ICMP, UDP, TCP, IGMP -IP: routing cache hash table of 512 buckets, 4Kbytes -TCP: Hash tables configured (established 2048 bind 4096) -NET4: Unix domain sockets 1.0/SMP for Linux NET4.0. -EXT2-fs warning: mounting unchecked fs, running e2fsck is recommended -VFS: Mounted root (ext2 filesystem). -Freeing unused kernel memory: 64k freed - -Linux version 2.4.21 (bellard@voyager.localdomain) (gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) #5 Tue Nov 11 18:18:53 CET 2003 - -QEMU Linux test distribution (based on Redhat 9) - -Type 'exit' to halt the system - -sh-2.05b# -</PRE> - -<LI> - -Then you can play with the kernel inside the virtual serial console. You -can launch <CODE>ls</CODE> for example. Type <KBD>Ctrl-a h</KBD> to have an help -about the keys you can type inside the virtual serial console. In -particular, use <KBD>Ctrl-a x</KBD> to exit QEMU and use <KBD>Ctrl-a b</KBD> as -the Magic SysRq key. - -<LI> - -If the network is enabled, launch the script <TT>`/etc/linuxrc'</TT> in the -emulator (don't forget the leading dot): - -<PRE> -. /etc/linuxrc -</PRE> - -Then enable X11 connections on your PC from the emulated Linux: - -<PRE> -xhost +172.20.0.2 -</PRE> - -You can now launch <TT>`xterm'</TT> or <TT>`xlogo'</TT> and verify that you have -a real Virtual Linux system ! - -</OL> - -<P> -NOTES: - -<OL> -<LI> - -A 2.5.74 kernel is also included in the archive. Just -replace the bzImage in qemu.sh to try it. - -<LI> - -qemu-fast creates a temporary file in <VAR>$QEMU_TMPDIR</VAR> (<TT>`/tmp'</TT> is the -default) containing all the simulated PC memory. If possible, try to use -a temporary directory using the tmpfs filesystem to avoid too many -unnecessary disk accesses. - -<LI> - -In order to exit cleanly from qemu, you can do a <EM>shutdown</EM> inside -qemu. qemu will automatically exit when the Linux shutdown is done. - -<LI> - -You can boot slightly faster by disabling the probe of non present IDE -interfaces. To do so, add the following options on the kernel command -line: - -<PRE> -ide1=noprobe ide2=noprobe ide3=noprobe ide4=noprobe ide5=noprobe -</PRE> - -<LI> - -The example disk image is a modified version of the one made by Kevin -Lawton for the plex86 Project (<A HREF="www.plex86.org">www.plex86.org</A>). - -</OL> - - - -<H2><A NAME="SEC24" HREF="qemu-doc.html#TOC24">3.9 Linux Kernel Compilation</A></H2> - -<P> -You can use any linux kernel with QEMU. However, if you want to use -<CODE>qemu-fast</CODE> to get maximum performances, you must use a modified -guest kernel. If you are using a 2.6 guest kernel, you can use -directly the patch <TT>`linux-2.6-qemu-fast.patch'</TT> made by Rusty -Russel available in the QEMU source archive. Otherwise, you can make the -following changes <EM>by hand</EM> to the Linux kernel: - - - -<OL> -<LI> - -The kernel must be mapped at 0x90000000 (the default is -0xc0000000). You must modify only two lines in the kernel source: - -In <TT>`include/asm/page.h'</TT>, replace - -<PRE> -#define __PAGE_OFFSET (0xc0000000) -</PRE> - -by - -<PRE> -#define __PAGE_OFFSET (0x90000000) -</PRE> - -And in <TT>`arch/i386/vmlinux.lds'</TT>, replace - -<PRE> - . = 0xc0000000 + 0x100000; -</PRE> - -by - -<PRE> - . = 0x90000000 + 0x100000; -</PRE> - -<LI> - -If you want to enable SMP (Symmetric Multi-Processing) support, you -must make the following change in <TT>`include/asm/fixmap.h'</TT>. Replace - -<PRE> -#define FIXADDR_TOP (0xffffX000UL) -</PRE> - -by - -<PRE> -#define FIXADDR_TOP (0xa7ffX000UL) -</PRE> - -(X is 'e' or 'f' depending on the kernel version). Although you can -use an SMP kernel with QEMU, it only supports one CPU. - -<LI> - -If you are not using a 2.6 kernel as host kernel but if you use a target -2.6 kernel, you must also ensure that the 'HZ' define is set to 100 -(1000 is the default) as QEMU cannot currently emulate timers at -frequencies greater than 100 Hz on host Linux systems < 2.6. In -<TT>`include/asm/param.h'</TT>, replace: - - -<PRE> -# define HZ 1000 /* Internal kernel timer frequency */ -</PRE> - -by - -<PRE> -# define HZ 100 /* Internal kernel timer frequency */ -</PRE> - -</OL> - -<P> -The file config-2.x.x gives the configuration of the example kernels. - - -<P> -Just type - -<PRE> -make bzImage -</PRE> - -<P> -As you would do to make a real kernel. Then you can use with QEMU -exactly the same kernel as you would boot on your PC (in -<TT>`arch/i386/boot/bzImage'</TT>). - - - - -<H2><A NAME="SEC25" HREF="qemu-doc.html#TOC25">3.10 GDB usage</A></H2> - -<P> -QEMU has a primitive support to work with gdb, so that you can do -'Ctrl-C' while the virtual machine is running and inspect its state. - - -<P> -In order to use gdb, launch qemu with the '-s' option. It will wait for a -gdb connection: - -<PRE> -> qemu -s -kernel arch/i386/boot/bzImage -hda root-2.4.20.img -append "root=/dev/hda" -Connected to host network interface: tun0 -Waiting gdb connection on port 1234 -</PRE> - -<P> -Then launch gdb on the 'vmlinux' executable: - -<PRE> -> gdb vmlinux -</PRE> - -<P> -In gdb, connect to QEMU: - -<PRE> -(gdb) target remote localhost:1234 -</PRE> - -<P> -Then you can use gdb normally. For example, type 'c' to launch the kernel: - -<PRE> -(gdb) c -</PRE> - -<P> -Here are some useful tips in order to use gdb on system code: - - - -<OL> -<LI> - -Use <CODE>info reg</CODE> to display all the CPU registers. -<LI> - -Use <CODE>x/10i $eip</CODE> to display the code at the PC position. -<LI> - -Use <CODE>set architecture i8086</CODE> to dump 16 bit code. Then use -<CODE>x/10i $cs*16+*eip</CODE> to dump the code at the PC position. -</OL> - - - -<H2><A NAME="SEC26" HREF="qemu-doc.html#TOC26">3.11 Target OS specific information</A></H2> - - - -<H3><A NAME="SEC27" HREF="qemu-doc.html#TOC27">3.11.1 Linux</A></H3> - -<P> -To have access to SVGA graphic modes under X11, use the <CODE>vesa</CODE> or -the <CODE>cirrus</CODE> X11 driver. For optimal performances, use 16 bit -color depth in the guest and the host OS. - - -<P> -When using a 2.6 guest Linux kernel, you should add the option -<CODE>clock=pit</CODE> on the kernel command line because the 2.6 Linux -kernels make very strict real time clock checks by default that QEMU -cannot simulate exactly. - - - - -<H3><A NAME="SEC28" HREF="qemu-doc.html#TOC28">3.11.2 Windows</A></H3> - -<P> -If you have a slow host, using Windows 95 is better as it gives the -best speed. Windows 2000 is also a good choice. - - - - -<H4><A NAME="SEC29" HREF="qemu-doc.html#TOC29">3.11.2.1 SVGA graphic modes support</A></H4> - -<P> -QEMU emulates a Cirrus Logic GD5446 Video -card. All Windows versions starting from Windows 95 should recognize -and use this graphic card. For optimal performances, use 16 bit color -depth in the guest and the host OS. - - - - -<H4><A NAME="SEC30" HREF="qemu-doc.html#TOC30">3.11.2.2 CPU usage reduction</A></H4> - -<P> -Windows 9x does not correctly use the CPU HLT -instruction. The result is that it takes host CPU cycles even when -idle. You can install the utility from -<A HREF="http://www.user.cityline.ru/~maxamn/amnhltm.zip">http://www.user.cityline.ru/~maxamn/amnhltm.zip</A> to solve this -problem. Note that no such tool is needed for NT, 2000 or XP. - - - - -<H4><A NAME="SEC31" HREF="qemu-doc.html#TOC31">3.11.2.3 Windows 2000 disk full problems</A></H4> - -<P> -Currently (release 0.6.0) QEMU has a bug which gives a <CODE>disk -full</CODE> error during installation of some releases of Windows 2000. The -workaround is to stop QEMU as soon as you notice that your disk image -size is growing too fast (monitor it with <CODE>ls -ls</CODE>). Then -relaunch QEMU to continue the installation. If you still experience -the problem, relaunch QEMU again. - - -<P> -Future QEMU releases are likely to correct this bug. - - - - -<H4><A NAME="SEC32" HREF="qemu-doc.html#TOC32">3.11.2.4 Windows XP security problems</A></H4> - -<P> -Some releases of Windows XP install correctly but give a security -error when booting: - -<PRE> -A problem is preventing Windows from accurately checking the -license for this computer. Error code: 0x800703e6. -</PRE> - -<P> -The only known workaround is to boot in Safe mode -without networking support. - - -<P> -Future QEMU releases are likely to correct this bug. - - - - -<H3><A NAME="SEC33" HREF="qemu-doc.html#TOC33">3.11.3 MS-DOS and FreeDOS</A></H3> - - - -<H4><A NAME="SEC34" HREF="qemu-doc.html#TOC34">3.11.3.1 CPU usage reduction</A></H4> - -<P> -DOS does not correctly use the CPU HLT instruction. The result is that -it takes host CPU cycles even when idle. You can install the utility -from <A HREF="http://www.vmware.com/software/dosidle210.zip">http://www.vmware.com/software/dosidle210.zip</A> to solve this -problem. - - - - -<H1><A NAME="SEC35" HREF="qemu-doc.html#TOC35">4. QEMU PowerPC System emulator invocation</A></H1> - -<P> -Use the executable <TT>`qemu-system-ppc'</TT> to simulate a complete PREP -or PowerMac PowerPC system. - - -<P> -QEMU emulates the following PowerMac peripherials: - - - -<UL> -<LI> - -UniNorth PCI Bridge -<LI> - -PCI VGA compatible card with VESA Bochs Extensions -<LI> - -2 PMAC IDE interfaces with hard disk and CD-ROM support -<LI> - -NE2000 PCI adapters -<LI> - -Non Volatile RAM -<LI> - -VIA-CUDA with ADB keyboard and mouse. -</UL> - -<P> -QEMU emulates the following PREP peripherials: - - - -<UL> -<LI> - -PCI Bridge -<LI> - -PCI VGA compatible card with VESA Bochs Extensions -<LI> - -2 IDE interfaces with hard disk and CD-ROM support -<LI> - -Floppy disk -<LI> - -NE2000 network adapters -<LI> - -Serial port -<LI> - -PREP Non Volatile RAM -<LI> - -PC compatible keyboard and mouse. -</UL> - -<P> -QEMU uses the Open Hack'Ware Open Firmware Compatible BIOS available at -<A HREF="http://site.voila.fr/jmayer/OpenHackWare/index.htm">http://site.voila.fr/jmayer/OpenHackWare/index.htm</A>. - - -<P> -You can read the qemu PC system emulation chapter to have more -informations about QEMU usage. - - -<P> -The following options are specific to the PowerPC emulation: - - -<DL COMPACT> - -<DT>@option{-prep} -<DD> -Simulate a PREP system (default is PowerMAC) - -<DT>@option{-g WxH[xDEPTH]} -<DD> -Set the initial VGA graphic mode. The default is 800x600x15. - -</DL> - -<P> -More information is available at -<A HREF="http://jocelyn.mayer.free.fr/qemu-ppc/">http://jocelyn.mayer.free.fr/qemu-ppc/</A>. - - - - -<H1><A NAME="SEC36" HREF="qemu-doc.html#TOC36">5. QEMU User space emulator invocation</A></H1> - - - -<H2><A NAME="SEC37" HREF="qemu-doc.html#TOC37">5.1 Quick Start</A></H2> - -<P> -In order to launch a Linux process, QEMU needs the process executable -itself and all the target (x86) dynamic libraries used by it. - - - -<UL> - -<LI>On x86, you can just try to launch any process by using the native - -libraries: - - -<PRE> -qemu-i386 -L / /bin/ls -</PRE> - -<CODE>-L /</CODE> tells that the x86 dynamic linker must be searched with a -<TT>`/'</TT> prefix. - -<LI>Since QEMU is also a linux process, you can launch qemu with qemu (NOTE: you can only do that if you compiled QEMU from the sources): - - -<PRE> -qemu-i386 -L / qemu-i386 -L / /bin/ls -</PRE> - -<LI>On non x86 CPUs, you need first to download at least an x86 glibc - -(<TT>`qemu-runtime-i386-XXX-.tar.gz'</TT> on the QEMU web page). Ensure that -<CODE>LD_LIBRARY_PATH</CODE> is not set: - - -<PRE> -unset LD_LIBRARY_PATH -</PRE> - -Then you can launch the precompiled <TT>`ls'</TT> x86 executable: - - -<PRE> -qemu-i386 tests/i386/ls -</PRE> - -You can look at <TT>`qemu-binfmt-conf.sh'</TT> so that -QEMU is automatically launched by the Linux kernel when you try to -launch x86 executables. It requires the <CODE>binfmt_misc</CODE> module in the -Linux kernel. - -<LI>The x86 version of QEMU is also included. You can try weird things such as: - - -<PRE> -qemu-i386 /usr/local/qemu-i386/bin/qemu-i386 /usr/local/qemu-i386/bin/ls-i386 -</PRE> - -</UL> - - - -<H2><A NAME="SEC38" HREF="qemu-doc.html#TOC38">5.2 Wine launch</A></H2> - - -<UL> - -<LI>Ensure that you have a working QEMU with the x86 glibc - -distribution (see previous section). In order to verify it, you must be -able to do: - - -<PRE> -qemu-i386 /usr/local/qemu-i386/bin/ls-i386 -</PRE> - -<LI>Download the binary x86 Wine install - -(<TT>`qemu-XXX-i386-wine.tar.gz'</TT> on the QEMU web page). - -<LI>Configure Wine on your account. Look at the provided script - -<TT>`/usr/local/qemu-i386/bin/wine-conf.sh'</TT>. Your previous -<CODE>${HOME}/.wine</CODE> directory is saved to <CODE>${HOME}/.wine.org</CODE>. - -<LI>Then you can try the example <TT>`putty.exe'</TT>: - - -<PRE> -qemu-i386 /usr/local/qemu-i386/wine/bin/wine /usr/local/qemu-i386/wine/c/Program\ Files/putty.exe -</PRE> - -</UL> - - - -<H2><A NAME="SEC39" HREF="qemu-doc.html#TOC39">5.3 Command line options</A></H2> - - -<PRE> -usage: qemu-i386 [-h] [-d] [-L path] [-s size] program [arguments...] -</PRE> - -<DL COMPACT> - -<DT>@option{-h} -<DD> -Print the help -<DT>@option{-L path} -<DD> -Set the x86 elf interpreter prefix (default=/usr/local/qemu-i386) -<DT>@option{-s size} -<DD> -Set the x86 stack size in bytes (default=524288) -</DL> - -<P> -Debug options: - - -<DL COMPACT> - -<DT>@option{-d} -<DD> -Activate log (logfile=/tmp/qemu.log) -<DT>@option{-p pagesize} -<DD> -Act as if the host page size was 'pagesize' bytes -</DL> - - - -<H1><A NAME="SEC40" HREF="qemu-doc.html#TOC40">6. Compilation from the sources</A></H1> - - - -<H2><A NAME="SEC41" HREF="qemu-doc.html#TOC41">6.1 Linux/BSD</A></H2> - -<P> -Read the <TT>`README'</TT> which gives the related information. - - - - -<H2><A NAME="SEC42" HREF="qemu-doc.html#TOC42">6.2 Windows</A></H2> - - -<UL> -<LI>Install the current versions of MSYS and MinGW from - -<A HREF="http://www.mingw.org/">http://www.mingw.org/</A>. You can find detailed installation -instructions in the download section and the FAQ. - -<LI>Download - -the MinGW development library of SDL 1.2.x -(<TT>`SDL-devel-1.2.x-mingw32.tar.gz'</TT>) from -<A HREF="http://www.libsdl.org">http://www.libsdl.org</A>. Unpack it in a temporary place, and -unpack the archive <TT>`i386-mingw32msvc.tar.gz'</TT> in the MinGW tool -directory. Edit the <TT>`sdl-config'</TT> script so that it gives the -correct SDL directory when invoked. - -<LI>Extract the current version of QEMU. - - -<LI>Start the MSYS shell (file <TT>`msys.bat'</TT>). - -<LI>Change to the QEMU directory. Launch <TT>`./configure'</TT> and - -<TT>`make'</TT>. If you have problems using SDL, verify that -<TT>`sdl-config'</TT> can be launched from the MSYS command line. - -<LI>You can install QEMU in <TT>`Program Files/Qemu'</TT> by typing - -<TT>`make install'</TT>. Don't forget to copy <TT>`SDL.dll'</TT> in -<TT>`Program Files/Qemu'</TT>. - -</UL> - - - -<H2><A NAME="SEC43" HREF="qemu-doc.html#TOC43">6.3 Cross compilation for Windows with Linux</A></H2> - - -<UL> -<LI> - -Install the MinGW cross compilation tools available at -<A HREF="http://www.mingw.org/">http://www.mingw.org/</A>. - -<LI> - -Install the Win32 version of SDL (<A HREF="http://www.libsdl.org">http://www.libsdl.org</A>) by -unpacking <TT>`i386-mingw32msvc.tar.gz'</TT>. Set up the PATH environment -variable so that <TT>`i386-mingw32msvc-sdl-config'</TT> can be launched by -the QEMU configuration script. - -<LI> - -Configure QEMU for Windows cross compilation: - -<PRE> -./configure --enable-mingw32 -</PRE> - -If necessary, you can change the cross-prefix according to the prefix -choosen for the MinGW tools with --cross-prefix. You can also use ---prefix to set the Win32 install path. - -<LI>You can install QEMU in the installation directory by typing - -<TT>`make install'</TT>. Don't forget to copy <TT>`SDL.dll'</TT> in the -installation directory. - -</UL> - -<P> -Note: Currently, Wine does not seem able to launch -QEMU for Win32. - - - - -<H2><A NAME="SEC44" HREF="qemu-doc.html#TOC44">6.4 Mac OS X</A></H2> - -<P> -The Mac OS X patches are not fully merged in QEMU, so you should look -at the QEMU mailing list archive to have all the necessary -information. - - -<P><HR><P> -This document was generated on 19 May 2005 using -<A HREF="http://wwwinfo.cern.ch/dis/texi2html/">texi2html</A> 1.56k. -</BODY> -</HTML> diff --git a/tools/ioemu/qemu-doc.texi b/tools/ioemu/qemu-doc.texi deleted file mode 100644 index c262ee7e9c..0000000000 --- a/tools/ioemu/qemu-doc.texi +++ /dev/null @@ -1,1296 +0,0 @@ -\input texinfo @c -*- texinfo -*- - -@iftex -@settitle QEMU CPU Emulator User Documentation -@titlepage -@sp 7 -@center @titlefont{QEMU CPU Emulator User Documentation} -@sp 3 -@end titlepage -@end iftex - -@chapter Introduction - -@section Features - -QEMU is a FAST! processor emulator using dynamic translation to -achieve good emulation speed. - -QEMU has two operating modes: - -@itemize @minus - -@item -Full system emulation. In this mode, QEMU emulates a full system (for -example a PC), including a processor and various peripherials. It can -be used to launch different Operating Systems without rebooting the -PC or to debug system code. - -@item -User mode emulation (Linux host only). In this mode, QEMU can launch -Linux processes compiled for one CPU on another CPU. It can be used to -launch the Wine Windows API emulator (@url{http://www.winehq.org}) or -to ease cross-compilation and cross-debugging. - -@end itemize - -As QEMU requires no host kernel driver to run, it is very safe and -easy to use. - -For system emulation, the following hardware targets are supported: -@itemize -@item PC (x86 processor) -@item PREP (PowerPC processor) -@item PowerMac (PowerPC processor, in progress) -@end itemize - -For user emulation, x86, PowerPC, ARM, and SPARC CPUs are supported. - -@chapter Installation - -If you want to compile QEMU yourself, see @ref{compilation}. - -@section Linux - -Download the binary distribution (@file{qemu-XXX-i386.tar.gz}) and -untar it as root in @file{/}: - -@example -su -cd / -tar zxvf /tmp/qemu-XXX-i386.tar.gz -@end example - -@section Windows - -Download the experimental binary installer at -@url{http://www.freeoszoo.org/download.php}. - -@section Mac OS X - -Download the experimental binary installer at -@url{http://www.freeoszoo.org/download.php}. - -@chapter QEMU PC System emulator invocation - -@section Introduction - -@c man begin DESCRIPTION - -The QEMU System emulator simulates a complete PC. - -In order to meet specific user needs, two versions of QEMU are -available: - -@enumerate - -@item -@code{qemu-fast} uses the host Memory Management Unit (MMU) to -simulate the x86 MMU. It is @emph{fast} but has limitations because -the whole 4 GB address space cannot be used and some memory mapped -peripherials cannot be emulated accurately yet. Therefore, a specific -guest Linux kernel can be used (@xref{linux_compile}) as guest -OS. - -Moreover there is no separation between the host and target address -spaces, so it offers no security (the target OS can modify the -@code{qemu-fast} code by writing at the right addresses). - -@item -@code{qemu} uses a software MMU. It is about @emph{two times slower} -but gives a more accurate emulation and a complete separation between -the host and target address spaces. - -@end enumerate - -QEMU emulates the following PC peripherials: - -@itemize @minus -@item -i440FX host PCI bridge and PIIX3 PCI to ISA bridge -@item -Cirrus CLGD 5446 PCI VGA card or dummy VGA card with Bochs VESA -extensions (hardware level, including all non standard modes). -@item -PS/2 mouse and keyboard -@item -2 PCI IDE interfaces with hard disk and CD-ROM support -@item -Floppy disk -@item -NE2000 PCI network adapters -@item -Serial ports -@item -Soundblaster 16 card -@end itemize - -QEMU uses the PC BIOS from the Bochs project and the Plex86/Bochs LGPL -VGA BIOS. - -@c man end - -@section Quick Start - -Download and uncompress the linux image (@file{linux.img}) and type: - -@example -qemu linux.img -@end example - -Linux should boot and give you a prompt. - -@section Invocation - -@example -@c man begin SYNOPSIS -usage: qemu [options] [disk_image] -@c man end -@end example - -@c man begin OPTIONS -@var{disk_image} is a raw hard disk image for IDE hard disk 0. - -General options: -@table @option -@item -fda file -@item -fdb file -Use @var{file} as floppy disk 0/1 image (@xref{disk_images}). You can -use the host floppy by using @file{/dev/fd0} as filename. - -@item -hda file -@item -hdb file -@item -hdc file -@item -hdd file -Use @var{file} as hard disk 0, 1, 2 or 3 image (@xref{disk_images}). - -@item -cdrom file -Use @var{file} as CD-ROM image (you cannot use @option{-hdc} and and -@option{-cdrom} at the same time). You can use the host CD-ROM by -using @file{/dev/cdrom} as filename. - -@item -boot [a|c|d] -Boot on floppy (a), hard disk (c) or CD-ROM (d). Hard disk boot is -the default. - -@item -snapshot -Write to temporary files instead of disk image files. In this case, -the raw disk image you use is not written back. You can however force -the write back by pressing @key{C-a s} (@xref{disk_images}). - -@item -m megs -Set virtual RAM size to @var{megs} megabytes. Default is 128 MB. - -@item -nographic - -Normally, QEMU uses SDL to display the VGA output. With this option, -you can totally disable graphical output so that QEMU is a simple -command line application. The emulated serial port is redirected on -the console. Therefore, you can still use QEMU to debug a Linux kernel -with a serial console. - -@item -enable-audio - -The SB16 emulation is disabled by default as it may give problems with -Windows. You can enable it manually with this option. - -@item -localtime -Set the real time clock to local time (the default is to UTC -time). This option is needed to have correct date in MS-DOS or -Windows. - -@item -full-screen -Start in full screen. - -@end table - -Network options: - -@table @option - -@item -n script -Set TUN/TAP network init script [default=/etc/qemu-ifup]. This script -is launched to configure the host network interface (usually tun0) -corresponding to the virtual NE2000 card. - -@item -macaddr addr - -Set the mac address of the first interface (the format is -aa:bb:cc:dd:ee:ff in hexa). The mac address is incremented for each -new network interface. - -@item -tun-fd fd -Assumes @var{fd} talks to a tap/tun host network interface and use -it. Read @url{http://bellard.org/qemu/tetrinet.html} to have an -example of its use. - -@item -user-net -Use the user mode network stack. This is the default if no tun/tap -network init script is found. - -@item -tftp prefix -When using the user mode network stack, activate a built-in TFTP -server. All filenames beginning with @var{prefix} can be downloaded -from the host to the guest using a TFTP client. The TFTP client on the -guest must be configured in binary mode (use the command @code{bin} of -the Unix TFTP client). The host IP address on the guest is as usual -10.0.2.2. - -@item -smb dir -When using the user mode network stack, activate a built-in SMB -server so that Windows OSes can access to the host files in @file{dir} -transparently. - -In the guest Windows OS, the line: -@example -10.0.2.4 smbserver -@end example -must be added in the file @file{C:\WINDOWS\LMHOSTS} (for windows 9x/Me) -or @file{C:\WINNT\SYSTEM32\DRIVERS\ETC\LMHOSTS} (Windows NT/2000). - -Then @file{dir} can be accessed in @file{\\smbserver\qemu}. - -Note that a SAMBA server must be installed on the host OS in -@file{/usr/sbin/smbd}. QEMU was tested succesfully with smbd version -2.2.7a from the Red Hat 9. - -@item -redir [tcp|udp]:host-port:[guest-host]:guest-port - -When using the user mode network stack, redirect incoming TCP or UDP -connections to the host port @var{host-port} to the guest -@var{guest-host} on guest port @var{guest-port}. If @var{guest-host} -is not specified, its value is 10.0.2.15 (default address given by the -built-in DHCP server). - -For example, to redirect host X11 connection from screen 1 to guest -screen 0, use the following: - -@example -# on the host -qemu -redir tcp:6001::6000 [...] -# this host xterm should open in the guest X11 server -xterm -display :1 -@end example - -To redirect telnet connections from host port 5555 to telnet port on -the guest, use the following: - -@example -# on the host -qemu -redir tcp:5555::23 [...] -telnet localhost 5555 -@end example - -Then when you use on the host @code{telnet localhost 5555}, you -connect to the guest telnet server. - -@item -dummy-net -Use the dummy network stack: no packet will be received by the network -cards. - -@end table - -Linux boot specific. When using this options, you can use a given -Linux kernel without installing it in the disk image. It can be useful -for easier testing of various kernels. - -@table @option - -@item -kernel bzImage -Use @var{bzImage} as kernel image. - -@item -append cmdline -Use @var{cmdline} as kernel command line - -@item -initrd file -Use @var{file} as initial ram disk. - -@end table - -Debug/Expert options: -@table @option - -@item -serial dev -Redirect the virtual serial port to host device @var{dev}. Available -devices are: -@table @code -@item vc -Virtual console -@item pty -[Linux only] Pseudo TTY (a new PTY is automatically allocated) -@item null -void device -@item stdio -[Unix only] standard input/output -@end table -The default device is @code{vc} in graphical mode and @code{stdio} in -non graphical mode. - -This option can be used several times to simulate up to 4 serials -ports. - -@item -monitor dev -Redirect the monitor to host device @var{dev} (same devices as the -serial port). -The default device is @code{vc} in graphical mode and @code{stdio} in -non graphical mode. - -@item -s -Wait gdb connection to port 1234 (@xref{gdb_usage}). -@item -p port -Change gdb connection port. -@item -S -Do not start CPU at startup (you must type 'c' in the monitor). -@item -d -Output log in /tmp/qemu.log -@item -isa -Simulate an ISA-only system (default is PCI system). -@item -std-vga -Simulate a standard VGA card with Bochs VBE extensions (default is -Cirrus Logic GD5446 PCI VGA) -@item -loadvm file -Start right away with a saved state (@code{loadvm} in monitor) -@end table - -@c man end - -@section Keys - -@c man begin OPTIONS - -During the graphical emulation, you can use the following keys: -@table @key -@item Ctrl-Alt-f -Toggle full screen - -@item Ctrl-Alt-n -Switch to virtual console 'n'. Standard console mappings are: -@table @emph -@item 1 -Target system display -@item 2 -Monitor -@item 3 -Serial port -@end table - -@item Ctrl-Alt -Toggle mouse and keyboard grab. -@end table - -In the virtual consoles, you can use @key{Ctrl-Up}, @key{Ctrl-Down}, -@key{Ctrl-PageUp} and @key{Ctrl-PageDown} to move in the back log. - -During emulation, if you are using the @option{-nographic} option, use -@key{Ctrl-a h} to get terminal commands: - -@table @key -@item Ctrl-a h -Print this help -@item Ctrl-a x -Exit emulatior -@item Ctrl-a s -Save disk data back to file (if -snapshot) -@item Ctrl-a b -Send break (magic sysrq in Linux) -@item Ctrl-a c -Switch between console and monitor -@item Ctrl-a Ctrl-a -Send Ctrl-a -@end table -@c man end - -@ignore - -@setfilename qemu -@settitle QEMU System Emulator - -@c man begin SEEALSO -The HTML documentation of QEMU for more precise information and Linux -user mode emulator invocation. -@c man end - -@c man begin AUTHOR -Fabrice Bellard -@c man end - -@end ignore - -@end ignore - - -@section QEMU Monitor - -The QEMU monitor is used to give complex commands to the QEMU -emulator. You can use it to: - -@itemize @minus - -@item -Remove or insert removable medias images -(such as CD-ROM or floppies) - -@item -Freeze/unfreeze the Virtual Machine (VM) and save or restore its state -from a disk file. - -@item Inspect the VM state without an external debugger. - -@end itemize - -@subsection Commands - -The following commands are available: - -@table @option - -@item help or ? [cmd] -Show the help for all commands or just for command @var{cmd}. - -@item commit -Commit changes to the disk images (if -snapshot is used) - -@item info subcommand -show various information about the system state - -@table @option -@item info network -show the network state -@item info block -show the block devices -@item info registers -show the cpu registers -@item info history -show the command line history -@end table - -@item q or quit -Quit the emulator. - -@item eject [-f] device -Eject a removable media (use -f to force it). - -@item change device filename -Change a removable media. - -@item screendump filename -Save screen into PPM image @var{filename}. - -@item log item1[,...] -Activate logging of the specified items to @file{/tmp/qemu.log}. - -@item savevm filename -Save the whole virtual machine state to @var{filename}. - -@item loadvm filename -Restore the whole virtual machine state from @var{filename}. - -@item stop -Stop emulation. - -@item c or cont -Resume emulation. - -@item gdbserver [port] -Start gdbserver session (default port=1234) - -@item x/fmt addr -Virtual memory dump starting at @var{addr}. - -@item xp /fmt addr -Physical memory dump starting at @var{addr}. - -@var{fmt} is a format which tells the command how to format the -data. Its syntax is: @option{/@{count@}@{format@}@{size@}} - -@table @var -@item count -is the number of items to be dumped. - -@item format -can be x (hexa), d (signed decimal), u (unsigned decimal), o (octal), -c (char) or i (asm instruction). - -@item size -can be b (8 bits), h (16 bits), w (32 bits) or g (64 bits). On x86, -@code{h} or @code{w} can be specified with the @code{i} format to -respectively select 16 or 32 bit code instruction size. - -@end table - -Examples: -@itemize -@item -Dump 10 instructions at the current instruction pointer: -@example -(qemu) x/10i $eip -0x90107063: ret -0x90107064: sti -0x90107065: lea 0x0(%esi,1),%esi -0x90107069: lea 0x0(%edi,1),%edi -0x90107070: ret -0x90107071: jmp 0x90107080 -0x90107073: nop -0x90107074: nop -0x90107075: nop -0x90107076: nop -@end example - -@item -Dump 80 16 bit values at the start of the video memory. -@example -(qemu) xp/80hx 0xb8000 -0x000b8000: 0x0b50 0x0b6c 0x0b65 0x0b78 0x0b38 0x0b36 0x0b2f 0x0b42 -0x000b8010: 0x0b6f 0x0b63 0x0b68 0x0b73 0x0b20 0x0b56 0x0b47 0x0b41 -0x000b8020: 0x0b42 0x0b69 0x0b6f 0x0b73 0x0b20 0x0b63 0x0b75 0x0b72 -0x000b8030: 0x0b72 0x0b65 0x0b6e 0x0b74 0x0b2d 0x0b63 0x0b76 0x0b73 -0x000b8040: 0x0b20 0x0b30 0x0b35 0x0b20 0x0b4e 0x0b6f 0x0b76 0x0b20 -0x000b8050: 0x0b32 0x0b30 0x0b30 0x0b33 0x0720 0x0720 0x0720 0x0720 -0x000b8060: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 -0x000b8070: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 -0x000b8080: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 -0x000b8090: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 -@end example -@end itemize - -@item p or print/fmt expr - -Print expression value. Only the @var{format} part of @var{fmt} is -used. - -@item sendkey keys - -Send @var{keys} to the emulator. Use @code{-} to press several keys -simultaneously. Example: -@example -sendkey ctrl-alt-f1 -@end example - -This command is useful to send keys that your graphical user interface -intercepts at low level, such as @code{ctrl-alt-f1} in X Window. - -@item system_reset - -Reset the system. - -@end table - -@subsection Integer expressions - -The monitor understands integers expressions for every integer -argument. You can use register names to get the value of specifics -CPU registers by prefixing them with @emph{$}. - -@node disk_images -@section Disk Images - -@subsection Raw disk images - -The disk images can simply be raw images of the hard disk. You can -create them with the command: -@example -dd of=myimage bs=1024 seek=mysize count=0 -@end example -where @var{myimage} is the image filename and @var{mysize} is its size -in kilobytes. - -@subsection Snapshot mode - -If you use the option @option{-snapshot}, all disk images are -considered as read only. When sectors in written, they are written in -a temporary file created in @file{/tmp}. You can however force the -write back to the raw disk images by pressing @key{C-a s}. - -NOTE: The snapshot mode only works with raw disk images. - -@subsection Copy On Write disk images - -QEMU also supports user mode Linux -(@url{http://user-mode-linux.sourceforge.net/}) Copy On Write (COW) -disk images. The COW disk images are much smaller than normal images -as they store only modified sectors. They also permit the use of the -same disk image template for many users. - -To create a COW disk images, use the command: - -@example -qemu-mkcow -f myrawimage.bin mycowimage.cow -@end example - -@file{myrawimage.bin} is a raw image you want to use as original disk -image. It will never be written to. - -@file{mycowimage.cow} is the COW disk image which is created by -@code{qemu-mkcow}. You can use it directly with the @option{-hdx} -options. You must not modify the original raw disk image if you use -COW images, as COW images only store the modified sectors from the raw -disk image. QEMU stores the original raw disk image name and its -modified time in the COW disk image so that chances of mistakes are -reduced. - -If the raw disk image is not read-only, by pressing @key{C-a s} you -can flush the COW disk image back into the raw disk image, as in -snapshot mode. - -COW disk images can also be created without a corresponding raw disk -image. It is useful to have a big initial virtual disk image without -using much disk space. Use: - -@example -qemu-mkcow mycowimage.cow 1024 -@end example - -to create a 1 gigabyte empty COW disk image. - -NOTES: -@enumerate -@item -COW disk images must be created on file systems supporting -@emph{holes} such as ext2 or ext3. -@item -Since holes are used, the displayed size of the COW disk image is not -the real one. To know it, use the @code{ls -ls} command. -@end enumerate - -@subsection Convert VMware disk images to raw disk images - -You can use the tool @file{vmdk2raw} to convert VMware disk images to -raw disk images directly usable by QEMU. The syntax is: -@example -vmdk2raw vmware_image output_image -@end example - -@section Network emulation - -QEMU simulates up to 6 networks cards (NE2000 boards). Each card can -be connected to a specific host network interface. - -@subsection Using tun/tap network interface - -This is the standard way to emulate network. QEMU adds a virtual -network device on your host (called @code{tun0}), and you can then -configure it as if it was a real ethernet card. - -As an example, you can download the @file{linux-test-xxx.tar.gz} -archive and copy the script @file{qemu-ifup} in @file{/etc} and -configure properly @code{sudo} so that the command @code{ifconfig} -contained in @file{qemu-ifup} can be executed as root. You must verify -that your host kernel supports the TUN/TAP network interfaces: the -device @file{/dev/net/tun} must be present. - -See @ref{direct_linux_boot} to have an example of network use with a -Linux distribution. - -@subsection Using the user mode network stack - -By using the option @option{-user-net} or if you have no tun/tap init -script, QEMU uses a completely user mode network stack (you don't need -root priviledge to use the virtual network). The virtual network -configuration is the following: - -@example - -QEMU Virtual Machine <------> Firewall/DHCP server <-----> Internet - (10.0.2.x) | (10.0.2.2) - | - ----> DNS server (10.0.2.3) - | - ----> SMB server (10.0.2.4) -@end example - -The QEMU VM behaves as if it was behind a firewall which blocks all -incoming connections. You can use a DHCP client to automatically -configure the network in the QEMU VM. - -In order to check that the user mode network is working, you can ping -the address 10.0.2.2 and verify that you got an address in the range -10.0.2.x from the QEMU virtual DHCP server. - -Note that @code{ping} is not supported reliably to the internet as it -would require root priviledges. It means you can only ping the local -router (10.0.2.2). - -When using the built-in TFTP server, the router is also the TFTP -server. - -When using the @option{-redir} option, TCP or UDP connections can be -redirected from the host to the guest. It allows for example to -redirect X11, telnet or SSH connections. - -@node direct_linux_boot -@section Direct Linux Boot - -This section explains how to launch a Linux kernel inside QEMU without -having to make a full bootable image. It is very useful for fast Linux -kernel testing. The QEMU network configuration is also explained. - -@enumerate -@item -Download the archive @file{linux-test-xxx.tar.gz} containing a Linux -kernel and a disk image. - -@item Optional: If you want network support (for example to launch X11 examples), you -must copy the script @file{qemu-ifup} in @file{/etc} and configure -properly @code{sudo} so that the command @code{ifconfig} contained in -@file{qemu-ifup} can be executed as root. You must verify that your host -kernel supports the TUN/TAP network interfaces: the device -@file{/dev/net/tun} must be present. - -When network is enabled, there is a virtual network connection between -the host kernel and the emulated kernel. The emulated kernel is seen -from the host kernel at IP address 172.20.0.2 and the host kernel is -seen from the emulated kernel at IP address 172.20.0.1. - -@item Launch @code{qemu.sh}. You should have the following output: - -@example -> ./qemu.sh -Connected to host network interface: tun0 -Linux version 2.4.21 (bellard@voyager.localdomain) (gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) #5 Tue Nov 11 18:18:53 CET 2003 -BIOS-provided physical RAM map: - BIOS-e801: 0000000000000000 - 000000000009f000 (usable) - BIOS-e801: 0000000000100000 - 0000000002000000 (usable) -32MB LOWMEM available. -On node 0 totalpages: 8192 -zone(0): 4096 pages. -zone(1): 4096 pages. -zone(2): 0 pages. -Kernel command line: root=/dev/hda sb=0x220,5,1,5 ide2=noprobe ide3=noprobe ide4=noprobe ide5=noprobe console=ttyS0 -ide_setup: ide2=noprobe -ide_setup: ide3=noprobe -ide_setup: ide4=noprobe -ide_setup: ide5=noprobe -Initializing CPU#0 -Detected 2399.621 MHz processor. -Console: colour EGA 80x25 -Calibrating delay loop... 4744.80 BogoMIPS -Memory: 28872k/32768k available (1210k kernel code, 3508k reserved, 266k data, 64k init, 0k highmem) -Dentry cache hash table entries: 4096 (order: 3, 32768 bytes) -Inode cache hash table entries: 2048 (order: 2, 16384 bytes) -Mount cache hash table entries: 512 (order: 0, 4096 bytes) -Buffer-cache hash table entries: 1024 (order: 0, 4096 bytes) -Page-cache hash table entries: 8192 (order: 3, 32768 bytes) -CPU: Intel Pentium Pro stepping 03 -Checking 'hlt' instruction... OK. -POSIX conformance testing by UNIFIX -Linux NET4.0 for Linux 2.4 -Based upon Swansea University Computer Society NET3.039 -Initializing RT netlink socket -apm: BIOS not found. -Starting kswapd -Journalled Block Device driver loaded -Detected PS/2 Mouse Port. -pty: 256 Unix98 ptys configured -Serial driver version 5.05c (2001-07-08) with no serial options enabled -ttyS00 at 0x03f8 (irq = 4) is a 16450 -ne.c:v1.10 9/23/94 Donald Becker (becker@scyld.com) -Last modified Nov 1, 2000 by Paul Gortmaker -NE*000 ethercard probe at 0x300: 52 54 00 12 34 56 -eth0: NE2000 found at 0x300, using IRQ 9. -RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize -Uniform Multi-Platform E-IDE driver Revision: 7.00beta4-2.4 -ide: Assuming 50MHz system bus speed for PIO modes; override with idebus=xx -hda: QEMU HARDDISK, ATA DISK drive -ide0 at 0x1f0-0x1f7,0x3f6 on irq 14 -hda: attached ide-disk driver. -hda: 20480 sectors (10 MB) w/256KiB Cache, CHS=20/16/63 -Partition check: - hda: -Soundblaster audio driver Copyright (C) by Hannu Savolainen 1993-1996 -NET4: Linux TCP/IP 1.0 for NET4.0 -IP Protocols: ICMP, UDP, TCP, IGMP -IP: routing cache hash table of 512 buckets, 4Kbytes -TCP: Hash tables configured (established 2048 bind 4096) -NET4: Unix domain sockets 1.0/SMP for Linux NET4.0. -EXT2-fs warning: mounting unchecked fs, running e2fsck is recommended -VFS: Mounted root (ext2 filesystem). -Freeing unused kernel memory: 64k freed - -Linux version 2.4.21 (bellard@voyager.localdomain) (gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) #5 Tue Nov 11 18:18:53 CET 2003 - -QEMU Linux test distribution (based on Redhat 9) - -Type 'exit' to halt the system - -sh-2.05b# -@end example - -@item -Then you can play with the kernel inside the virtual serial console. You -can launch @code{ls} for example. Type @key{Ctrl-a h} to have an help -about the keys you can type inside the virtual serial console. In -particular, use @key{Ctrl-a x} to exit QEMU and use @key{Ctrl-a b} as -the Magic SysRq key. - -@item -If the network is enabled, launch the script @file{/etc/linuxrc} in the -emulator (don't forget the leading dot): -@example -. /etc/linuxrc -@end example - -Then enable X11 connections on your PC from the emulated Linux: -@example -xhost +172.20.0.2 -@end example - -You can now launch @file{xterm} or @file{xlogo} and verify that you have -a real Virtual Linux system ! - -@end enumerate - -NOTES: -@enumerate -@item -A 2.5.74 kernel is also included in the archive. Just -replace the bzImage in qemu.sh to try it. - -@item -qemu-fast creates a temporary file in @var{$QEMU_TMPDIR} (@file{/tmp} is the -default) containing all the simulated PC memory. If possible, try to use -a temporary directory using the tmpfs filesystem to avoid too many -unnecessary disk accesses. - -@item -In order to exit cleanly from qemu, you can do a @emph{shutdown} inside -qemu. qemu will automatically exit when the Linux shutdown is done. - -@item -You can boot slightly faster by disabling the probe of non present IDE -interfaces. To do so, add the following options on the kernel command -line: -@example -ide1=noprobe ide2=noprobe ide3=noprobe ide4=noprobe ide5=noprobe -@end example - -@item -The example disk image is a modified version of the one made by Kevin -Lawton for the plex86 Project (@url{www.plex86.org}). - -@end enumerate - -@node linux_compile -@section Linux Kernel Compilation - -You can use any linux kernel with QEMU. However, if you want to use -@code{qemu-fast} to get maximum performances, you must use a modified -guest kernel. If you are using a 2.6 guest kernel, you can use -directly the patch @file{linux-2.6-qemu-fast.patch} made by Rusty -Russel available in the QEMU source archive. Otherwise, you can make the -following changes @emph{by hand} to the Linux kernel: - -@enumerate -@item -The kernel must be mapped at 0x90000000 (the default is -0xc0000000). You must modify only two lines in the kernel source: - -In @file{include/asm/page.h}, replace -@example -#define __PAGE_OFFSET (0xc0000000) -@end example -by -@example -#define __PAGE_OFFSET (0x90000000) -@end example - -And in @file{arch/i386/vmlinux.lds}, replace -@example - . = 0xc0000000 + 0x100000; -@end example -by -@example - . = 0x90000000 + 0x100000; -@end example - -@item -If you want to enable SMP (Symmetric Multi-Processing) support, you -must make the following change in @file{include/asm/fixmap.h}. Replace -@example -#define FIXADDR_TOP (0xffffX000UL) -@end example -by -@example -#define FIXADDR_TOP (0xa7ffX000UL) -@end example -(X is 'e' or 'f' depending on the kernel version). Although you can -use an SMP kernel with QEMU, it only supports one CPU. - -@item -If you are not using a 2.6 kernel as host kernel but if you use a target -2.6 kernel, you must also ensure that the 'HZ' define is set to 100 -(1000 is the default) as QEMU cannot currently emulate timers at -frequencies greater than 100 Hz on host Linux systems < 2.6. In -@file{include/asm/param.h}, replace: - -@example -# define HZ 1000 /* Internal kernel timer frequency */ -@end example -by -@example -# define HZ 100 /* Internal kernel timer frequency */ -@end example - -@end enumerate - -The file config-2.x.x gives the configuration of the example kernels. - -Just type -@example -make bzImage -@end example - -As you would do to make a real kernel. Then you can use with QEMU -exactly the same kernel as you would boot on your PC (in -@file{arch/i386/boot/bzImage}). - -@node gdb_usage -@section GDB usage - -QEMU has a primitive support to work with gdb, so that you can do -'Ctrl-C' while the virtual machine is running and inspect its state. - -In order to use gdb, launch qemu with the '-s' option. It will wait for a -gdb connection: -@example -> qemu -s -kernel arch/i386/boot/bzImage -hda root-2.4.20.img -append "root=/dev/hda" -Connected to host network interface: tun0 -Waiting gdb connection on port 1234 -@end example - -Then launch gdb on the 'vmlinux' executable: -@example -> gdb vmlinux -@end example - -In gdb, connect to QEMU: -@example -(gdb) target remote localhost:1234 -@end example - -Then you can use gdb normally. For example, type 'c' to launch the kernel: -@example -(gdb) c -@end example - -Here are some useful tips in order to use gdb on system code: - -@enumerate -@item -Use @code{info reg} to display all the CPU registers. -@item -Use @code{x/10i $eip} to display the code at the PC position. -@item -Use @code{set architecture i8086} to dump 16 bit code. Then use -@code{x/10i $cs*16+*eip} to dump the code at the PC position. -@end enumerate - -@section Target OS specific information - -@subsection Linux - -To have access to SVGA graphic modes under X11, use the @code{vesa} or -the @code{cirrus} X11 driver. For optimal performances, use 16 bit -color depth in the guest and the host OS. - -When using a 2.6 guest Linux kernel, you should add the option -@code{clock=pit} on the kernel command line because the 2.6 Linux -kernels make very strict real time clock checks by default that QEMU -cannot simulate exactly. - -@subsection Windows - -If you have a slow host, using Windows 95 is better as it gives the -best speed. Windows 2000 is also a good choice. - -@subsubsection SVGA graphic modes support - -QEMU emulates a Cirrus Logic GD5446 Video -card. All Windows versions starting from Windows 95 should recognize -and use this graphic card. For optimal performances, use 16 bit color -depth in the guest and the host OS. - -@subsubsection CPU usage reduction - -Windows 9x does not correctly use the CPU HLT -instruction. The result is that it takes host CPU cycles even when -idle. You can install the utility from -@url{http://www.user.cityline.ru/~maxamn/amnhltm.zip} to solve this -problem. Note that no such tool is needed for NT, 2000 or XP. - -@subsubsection Windows 2000 disk full problems - -Currently (release 0.6.0) QEMU has a bug which gives a @code{disk -full} error during installation of some releases of Windows 2000. The -workaround is to stop QEMU as soon as you notice that your disk image -size is growing too fast (monitor it with @code{ls -ls}). Then -relaunch QEMU to continue the installation. If you still experience -the problem, relaunch QEMU again. - -Future QEMU releases are likely to correct this bug. - -@subsubsection Windows XP security problems - -Some releases of Windows XP install correctly but give a security -error when booting: -@example -A problem is preventing Windows from accurately checking the -license for this computer. Error code: 0x800703e6. -@end example -The only known workaround is to boot in Safe mode -without networking support. - -Future QEMU releases are likely to correct this bug. - -@subsection MS-DOS and FreeDOS - -@subsubsection CPU usage reduction - -DOS does not correctly use the CPU HLT instruction. The result is that -it takes host CPU cycles even when idle. You can install the utility -from @url{http://www.vmware.com/software/dosidle210.zip} to solve this -problem. - -@chapter QEMU PowerPC System emulator invocation - -Use the executable @file{qemu-system-ppc} to simulate a complete PREP -or PowerMac PowerPC system. - -QEMU emulates the following PowerMac peripherials: - -@itemize @minus -@item -UniNorth PCI Bridge -@item -PCI VGA compatible card with VESA Bochs Extensions -@item -2 PMAC IDE interfaces with hard disk and CD-ROM support -@item -NE2000 PCI adapters -@item -Non Volatile RAM -@item -VIA-CUDA with ADB keyboard and mouse. -@end itemize - -QEMU emulates the following PREP peripherials: - -@itemize @minus -@item -PCI Bridge -@item -PCI VGA compatible card with VESA Bochs Extensions -@item -2 IDE interfaces with hard disk and CD-ROM support -@item -Floppy disk -@item -NE2000 network adapters -@item -Serial port -@item -PREP Non Volatile RAM -@item -PC compatible keyboard and mouse. -@end itemize - -QEMU uses the Open Hack'Ware Open Firmware Compatible BIOS available at -@url{http://site.voila.fr/jmayer/OpenHackWare/index.htm}. - -You can read the qemu PC system emulation chapter to have more -informations about QEMU usage. - -@c man begin OPTIONS - -The following options are specific to the PowerPC emulation: - -@table @option - -@item -prep -Simulate a PREP system (default is PowerMAC) - -@item -g WxH[xDEPTH] - -Set the initial VGA graphic mode. The default is 800x600x15. - -@end table - -@c man end - - -More information is available at -@url{http://jocelyn.mayer.free.fr/qemu-ppc/}. - -@chapter QEMU User space emulator invocation - -@section Quick Start - -In order to launch a Linux process, QEMU needs the process executable -itself and all the target (x86) dynamic libraries used by it. - -@itemize - -@item On x86, you can just try to launch any process by using the native -libraries: - -@example -qemu-i386 -L / /bin/ls -@end example - -@code{-L /} tells that the x86 dynamic linker must be searched with a -@file{/} prefix. - -@item Since QEMU is also a linux process, you can launch qemu with qemu (NOTE: you can only do that if you compiled QEMU from the sources): - -@example -qemu-i386 -L / qemu-i386 -L / /bin/ls -@end example - -@item On non x86 CPUs, you need first to download at least an x86 glibc -(@file{qemu-runtime-i386-XXX-.tar.gz} on the QEMU web page). Ensure that -@code{LD_LIBRARY_PATH} is not set: - -@example -unset LD_LIBRARY_PATH -@end example - -Then you can launch the precompiled @file{ls} x86 executable: - -@example -qemu-i386 tests/i386/ls -@end example -You can look at @file{qemu-binfmt-conf.sh} so that -QEMU is automatically launched by the Linux kernel when you try to -launch x86 executables. It requires the @code{binfmt_misc} module in the -Linux kernel. - -@item The x86 version of QEMU is also included. You can try weird things such as: -@example -qemu-i386 /usr/local/qemu-i386/bin/qemu-i386 /usr/local/qemu-i386/bin/ls-i386 -@end example - -@end itemize - -@section Wine launch - -@itemize - -@item Ensure that you have a working QEMU with the x86 glibc -distribution (see previous section). In order to verify it, you must be -able to do: - -@example -qemu-i386 /usr/local/qemu-i386/bin/ls-i386 -@end example - -@item Download the binary x86 Wine install -(@file{qemu-XXX-i386-wine.tar.gz} on the QEMU web page). - -@item Configure Wine on your account. Look at the provided script -@file{/usr/local/qemu-i386/bin/wine-conf.sh}. Your previous -@code{$@{HOME@}/.wine} directory is saved to @code{$@{HOME@}/.wine.org}. - -@item Then you can try the example @file{putty.exe}: - -@example -qemu-i386 /usr/local/qemu-i386/wine/bin/wine /usr/local/qemu-i386/wine/c/Program\ Files/putty.exe -@end example - -@end itemize - -@section Command line options - -@example -usage: qemu-i386 [-h] [-d] [-L path] [-s size] program [arguments...] -@end example - -@table @option -@item -h -Print the help -@item -L path -Set the x86 elf interpreter prefix (default=/usr/local/qemu-i386) -@item -s size -Set the x86 stack size in bytes (default=524288) -@end table - -Debug options: - -@table @option -@item -d -Activate log (logfile=/tmp/qemu.log) -@item -p pagesize -Act as if the host page size was 'pagesize' bytes -@end table - -@node compilation -@chapter Compilation from the sources - -@section Linux/BSD - -Read the @file{README} which gives the related information. - -@section Windows - -@itemize -@item Install the current versions of MSYS and MinGW from -@url{http://www.mingw.org/}. You can find detailed installation -instructions in the download section and the FAQ. - -@item Download -the MinGW development library of SDL 1.2.x -(@file{SDL-devel-1.2.x-mingw32.tar.gz}) from -@url{http://www.libsdl.org}. Unpack it in a temporary place, and -unpack the archive @file{i386-mingw32msvc.tar.gz} in the MinGW tool -directory. Edit the @file{sdl-config} script so that it gives the -correct SDL directory when invoked. - -@item Extract the current version of QEMU. - -@item Start the MSYS shell (file @file{msys.bat}). - -@item Change to the QEMU directory. Launch @file{./configure} and -@file{make}. If you have problems using SDL, verify that -@file{sdl-config} can be launched from the MSYS command line. - -@item You can install QEMU in @file{Program Files/Qemu} by typing -@file{make install}. Don't forget to copy @file{SDL.dll} in -@file{Program Files/Qemu}. - -@end itemize - -@section Cross compilation for Windows with Linux - -@itemize -@item -Install the MinGW cross compilation tools available at -@url{http://www.mingw.org/}. - -@item -Install the Win32 version of SDL (@url{http://www.libsdl.org}) by -unpacking @file{i386-mingw32msvc.tar.gz}. Set up the PATH environment -variable so that @file{i386-mingw32msvc-sdl-config} can be launched by -the QEMU configuration script. - -@item -Configure QEMU for Windows cross compilation: -@example -./configure --enable-mingw32 -@end example -If necessary, you can change the cross-prefix according to the prefix -choosen for the MinGW tools with --cross-prefix. You can also use ---prefix to set the Win32 install path. - -@item You can install QEMU in the installation directory by typing -@file{make install}. Don't forget to copy @file{SDL.dll} in the -installation directory. - -@end itemize - -Note: Currently, Wine does not seem able to launch -QEMU for Win32. - -@section Mac OS X - -The Mac OS X patches are not fully merged in QEMU, so you should look -at the QEMU mailing list archive to have all the necessary -information. - diff --git a/tools/ioemu/qemu-mkcow.1 b/tools/ioemu/qemu-mkcow.1 deleted file mode 100644 index d156de6fbb..0000000000 --- a/tools/ioemu/qemu-mkcow.1 +++ /dev/null @@ -1,105 +0,0 @@ -.\" $Header: /cvsroot/qemu/qemu/qemu-mkcow.1,v 1.1 2004/03/26 22:42:54 bellard Exp $ -.\" -.\" transcript compatibility for postscript use. -.\" -.\" synopsis: .P! <file.ps> -.\" -.de P! -.fl -\!!1 setgray -.fl -\\&.\" -.fl -\!!0 setgray -.fl \" force out current output buffer -\!!save /psv exch def currentpoint translate 0 0 moveto -\!!/showpage{}def -.fl \" prolog -.sy sed -e 's/^/!/' \\$1\" bring in postscript file -\!!psv restore -. -.de pF -.ie \\*(f1 .ds f1 \\n(.f -.el .ie \\*(f2 .ds f2 \\n(.f -.el .ie \\*(f3 .ds f3 \\n(.f -.el .ie \\*(f4 .ds f4 \\n(.f -.el .tm ? font overflow -.ft \\$1 -.. -.de fP -.ie !\\*(f4 \{\ -. ft \\*(f4 -. ds f4\" -' br \} -.el .ie !\\*(f3 \{\ -. ft \\*(f3 -. ds f3\" -' br \} -.el .ie !\\*(f2 \{\ -. ft \\*(f2 -. ds f2\" -' br \} -.el .ie !\\*(f1 \{\ -. ft \\*(f1 -. ds f1\" -' br \} -.el .tm ? font underflow -.. -.ds f1\" -.ds f2\" -.ds f3\" -.ds f4\" -'\" t -.ta 8n 16n 24n 32n 40n 48n 56n 64n 72n -.TH "QEMU" "8" -.SH "NAME" -qemu-mkcow \(em create a copy-on-write file for qemu -.SH "SYNOPSIS" -.PP -\fBqemu-mkcow\fR [\fB-h\fP] [\fB-f \fImaster_disk_image\fR\fP] [\fIcow_image\fR] [\fB\fIcow_size\fR\fP] -.SH "DESCRIPTION" -.PP -The \fBqemu-mkcow\fR command creates a -persistent copy-on-write file for \fBqemu\fR. - -.PP -\fBqemu\fR can be used in a "copy-on-write" mode, -where changes made by \fBqemu\fR do not actually -change the disk image file. One way is to invoke -\fBqemu\fR with -snapshot: these changes -are stored in a temporary file, which is discarded when -\fBqemu\fR exits. - -.PP -\fBqemu-mkcow\fR creates an explicit copy-on-write -file where changes are to be stored: this way, changes made -inside \fBqemu\fR will still be there next time you -run it, although the master disk image isn't ever changed. - -.PP -The usual method is to create the master image, then create a -copy-on-write file using \fBqemu-mkcow\fR with -\fB-f\fP. The filename of the master image is stored -inside the generated copy-on-write file: it must not be modified -after this is run! - -.PP -If no master file is specified, the effect is that of a -blank master of size \fIcow_size\fR. - -.SH "SEE ALSO" -.PP -qemu(1), qemu-fast(1). -.SH "AUTHOR" -.PP -This manual page was written by Paul Russell prussell@debian.org for -the \fBDebian\fP system (but may be used by others). Permission is -granted to copy, distribute and/or modify this document under -the terms of the GNU General Public License, Version 2 any -later version published by the Free Software Foundation. - -.PP -On Debian systems, the complete text of the GNU General Public -License can be found in /usr/share/common-licenses/GPL. - -.\" created by instant / docbook-to-man, Fri 12 Mar 2004, 05:58 diff --git a/tools/ioemu/qemu-tech.html b/tools/ioemu/qemu-tech.html deleted file mode 100644 index 4277cfed1b..0000000000 --- a/tools/ioemu/qemu-tech.html +++ /dev/null @@ -1,1303 +0,0 @@ -<HTML> -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<!-- Created on January, 25 2005 by texi2html 1.64 --> -<!-- -Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author) - Karl Berry <karl@freefriends.org> - Olaf Bachmann <obachman@mathematik.uni-kl.de> - and many others. -Maintained by: Olaf Bachmann <obachman@mathematik.uni-kl.de> -Send bugs and suggestions to <texi2html@mathematik.uni-kl.de> - ---> -<HEAD> -<TITLE>Untitled Document: </TITLE> - -<META NAME="description" CONTENT="Untitled Document: "> -<META NAME="keywords" CONTENT="Untitled Document: "> -<META NAME="resource-type" CONTENT="document"> -<META NAME="distribution" CONTENT="global"> -<META NAME="Generator" CONTENT="texi2html 1.64"> - -</HEAD> - -<BODY LANG="" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000"> - -<A NAME="SEC1"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC2"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<P> - -<H1> 1. Introduction </H1> -<!--docid::SEC1::--> -<P> - -<HR SIZE="6"> -<A NAME="SEC2"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC3"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 1.1 Features </H2> -<!--docid::SEC2::--> -<P> - -QEMU is a FAST! processor emulator using a portable dynamic -translator. -</P><P> - -QEMU has two operating modes: -</P><P> - -<UL> - -<LI> -Full system emulation. In this mode, QEMU emulates a full system -(usually a PC), including a processor and various peripherials. It can -be used to launch an different Operating System without rebooting the -PC or to debug system code. -<P> - -<LI> -User mode emulation (Linux host only). In this mode, QEMU can launch -Linux processes compiled for one CPU on another CPU. It can be used to -launch the Wine Windows API emulator (<A HREF="http://www.winehq.org">http://www.winehq.org</A>) or -to ease cross-compilation and cross-debugging. -<P> - -</UL> -<P> - -As QEMU requires no host kernel driver to run, it is very safe and -easy to use. -</P><P> - -QEMU generic features: -</P><P> - -<UL> - -<LI>User space only or full system emulation. -<P> - -<LI>Using dynamic translation to native code for reasonnable speed. -<P> - -<LI>Working on x86 and PowerPC hosts. Being tested on ARM, Sparc32, Alpha and S390. -<P> - -<LI>Self-modifying code support. -<P> - -<LI>Precise exceptions support. -<P> - -<LI>The virtual CPU is a library (<CODE>libqemu</CODE>) which can be used -in other projects (look at <TT>`qemu/tests/qruncom.c'</TT> to have an -example of user mode <CODE>libqemu</CODE> usage). -<P> - -</UL> -<P> - -QEMU user mode emulation features: -<UL> -<LI>Generic Linux system call converter, including most ioctls. -<P> - -<LI>clone() emulation using native CPU clone() to use Linux scheduler for threads. -<P> - -<LI>Accurate signal handling by remapping host signals to target signals. -</UL> -</UL> - -QEMU full system emulation features: -<UL> -<LI>QEMU can either use a full software MMU for maximum portability or use the host system call mmap() to simulate the target MMU. -</UL> - -<HR SIZE="6"> -<A NAME="SEC3"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC2"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC4"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 1.2 x86 emulation </H2> -<!--docid::SEC3::--> -<P> - -QEMU x86 target features: -</P><P> - -<UL> - -<LI>The virtual x86 CPU supports 16 bit and 32 bit addressing with segmentation. -LDT/GDT and IDT are emulated. VM86 mode is also supported to run DOSEMU. -<P> - -<LI>Support of host page sizes bigger than 4KB in user mode emulation. -<P> - -<LI>QEMU can emulate itself on x86. -<P> - -<LI>An extensive Linux x86 CPU test program is included <TT>`tests/test-i386'</TT>. -It can be used to test other x86 virtual CPUs. -<P> - -</UL> -<P> - -Current QEMU limitations: -</P><P> - -<UL> - -<LI>No SSE/MMX support (yet). -<P> - -<LI>No x86-64 support. -<P> - -<LI>IPC syscalls are missing. -<P> - -<LI>The x86 segment limits and access rights are not tested at every -memory access (yet). Hopefully, very few OSes seem to rely on that for -normal use. -<P> - -<LI>On non x86 host CPUs, <CODE>double</CODE>s are used instead of the non standard -10 byte <CODE>long double</CODE>s of x86 for floating point emulation to get -maximum performances. -<P> - -</UL> -<P> - -<HR SIZE="6"> -<A NAME="SEC4"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC3"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC5"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 1.3 ARM emulation </H2> -<!--docid::SEC4::--> -<P> - -<UL> - -<LI>Full ARM 7 user emulation. -<P> - -<LI>NWFPE FPU support included in user Linux emulation. -<P> - -<LI>Can run most ARM Linux binaries. -<P> - -</UL> -<P> - -<HR SIZE="6"> -<A NAME="SEC5"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC4"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC6"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 1.4 PowerPC emulation </H2> -<!--docid::SEC5::--> -<P> - -<UL> - -<LI>Full PowerPC 32 bit emulation, including priviledged instructions, -FPU and MMU. -<P> - -<LI>Can run most PowerPC Linux binaries. -<P> - -</UL> -<P> - -<HR SIZE="6"> -<A NAME="SEC6"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC5"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC7"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 1.5 SPARC emulation </H2> -<!--docid::SEC6::--> -<P> - -<UL> - -<LI>SPARC V8 user support, except FPU instructions. -<P> - -<LI>Can run some SPARC Linux binaries. -<P> - -</UL> -<P> - -<HR SIZE="6"> -<A NAME="SEC7"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC6"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC8"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H1> 2. QEMU Internals </H1> -<!--docid::SEC7::--> -<P> - -<HR SIZE="6"> -<A NAME="SEC8"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC7"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC9"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 2.1 QEMU compared to other emulators </H2> -<!--docid::SEC8::--> -<P> - -Like bochs <A HREF="qemu-tech.html#BIB3">[3]</A>, QEMU emulates an x86 CPU. But QEMU is much faster than -bochs as it uses dynamic compilation. Bochs is closely tied to x86 PC -emulation while QEMU can emulate several processors. -</P><P> - -Like Valgrind <A HREF="qemu-tech.html#BIB2">[2]</A>, 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). The Valgrind dynamic translator generates better code -than QEMU (in particular it does register allocation) but it is closely -tied to an x86 host and target and has no support for precise exceptions -and system emulation. -</P><P> - -EM86 <A HREF="qemu-tech.html#BIB4">[4]</A> is the closest project to user space 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 <A HREF="qemu-tech.html#BIB5">[5]</A>). -</P><P> - -TWIN <A HREF="qemu-tech.html#BIB6">[6]</A> is a Windows API emulator like Wine. It is less accurate than -Wine but includes a protected mode x86 interpreter to launch x86 Windows -executables. Such an approach has greater potential because most of the -Windows API is executed natively but it is far more difficult to develop -because all the data structures and function parameters exchanged -between the API and the x86 code must be converted. -</P><P> - -User mode Linux <A HREF="qemu-tech.html#BIB7">[7]</A> was the only solution before QEMU to launch a -Linux kernel as a process while not needing any host kernel -patches. However, user mode Linux requires heavy kernel patches while -QEMU accepts unpatched Linux kernels. The price to pay is that QEMU is -slower. -</P><P> - -The new Plex86 <A HREF="qemu-tech.html#BIB8">[8]</A> PC virtualizer is done in the same spirit as the -qemu-fast system emulator. It requires a patched Linux kernel to work -(you cannot launch the same kernel on your PC), but the patches are -really small. As it is a PC virtualizer (no emulation is done except -for some priveledged instructions), it has the potential of being -faster than QEMU. The downside is that a complicated (and potentially -unsafe) host kernel patch is needed. -</P><P> - -The commercial PC Virtualizers (VMWare <A HREF="qemu-tech.html#BIB9">[9]</A>, VirtualPC <A HREF="qemu-tech.html#BIB10">[10]</A>, TwoOStwo -<A HREF="qemu-tech.html#BIB11">[11]</A>) are faster than QEMU, but they all need specific, proprietary -and potentially unsafe host drivers. Moreover, they are unable to -provide cycle exact simulation as an emulator can. -</P><P> - -<HR SIZE="6"> -<A NAME="SEC9"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC8"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC10"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 2.2 Portable dynamic translation </H2> -<!--docid::SEC9::--> -<P> - -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 dependent. QEMU uses some tricks -which make it relatively easily portable and simple while achieving good -performances. -</P><P> - -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 <TT>`target-i386/op.c'</TT>). Then a compile time tool -(<TT>`dyngen'</TT>) takes the corresponding object file (<TT>`op.o'</TT>) -to generate a dynamic code generator which concatenates the simple -instructions to build a function (see <TT>`op.h:dyngen_code()'</TT>). -</P><P> - -In essence, the process is similar to <A HREF="qemu-tech.html#BIB1">[1]</A>, but more work is done at -compile time. -</P><P> - -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 (<TT>`dyngen'</TT>) can locate the relocations and generate the -appriopriate C code to resolve them when building the dynamic code. -</P><P> - -That way, QEMU is no more difficult to port than a dynamic linker. -</P><P> - -To go even faster, GCC static register variables are used to keep the -state of the virtual CPU. -</P><P> - -<HR SIZE="6"> -<A NAME="SEC10"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC9"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC11"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 2.3 Register allocation </H2> -<!--docid::SEC10::--> -<P> - -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. -</P><P> - -<HR SIZE="6"> -<A NAME="SEC11"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC10"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC12"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 2.4 Condition code optimisations </H2> -<!--docid::SEC11::--> -<P> - -Good CPU condition codes emulation (<CODE>EFLAGS</CODE> 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 just stores one operand (called <CODE>CC_SRC</CODE>), the -result (called <CODE>CC_DST</CODE>) and the type of operation (called -<CODE>CC_OP</CODE>). -</P><P> - -<CODE>CC_OP</CODE> is almost never explicitely set in the generated code -because it is known at translation time. -</P><P> - -In order to increase performances, a backward pass is performed on the -generated simple instructions (see -<CODE>target-i386/translate.c:optimize_flags()</CODE>). When it can be proved that -the condition codes are not needed by the next instructions, no -condition codes are computed at all. -</P><P> - -<HR SIZE="6"> -<A NAME="SEC12"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC11"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC13"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 2.5 CPU state optimisations </H2> -<!--docid::SEC12::--> -<P> - -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. -</P><P> - -[The FPU stack pointer register is not handled that way yet]. -</P><P> - -<HR SIZE="6"> -<A NAME="SEC13"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC12"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC14"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 2.6 Translation cache </H2> -<!--docid::SEC13::--> -<P> - -A 16 MByte 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). -</P><P> - -<HR SIZE="6"> -<A NAME="SEC14"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC13"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC15"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 2.7 Direct block chaining </H2> -<!--docid::SEC14::--> -<P> - -After each translated basic block is executed, QEMU uses the simulated -Program Counter (PC) and other cpu state informations (such as the CS -segment base value) to find the next basic block. -</P><P> - -In order to accelerate the most common cases where the new simulated PC -is known, QEMU can patch a basic block so that it jumps directly to the -next one. -</P><P> - -The most portable code uses an indirect jump. An indirect jump makes -it easier to make the jump target modification atomic. On some host -architectures (such as x86 or PowerPC), the <CODE>JUMP</CODE> opcode is -directly patched so that the block chaining has no overhead. -</P><P> - -<HR SIZE="6"> -<A NAME="SEC15"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC14"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC16"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 2.8 Self-modifying code and translated code invalidation </H2> -<!--docid::SEC15::--> -<P> - -Self-modifying code is a special challenge in x86 emulation because no -instruction cache invalidation is signaled by the application when code -is modified. -</P><P> - -When translated code is generated for a basic block, the corresponding -host page is write protected if it is not already read-only (with the -system call <CODE>mprotect()</CODE>). Then, if a write access is done to the -page, Linux raises a SEGV signal. QEMU then invalidates all the -translated code in the page and enables write accesses to the page. -</P><P> - -Correct translated code invalidation is done efficiently by maintaining -a linked list of every translated block contained in a given page. Other -linked lists are also maintained to undo direct block chaining. -</P><P> - -Although the overhead of doing <CODE>mprotect()</CODE> calls is important, -most MSDOS programs can be emulated at reasonnable speed with QEMU and -DOSEMU. -</P><P> - -Note that QEMU also invalidates pages of translated code when it detects -that memory mappings are modified with <CODE>mmap()</CODE> or <CODE>munmap()</CODE>. -</P><P> - -When using a software MMU, the code invalidation is more efficient: if -a given code page is invalidated too often because of write accesses, -then a bitmap representing all the code inside the page is -built. Every store into that page checks the bitmap to see if the code -really needs to be invalidated. It avoids invalidating the code when -only data is modified in the page. -</P><P> - -<HR SIZE="6"> -<A NAME="SEC16"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC15"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC17"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 2.9 Exception support </H2> -<!--docid::SEC16::--> -<P> - -longjmp() is used when an exception such as division by zero is -encountered. -</P><P> - -The host SIGSEGV and SIGBUS signal handlers are used to get invalid -memory accesses. The exact CPU state can be retrieved because all the -x86 registers are stored in fixed host registers. The simulated program -counter is found by retranslating the corresponding basic block and by -looking where the host program counter was at the exception point. -</P><P> - -The virtual CPU cannot retrieve the exact <CODE>EFLAGS</CODE> register because -in some cases it is not computed because of condition code -optimisations. It is not a big concern because the emulated code can -still be restarted in any cases. -</P><P> - -<HR SIZE="6"> -<A NAME="SEC17"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC16"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC18"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 2.10 MMU emulation </H2> -<!--docid::SEC17::--> -<P> - -For system emulation, QEMU uses the mmap() system call to emulate the -target CPU MMU. It works as long the emulated OS does not use an area -reserved by the host OS (such as the area above 0xc0000000 on x86 -Linux). -</P><P> - -In order to be able to launch any OS, QEMU also supports a soft -MMU. In that mode, the MMU virtual to physical address translation is -done at every memory access. QEMU uses an address translation cache to -speed up the translation. -</P><P> - -In order to avoid flushing the translated code each time the MMU -mappings change, QEMU uses a physically indexed translation cache. It -means that each basic block is indexed with its physical address. -</P><P> - -When MMU mappings change, only the chaining of the basic blocks is -reset (i.e. a basic block can no longer jump directly to another one). -</P><P> - -<HR SIZE="6"> -<A NAME="SEC18"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC17"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC19"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 2.11 Hardware interrupts </H2> -<!--docid::SEC18::--> -<P> - -In order to be faster, QEMU does not check at every basic block if an -hardware interrupt is pending. Instead, the user must asynchrously -call a specific function to tell that an interrupt is pending. This -function resets the chaining of the currently executing basic -block. It ensures that the execution will return soon in the main loop -of the CPU emulator. Then the main loop can test if the interrupt is -pending and handle it. -</P><P> - -<HR SIZE="6"> -<A NAME="SEC19"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC18"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC20"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 2.12 User emulation specific details </H2> -<!--docid::SEC19::--> -<P> - -<HR SIZE="6"> -<A NAME="SEC20"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC19"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC21"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 2.12.1 Linux system call translation </H3> -<!--docid::SEC20::--> -<P> - -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 <TT>`ioctls.h'</TT> and <TT>`thunk.c'</TT>). -</P><P> - -QEMU supports host CPUs which have pages bigger than 4KB. It records all -the mappings the process does and try to emulated the <CODE>mmap()</CODE> -system calls in cases where the host <CODE>mmap()</CODE> call would fail -because of bad page alignment. -</P><P> - -<HR SIZE="6"> -<A NAME="SEC21"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC20"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC22"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 2.12.2 Linux signals </H3> -<!--docid::SEC21::--> -<P> - -Normal and real-time signals are queued along with their information -(<CODE>siginfo_t</CODE>) 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()</CODE> system call is emulated to return -from the virtual signal handler. -</P><P> - -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()</CODE>). -</P><P> - -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()</CODE> and <CODE>sigreturn()</CODE> system -calls need to be fully emulated (see <TT>`signal.c'</TT>). -</P><P> - -<HR SIZE="6"> -<A NAME="SEC22"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC21"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC23"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 2.12.3 clone() system call and threads </H3> -<!--docid::SEC22::--> -<P> - -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. -</P><P> - -The virtual x86 CPU atomic operations are emulated with a global lock so -that their semantic is preserved. -</P><P> - -Note that currently there are still some locking issues in QEMU. In -particular, the translated cache flush is not protected yet against -reentrancy. -</P><P> - -<HR SIZE="6"> -<A NAME="SEC23"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC22"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC24"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 2.12.4 Self-virtualization </H3> -<!--docid::SEC23::--> -<P> - -QEMU was conceived so that ultimately it can emulate itself. Although -it is not very useful, it is an important test to show the power of the -emulator. -</P><P> - -Achieving self-virtualization is not easy because there may be address -space conflicts. QEMU solves this problem by being an executable ELF -shared object as the ld-linux.so ELF interpreter. That way, it can be -relocated at load time. -</P><P> - -<HR SIZE="6"> -<A NAME="SEC24"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC23"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC25"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 2.13 Bibliography </H2> -<!--docid::SEC24::--> -<P> - -<DL COMPACT> - -<DT><A NAME="BIB1">[1]</A> -<DD><A HREF="http://citeseer.nj.nec.com/piumarta98optimizing.html">http://citeseer.nj.nec.com/piumarta98optimizing.html</A>, Optimizing -direct threaded code by selective inlining (1998) by Ian Piumarta, Fabio -Riccardi. -<P> - -<DT><A NAME="BIB2">[2]</A> -<DD><A HREF="http://developer.kde.org/~sewardj/">http://developer.kde.org/~sewardj/</A>, Valgrind, an open-source -memory debugger for x86-GNU/Linux, by Julian Seward. -<P> - -<DT><A NAME="BIB3">[3]</A> -<DD><A HREF="http://bochs.sourceforge.net/">http://bochs.sourceforge.net/</A>, the Bochs IA-32 Emulator Project, -by Kevin Lawton et al. -<P> - -<DT><A NAME="BIB4">[4]</A> -<DD><A HREF="http://www.cs.rose-hulman.edu/~donaldlf/em86/index.html">http://www.cs.rose-hulman.edu/~donaldlf/em86/index.html</A>, the EM86 -x86 emulator on Alpha-Linux. -<P> - -<DT><A NAME="BIB5">[5]</A> -<DD><A HREF="http://www.usenix.org/publications/library/proceedings/usenix-nt97/full_papers/chernoff/chernoff.pdf">http://www.usenix.org/publications/library/proceedings/usenix-nt97/full_papers/chernoff/chernoff.pdf</A>, -DIGITAL FX!32: Running 32-Bit x86 Applications on Alpha NT, by Anton -Chernoff and Ray Hookway. -<P> - -<DT><A NAME="BIB6">[6]</A> -<DD><A HREF="http://www.willows.com/">http://www.willows.com/</A>, Windows API library emulation from -Willows Software. -<P> - -<DT><A NAME="BIB7">[7]</A> -<DD><A HREF="http://user-mode-linux.sourceforge.net/">http://user-mode-linux.sourceforge.net/</A>, -The User-mode Linux Kernel. -<P> - -<DT><A NAME="BIB8">[8]</A> -<DD><A HREF="http://www.plex86.org/">http://www.plex86.org/</A>, -The new Plex86 project. -<P> - -<DT><A NAME="BIB9">[9]</A> -<DD><A HREF="http://www.vmware.com/">http://www.vmware.com/</A>, -The VMWare PC virtualizer. -<P> - -<DT><A NAME="BIB10">[10]</A> -<DD><A HREF="http://www.microsoft.com/windowsxp/virtualpc/">http://www.microsoft.com/windowsxp/virtualpc/</A>, -The VirtualPC PC virtualizer. -<P> - -<DT><A NAME="BIB11">[11]</A> -<DD><A HREF="http://www.twoostwo.org/">http://www.twoostwo.org/</A>, -The TwoOStwo PC virtualizer. -<P> - -</DL> -<P> - -<HR SIZE="6"> -<A NAME="SEC25"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC24"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC26"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H1> 3. Regression Tests </H1> -<!--docid::SEC25::--> -<P> - -In the directory <TT>`tests/'</TT>, various interesting testing programs -are available. There are used for regression testing. -</P><P> - -<HR SIZE="6"> -<A NAME="SEC26"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC25"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC27"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 3.1 <TT>`test-i386'</TT> </H2> -<!--docid::SEC26::--> -<P> - -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</CODE> runs this -program and a <CODE>diff</CODE> on the generated output. -</P><P> - -The Linux system call <CODE>modify_ldt()</CODE> is used to create x86 selectors -to test some 16 bit addressing and 32 bit with segmentation cases. -</P><P> - -The Linux system call <CODE>vm86()</CODE> is used to test vm86 emulation. -</P><P> - -Various exceptions are raised to test most of the x86 user space -exception reporting. -</P><P> - -<HR SIZE="6"> -<A NAME="SEC27"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC26"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC28"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 3.2 <TT>`linux-test'</TT> </H2> -<!--docid::SEC27::--> -<P> - -This program tests various Linux system calls. It is used to verify -that the system call parameters are correctly converted between target -and host CPUs. -</P><P> - -<HR SIZE="6"> -<A NAME="SEC28"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC27"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ > ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[ >> ]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 3.3 <TT>`qruncom.c'</TT> </H2> -<!--docid::SEC28::--> -<P> - -Example of usage of <CODE>libqemu</CODE> to emulate a user mode i386 CPU. -<HR SIZE="6"> -<A NAME="SEC_Contents"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H1>Table of Contents</H1> -<UL> -<A NAME="TOC1" HREF="qemu-tech.html#SEC1">1. Introduction</A> -<BR> -<UL> -<A NAME="TOC2" HREF="qemu-tech.html#SEC2">1.1 Features</A> -<BR> -<A NAME="TOC3" HREF="qemu-tech.html#SEC3">1.2 x86 emulation</A> -<BR> -<A NAME="TOC4" HREF="qemu-tech.html#SEC4">1.3 ARM emulation</A> -<BR> -<A NAME="TOC5" HREF="qemu-tech.html#SEC5">1.4 PowerPC emulation</A> -<BR> -<A NAME="TOC6" HREF="qemu-tech.html#SEC6">1.5 SPARC emulation</A> -<BR> -</UL> -<A NAME="TOC7" HREF="qemu-tech.html#SEC7">2. QEMU Internals</A> -<BR> -<UL> -<A NAME="TOC8" HREF="qemu-tech.html#SEC8">2.1 QEMU compared to other emulators</A> -<BR> -<A NAME="TOC9" HREF="qemu-tech.html#SEC9">2.2 Portable dynamic translation</A> -<BR> -<A NAME="TOC10" HREF="qemu-tech.html#SEC10">2.3 Register allocation</A> -<BR> -<A NAME="TOC11" HREF="qemu-tech.html#SEC11">2.4 Condition code optimisations</A> -<BR> -<A NAME="TOC12" HREF="qemu-tech.html#SEC12">2.5 CPU state optimisations</A> -<BR> -<A NAME="TOC13" HREF="qemu-tech.html#SEC13">2.6 Translation cache</A> -<BR> -<A NAME="TOC14" HREF="qemu-tech.html#SEC14">2.7 Direct block chaining</A> -<BR> -<A NAME="TOC15" HREF="qemu-tech.html#SEC15">2.8 Self-modifying code and translated code invalidation</A> -<BR> -<A NAME="TOC16" HREF="qemu-tech.html#SEC16">2.9 Exception support</A> -<BR> -<A NAME="TOC17" HREF="qemu-tech.html#SEC17">2.10 MMU emulation</A> -<BR> -<A NAME="TOC18" HREF="qemu-tech.html#SEC18">2.11 Hardware interrupts</A> -<BR> -<A NAME="TOC19" HREF="qemu-tech.html#SEC19">2.12 User emulation specific details</A> -<BR> -<UL> -<A NAME="TOC20" HREF="qemu-tech.html#SEC20">2.12.1 Linux system call translation</A> -<BR> -<A NAME="TOC21" HREF="qemu-tech.html#SEC21">2.12.2 Linux signals</A> -<BR> -<A NAME="TOC22" HREF="qemu-tech.html#SEC22">2.12.3 clone() system call and threads</A> -<BR> -<A NAME="TOC23" HREF="qemu-tech.html#SEC23">2.12.4 Self-virtualization</A> -<BR> -</UL> -<A NAME="TOC24" HREF="qemu-tech.html#SEC24">2.13 Bibliography</A> -<BR> -</UL> -<A NAME="TOC25" HREF="qemu-tech.html#SEC25">3. Regression Tests</A> -<BR> -<UL> -<A NAME="TOC26" HREF="qemu-tech.html#SEC26">3.1 <TT>`test-i386'</TT></A> -<BR> -<A NAME="TOC27" HREF="qemu-tech.html#SEC27">3.2 <TT>`linux-test'</TT></A> -<BR> -<A NAME="TOC28" HREF="qemu-tech.html#SEC28">3.3 <TT>`qruncom.c'</TT></A> -<BR> -</UL> -</UL> -<HR SIZE=1> -<A NAME="SEC_OVERVIEW"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H1>Short Table of Contents</H1> -<BLOCKQUOTE> -<A NAME="TOC1" HREF="qemu-tech.html#SEC1">1. Introduction</A> -<BR> -<A NAME="TOC7" HREF="qemu-tech.html#SEC7">2. QEMU Internals</A> -<BR> -<A NAME="TOC25" HREF="qemu-tech.html#SEC25">3. Regression Tests</A> -<BR> - -</BLOCKQUOTE> -<HR SIZE=1> -<A NAME="SEC_About"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H1>About this document</H1> -This document was generated on <I>January, 25 2005</I> -using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html -"><I>texi2html</I></A> -<P></P> -The buttons in the navigation panels have the following meaning: -<P></P> -<table border = "1"> -<TR> -<TH> Button </TH> -<TH> Name </TH> -<TH> Go to </TH> -<TH> From 1.2.3 go to</TH> -</TR> -<TR> -<TD ALIGN="CENTER"> - [ < ] </TD> -<TD ALIGN="CENTER"> -Back -</TD> -<TD> -previous section in reading order -</TD> -<TD> -1.2.2 -</TD> -</TR> -<TR> -<TD ALIGN="CENTER"> - [ > ] </TD> -<TD ALIGN="CENTER"> -Forward -</TD> -<TD> -next section in reading order -</TD> -<TD> -1.2.4 -</TD> -</TR> -<TR> -<TD ALIGN="CENTER"> - [ << ] </TD> -<TD ALIGN="CENTER"> -FastBack -</TD> -<TD> -previous or up-and-previous section -</TD> -<TD> -1.1 -</TD> -</TR> -<TR> -<TD ALIGN="CENTER"> - [ Up ] </TD> -<TD ALIGN="CENTER"> -Up -</TD> -<TD> -up section -</TD> -<TD> -1.2 -</TD> -</TR> -<TR> -<TD ALIGN="CENTER"> - [ >> ] </TD> -<TD ALIGN="CENTER"> -FastForward -</TD> -<TD> -next or up-and-next section -</TD> -<TD> -1.3 -</TD> -</TR> -<TR> -<TD ALIGN="CENTER"> - [Top] </TD> -<TD ALIGN="CENTER"> -Top -</TD> -<TD> -cover (top) of document -</TD> -<TD> - -</TD> -</TR> -<TR> -<TD ALIGN="CENTER"> - [Contents] </TD> -<TD ALIGN="CENTER"> -Contents -</TD> -<TD> -table of contents -</TD> -<TD> - -</TD> -</TR> -<TR> -<TD ALIGN="CENTER"> - [Index] </TD> -<TD ALIGN="CENTER"> -Index -</TD> -<TD> -concept index -</TD> -<TD> - -</TD> -</TR> -<TR> -<TD ALIGN="CENTER"> - [ ? ] </TD> -<TD ALIGN="CENTER"> -About -</TD> -<TD> -this page -</TD> -<TD> - -</TD> -</TR> -</TABLE> -<P></P> -where the <STRONG> Example </STRONG> assumes that the current position -is at <STRONG> Subsubsection One-Two-Three </STRONG> of a document of -the following structure: -<UL> -<LI> 1. Section One </LI> -<UL> -<LI>1.1 Subsection One-One</LI> -<UL> -<LI> ... </LI> -</UL> -<LI>1.2 Subsection One-Two</LI> -<UL> -<LI>1.2.1 Subsubsection One-Two-One -</LI><LI>1.2.2 Subsubsection One-Two-Two -</LI><LI>1.2.3 Subsubsection One-Two-Three <STRONG> -<== Current Position </STRONG> -</LI><LI>1.2.4 Subsubsection One-Two-Four -</LI></UL> -<LI>1.3 Subsection One-Three</LI> -<UL> -<LI> ... </LI> -</UL> -<LI>1.4 Subsection One-Four</LI> -</UL> -</UL> - -<HR SIZE=1> -<BR> -<FONT SIZE="-1"> -This document was generated -on <I>January, 25 2005</I> -using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html -"><I>texi2html</I></A> - -</BODY> -</HTML> diff --git a/tools/ioemu/qemu-tech.texi b/tools/ioemu/qemu-tech.texi deleted file mode 100644 index 4e6f507c74..0000000000 --- a/tools/ioemu/qemu-tech.texi +++ /dev/null @@ -1,494 +0,0 @@ -\input texinfo @c -*- texinfo -*- - -@iftex -@settitle QEMU Internals -@titlepage -@sp 7 -@center @titlefont{QEMU Internals} -@sp 3 -@end titlepage -@end iftex - -@chapter Introduction - -@section Features - -QEMU is a FAST! processor emulator using a portable dynamic -translator. - -QEMU has two operating modes: - -@itemize @minus - -@item -Full system emulation. In this mode, QEMU emulates a full system -(usually a PC), including a processor and various peripherials. It can -be used to launch an different Operating System without rebooting the -PC or to debug system code. - -@item -User mode emulation (Linux host only). In this mode, QEMU can launch -Linux processes compiled for one CPU on another CPU. It can be used to -launch the Wine Windows API emulator (@url{http://www.winehq.org}) or -to ease cross-compilation and cross-debugging. - -@end itemize - -As QEMU requires no host kernel driver to run, it is very safe and -easy to use. - -QEMU generic features: - -@itemize - -@item User space only or full system emulation. - -@item Using dynamic translation to native code for reasonnable speed. - -@item Working on x86 and PowerPC hosts. Being tested on ARM, Sparc32, Alpha and S390. - -@item Self-modifying code support. - -@item Precise exceptions support. - -@item The virtual CPU is a library (@code{libqemu}) which can be used -in other projects (look at @file{qemu/tests/qruncom.c} to have an -example of user mode @code{libqemu} usage). - -@end itemize - -QEMU user mode emulation features: -@itemize -@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 target signals. -@end itemize -@end itemize - -QEMU full system emulation features: -@itemize -@item QEMU can either use a full software MMU for maximum portability or use the host system call mmap() to simulate the target MMU. -@end itemize - -@section x86 emulation - -QEMU x86 target features: - -@itemize - -@item The virtual x86 CPU supports 16 bit and 32 bit addressing with segmentation. -LDT/GDT and IDT are emulated. VM86 mode is also supported to run DOSEMU. - -@item Support of host page sizes bigger than 4KB in user mode emulation. - -@item QEMU can emulate itself on x86. - -@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 No SSE/MMX support (yet). - -@item No x86-64 support. - -@item IPC syscalls are missing. - -@item The x86 segment limits and access rights are not tested at every -memory access (yet). Hopefully, very few OSes seem to rely on that for -normal use. - -@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 - -@section ARM emulation - -@itemize - -@item Full ARM 7 user emulation. - -@item NWFPE FPU support included in user Linux emulation. - -@item Can run most ARM Linux binaries. - -@end itemize - -@section PowerPC emulation - -@itemize - -@item Full PowerPC 32 bit emulation, including priviledged instructions, -FPU and MMU. - -@item Can run most PowerPC Linux binaries. - -@end itemize - -@section SPARC emulation - -@itemize - -@item SPARC V8 user support, except FPU instructions. - -@item Can run some SPARC Linux binaries. - -@end itemize - -@chapter QEMU Internals - -@section QEMU compared to other emulators - -Like bochs [3], QEMU emulates an x86 CPU. But QEMU is much faster than -bochs as it uses dynamic compilation. Bochs is closely tied to x86 PC -emulation while QEMU can emulate several processors. - -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). The Valgrind dynamic translator generates better code -than QEMU (in particular it does register allocation) but it is closely -tied to an x86 host and target and has no support for precise exceptions -and system emulation. - -EM86 [4] is the closest project to user space 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]). - -TWIN [6] is a Windows API emulator like Wine. It is less accurate than -Wine but includes a protected mode x86 interpreter to launch x86 Windows -executables. Such an approach has greater potential because most of the -Windows API is executed natively but it is far more difficult to develop -because all the data structures and function parameters exchanged -between the API and the x86 code must be converted. - -User mode Linux [7] was the only solution before QEMU to launch a -Linux kernel as a process while not needing any host kernel -patches. However, user mode Linux requires heavy kernel patches while -QEMU accepts unpatched Linux kernels. The price to pay is that QEMU is -slower. - -The new Plex86 [8] PC virtualizer is done in the same spirit as the -qemu-fast system emulator. It requires a patched Linux kernel to work -(you cannot launch the same kernel on your PC), but the patches are -really small. As it is a PC virtualizer (no emulation is done except -for some priveledged instructions), it has the potential of being -faster than QEMU. The downside is that a complicated (and potentially -unsafe) host kernel patch is needed. - -The commercial PC Virtualizers (VMWare [9], VirtualPC [10], TwoOStwo -[11]) are faster than QEMU, but they all need specific, proprietary -and potentially unsafe host drivers. Moreover, they are unable to -provide cycle exact simulation as an emulator can. - -@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 dependent. 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{target-i386/op.c}). Then a compile time tool -(@file{dyngen}) takes the corresponding object file (@file{op.o}) -to generate a dynamic code generator which concatenates the simple -instructions to build a function (see @file{op.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 just stores one operand (called @code{CC_SRC}), 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{target-i386/translate.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 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 16 MByte 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). - -@section Direct block chaining - -After each translated basic block is executed, QEMU uses the simulated -Program Counter (PC) and other cpu state informations (such as the CS -segment base value) to find the next basic block. - -In order to accelerate the most common cases where the new simulated PC -is known, QEMU can patch a basic block so that it jumps directly to the -next one. - -The most portable code uses an indirect jump. An indirect jump makes -it easier to make the jump target modification atomic. On some host -architectures (such as x86 or PowerPC), the @code{JUMP} opcode is -directly patched so that the block chaining has no overhead. - -@section Self-modifying code and translated code invalidation - -Self-modifying code is a special challenge in x86 emulation because no -instruction cache invalidation is signaled by the application when code -is modified. - -When translated code is generated for a basic block, the corresponding -host page is write protected if it is not already read-only (with the -system call @code{mprotect()}). Then, if a write access is done to the -page, Linux raises a SEGV signal. QEMU then invalidates all the -translated code in the page and enables write accesses to the page. - -Correct translated code invalidation is done efficiently by maintaining -a linked list of every translated block contained in a given page. Other -linked lists are also maintained to undo direct block chaining. - -Although the overhead of doing @code{mprotect()} calls is important, -most MSDOS programs can be emulated at reasonnable speed with QEMU and -DOSEMU. - -Note that QEMU also invalidates pages of translated code when it detects -that memory mappings are modified with @code{mmap()} or @code{munmap()}. - -When using a software MMU, the code invalidation is more efficient: if -a given code page is invalidated too often because of write accesses, -then a bitmap representing all the code inside the page is -built. Every store into that page checks the bitmap to see if the code -really needs to be invalidated. It avoids invalidating the code when -only data is modified in the page. - -@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. The exact CPU state can be retrieved because all the -x86 registers are stored in fixed host registers. The simulated program -counter is found by retranslating the corresponding basic block and by -looking where the host program counter was at the exception point. - -The virtual CPU cannot retrieve the exact @code{EFLAGS} register because -in some cases it is not computed because of condition code -optimisations. It is not a big concern because the emulated code can -still be restarted in any cases. - -@section MMU emulation - -For system emulation, QEMU uses the mmap() system call to emulate the -target CPU MMU. It works as long the emulated OS does not use an area -reserved by the host OS (such as the area above 0xc0000000 on x86 -Linux). - -In order to be able to launch any OS, QEMU also supports a soft -MMU. In that mode, the MMU virtual to physical address translation is -done at every memory access. QEMU uses an address translation cache to -speed up the translation. - -In order to avoid flushing the translated code each time the MMU -mappings change, QEMU uses a physically indexed translation cache. It -means that each basic block is indexed with its physical address. - -When MMU mappings change, only the chaining of the basic blocks is -reset (i.e. a basic block can no longer jump directly to another one). - -@section Hardware interrupts - -In order to be faster, QEMU does not check at every basic block if an -hardware interrupt is pending. Instead, the user must asynchrously -call a specific function to tell that an interrupt is pending. This -function resets the chaining of the currently executing basic -block. It ensures that the execution will return soon in the main loop -of the CPU emulator. Then the main loop can test if the interrupt is -pending and handle it. - -@section User emulation specific details - -@subsection 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}). - -QEMU supports host CPUs which have pages bigger than 4KB. It records all -the mappings the process does and try to emulated the @code{mmap()} -system calls in cases where the host @code{mmap()} call would fail -because of bad page alignment. - -@subsection 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}). - -@subsection 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. - -Note that currently there are still some locking issues in QEMU. In -particular, the translated cache flush is not protected yet against -reentrancy. - -@subsection Self-virtualization - -QEMU was conceived so that ultimately it can emulate itself. Although -it is not very useful, it is an important test to show the power of the -emulator. - -Achieving self-virtualization is not easy because there may be address -space conflicts. QEMU solves this problem by being an executable ELF -shared object as the ld-linux.so ELF interpreter. That way, it can be -relocated at load time. - -@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. - -@item [6] -@url{http://www.willows.com/}, Windows API library emulation from -Willows Software. - -@item [7] -@url{http://user-mode-linux.sourceforge.net/}, -The User-mode Linux Kernel. - -@item [8] -@url{http://www.plex86.org/}, -The new Plex86 project. - -@item [9] -@url{http://www.vmware.com/}, -The VMWare PC virtualizer. - -@item [10] -@url{http://www.microsoft.com/windowsxp/virtualpc/}, -The VirtualPC PC virtualizer. - -@item [11] -@url{http://www.twoostwo.org/}, -The TwoOStwo PC virtualizer. - -@end table - -@chapter Regression Tests - -In the directory @file{tests/}, various interesting testing programs -are available. There are used for regression testing. - -@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. - -The Linux system call @code{vm86()} is used to test vm86 emulation. - -Various exceptions are raised to test most of the x86 user space -exception reporting. - -@section @file{linux-test} - -This program tests various Linux system calls. It is used to verify -that the system call parameters are correctly converted between target -and host CPUs. - -@section @file{qruncom.c} - -Example of usage of @code{libqemu} to emulate a user mode i386 CPU. diff --git a/tools/ioemu/qemu.1 b/tools/ioemu/qemu.1 deleted file mode 100644 index ddf0c2b651..0000000000 --- a/tools/ioemu/qemu.1 +++ /dev/null @@ -1,457 +0,0 @@ -.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.14 -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sh \" Subsection heading -.br -.if t .Sp -.ne 5 -.PP -\fB\\$1\fR -.PP -.. -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. | will give a -.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to -.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' -.\" expand to `' in nroff, nothing in troff, for use with C<>. -.tr \(*W-|\(bv\*(Tr -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.if \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.\" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.hy 0 -.if n .na -.\" -.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). -.\" Fear. Run. Save yourself. No user-serviceable parts. -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds / -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -.\} -.rm #[ #] #H #V #F C -.\" ======================================================================== -.\" -.IX Title "QEMU 1" -.TH QEMU 1 "2005-05-19" " " " " -.SH "NAME" -qemu \- QEMU System Emulator -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -usage: qemu [options] [disk_image] -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -The \s-1QEMU\s0 System emulator simulates a complete \s-1PC\s0. -.PP -In order to meet specific user needs, two versions of \s-1QEMU\s0 are -available: -.IP "1." 4 -\&\f(CW\*(C`qemu\-fast\*(C'\fR uses the host Memory Management Unit (\s-1MMU\s0) to -simulate the x86 \s-1MMU\s0. It is \fIfast\fR but has limitations because -the whole 4 \s-1GB\s0 address space cannot be used and some memory mapped -peripherials cannot be emulated accurately yet. Therefore, a specific -guest Linux kernel can be used -.Sp -Moreover there is no separation between the host and target address -spaces, so it offers no security (the target \s-1OS\s0 can modify the -\&\f(CW\*(C`qemu\-fast\*(C'\fR code by writing at the right addresses). -.IP "2." 4 -\&\f(CW\*(C`qemu\*(C'\fR uses a software \s-1MMU\s0. It is about \fItwo times slower\fR -but gives a more accurate emulation and a complete separation between -the host and target address spaces. -.PP -\&\s-1QEMU\s0 emulates the following \s-1PC\s0 peripherials: -.IP "\-" 4 -i440FX host \s-1PCI\s0 bridge and \s-1PIIX3\s0 \s-1PCI\s0 to \s-1ISA\s0 bridge -.IP "\-" 4 -Cirrus \s-1CLGD\s0 5446 \s-1PCI\s0 \s-1VGA\s0 card or dummy \s-1VGA\s0 card with Bochs \s-1VESA\s0 -extensions (hardware level, including all non standard modes). -.IP "\-" 4 -\&\s-1PS/2\s0 mouse and keyboard -.IP "\-" 4 -2 \s-1PCI\s0 \s-1IDE\s0 interfaces with hard disk and CD-ROM support -.IP "\-" 4 -Floppy disk -.IP "\-" 4 -\&\s-1NE2000\s0 \s-1PCI\s0 network adapters -.IP "\-" 4 -Serial ports -.IP "\-" 4 -Soundblaster 16 card -.PP -\&\s-1QEMU\s0 uses the \s-1PC\s0 \s-1BIOS\s0 from the Bochs project and the Plex86/Bochs \s-1LGPL\s0 -\&\s-1VGA\s0 \s-1BIOS\s0. -.SH "OPTIONS" -.IX Header "OPTIONS" -\&\fIdisk_image\fR is a raw hard disk image for \s-1IDE\s0 hard disk 0. -.PP -General options: -.IP "\fB\-fda file\fR" 4 -.IX Item "-fda file" -.PD 0 -.IP "\fB\-fdb file\fR" 4 -.IX Item "-fdb file" -.PD -Use \fIfile\fR as floppy disk 0/1 image You can -use the host floppy by using \fI/dev/fd0\fR as filename. -.IP "\fB\-hda file\fR" 4 -.IX Item "-hda file" -.PD 0 -.IP "\fB\-hdb file\fR" 4 -.IX Item "-hdb file" -.IP "\fB\-hdc file\fR" 4 -.IX Item "-hdc file" -.IP "\fB\-hdd file\fR" 4 -.IX Item "-hdd file" -.PD -Use \fIfile\fR as hard disk 0, 1, 2 or 3 image -.IP "\fB\-cdrom file\fR" 4 -.IX Item "-cdrom file" -Use \fIfile\fR as CD-ROM image (you cannot use \fB\-hdc\fR and and -\&\fB\-cdrom\fR at the same time). You can use the host CD-ROM by -using \fI/dev/cdrom\fR as filename. -.IP "\fB\-boot [a|c|d]\fR" 4 -.IX Item "-boot [a|c|d]" -Boot on floppy (a), hard disk (c) or CD-ROM (d). Hard disk boot is -the default. -.IP "\fB\-snapshot\fR" 4 -.IX Item "-snapshot" -Write to temporary files instead of disk image files. In this case, -the raw disk image you use is not written back. You can however force -the write back by pressing \fBC\-a s\fR -.IP "\fB\-m megs\fR" 4 -.IX Item "-m megs" -Set virtual \s-1RAM\s0 size to \fImegs\fR megabytes. Default is 128 \s-1MB\s0. -.IP "\fB\-nographic\fR" 4 -.IX Item "-nographic" -Normally, \s-1QEMU\s0 uses \s-1SDL\s0 to display the \s-1VGA\s0 output. With this option, -you can totally disable graphical output so that \s-1QEMU\s0 is a simple -command line application. The emulated serial port is redirected on -the console. Therefore, you can still use \s-1QEMU\s0 to debug a Linux kernel -with a serial console. -.IP "\fB\-enable\-audio\fR" 4 -.IX Item "-enable-audio" -The \s-1SB16\s0 emulation is disabled by default as it may give problems with -Windows. You can enable it manually with this option. -.IP "\fB\-localtime\fR" 4 -.IX Item "-localtime" -Set the real time clock to local time (the default is to \s-1UTC\s0 -time). This option is needed to have correct date in MS-DOS or -Windows. -.IP "\fB\-full\-screen\fR" 4 -.IX Item "-full-screen" -Start in full screen. -.PP -Network options: -.IP "\fB\-n script\fR" 4 -.IX Item "-n script" -Set \s-1TUN/TAP\s0 network init script [default=/etc/qemu\-ifup]. This script -is launched to configure the host network interface (usually tun0) -corresponding to the virtual \s-1NE2000\s0 card. -.IP "\fB\-macaddr addr\fR" 4 -.IX Item "-macaddr addr" -Set the mac address of the first interface (the format is -aa:bb:cc:dd:ee:ff in hexa). The mac address is incremented for each -new network interface. -.IP "\fB\-tun\-fd fd\fR" 4 -.IX Item "-tun-fd fd" -Assumes \fIfd\fR talks to a tap/tun host network interface and use -it. Read <\fBhttp://bellard.org/qemu/tetrinet.html\fR> to have an -example of its use. -.IP "\fB\-user\-net\fR" 4 -.IX Item "-user-net" -Use the user mode network stack. This is the default if no tun/tap -network init script is found. -.IP "\fB\-tftp prefix\fR" 4 -.IX Item "-tftp prefix" -When using the user mode network stack, activate a built-in \s-1TFTP\s0 -server. All filenames beginning with \fIprefix\fR can be downloaded -from the host to the guest using a \s-1TFTP\s0 client. The \s-1TFTP\s0 client on the -guest must be configured in binary mode (use the command \f(CW\*(C`bin\*(C'\fR of -the Unix \s-1TFTP\s0 client). The host \s-1IP\s0 address on the guest is as usual -10.0.2.2. -.IP "\fB\-smb dir\fR" 4 -.IX Item "-smb dir" -When using the user mode network stack, activate a built-in \s-1SMB\s0 -server so that Windows OSes can access to the host files in \fIdir\fR -transparently. -.Sp -In the guest Windows \s-1OS\s0, the line: -.Sp -.Vb 1 -\& 10.0.2.4 smbserver -.Ve -.Sp -must be added in the file \fIC:\eWINDOWS\eLMHOSTS\fR (for windows 9x/Me) -or \fIC:\eWINNT\eSYSTEM32\eDRIVERS\eETC\eLMHOSTS\fR (Windows \s-1NT/2000\s0). -.Sp -Then \fIdir\fR can be accessed in \fI\e\esmbserver\eqemu\fR. -.Sp -Note that a \s-1SAMBA\s0 server must be installed on the host \s-1OS\s0 in -\&\fI/usr/sbin/smbd\fR. \s-1QEMU\s0 was tested succesfully with smbd version -2.2.7a from the Red Hat 9. -.IP "\fB\-redir [tcp|udp]:host\-port:[guest\-host]:guest\-port\fR" 4 -.IX Item "-redir [tcp|udp]:host-port:[guest-host]:guest-port" -When using the user mode network stack, redirect incoming \s-1TCP\s0 or \s-1UDP\s0 -connections to the host port \fIhost-port\fR to the guest -\&\fIguest-host\fR on guest port \fIguest-port\fR. If \fIguest-host\fR -is not specified, its value is 10.0.2.15 (default address given by the -built-in \s-1DHCP\s0 server). -.Sp -For example, to redirect host X11 connection from screen 1 to guest -screen 0, use the following: -.Sp -.Vb 4 -\& # on the host -\& qemu -redir tcp:6001::6000 [...] -\& # this host xterm should open in the guest X11 server -\& xterm -display :1 -.Ve -.Sp -To redirect telnet connections from host port 5555 to telnet port on -the guest, use the following: -.Sp -.Vb 3 -\& # on the host -\& qemu -redir tcp:5555::23 [...] -\& telnet localhost 5555 -.Ve -.Sp -Then when you use on the host \f(CW\*(C`telnet localhost 5555\*(C'\fR, you -connect to the guest telnet server. -.IP "\fB\-dummy\-net\fR" 4 -.IX Item "-dummy-net" -Use the dummy network stack: no packet will be received by the network -cards. -.PP -Linux boot specific. When using this options, you can use a given -Linux kernel without installing it in the disk image. It can be useful -for easier testing of various kernels. -.IP "\fB\-kernel bzImage\fR" 4 -.IX Item "-kernel bzImage" -Use \fIbzImage\fR as kernel image. -.IP "\fB\-append cmdline\fR" 4 -.IX Item "-append cmdline" -Use \fIcmdline\fR as kernel command line -.IP "\fB\-initrd file\fR" 4 -.IX Item "-initrd file" -Use \fIfile\fR as initial ram disk. -.PP -Debug/Expert options: -.IP "\fB\-serial dev\fR" 4 -.IX Item "-serial dev" -Redirect the virtual serial port to host device \fIdev\fR. Available -devices are: -.RS 4 -.ie n .IP """vc""" 4 -.el .IP "\f(CWvc\fR" 4 -.IX Item "vc" -Virtual console -.ie n .IP """pty""" 4 -.el .IP "\f(CWpty\fR" 4 -.IX Item "pty" -[Linux only] Pseudo \s-1TTY\s0 (a new \s-1PTY\s0 is automatically allocated) -.ie n .IP """null""" 4 -.el .IP "\f(CWnull\fR" 4 -.IX Item "null" -void device -.ie n .IP """stdio""" 4 -.el .IP "\f(CWstdio\fR" 4 -.IX Item "stdio" -[Unix only] standard input/output -.RE -.RS 4 -.Sp -The default device is \f(CW\*(C`vc\*(C'\fR in graphical mode and \f(CW\*(C`stdio\*(C'\fR in -non graphical mode. -.Sp -This option can be used several times to simulate up to 4 serials -ports. -.RE -.IP "\fB\-monitor dev\fR" 4 -.IX Item "-monitor dev" -Redirect the monitor to host device \fIdev\fR (same devices as the -serial port). -The default device is \f(CW\*(C`vc\*(C'\fR in graphical mode and \f(CW\*(C`stdio\*(C'\fR in -non graphical mode. -.IP "\fB\-s\fR" 4 -.IX Item "-s" -Wait gdb connection to port 1234 -.IP "\fB\-p port\fR" 4 -.IX Item "-p port" -Change gdb connection port. -.IP "\fB\-S\fR" 4 -.IX Item "-S" -Do not start \s-1CPU\s0 at startup (you must type 'c' in the monitor). -.IP "\fB\-d\fR" 4 -.IX Item "-d" -Output log in /tmp/qemu.log -.IP "\fB\-isa\fR" 4 -.IX Item "-isa" -Simulate an ISA-only system (default is \s-1PCI\s0 system). -.IP "\fB\-std\-vga\fR" 4 -.IX Item "-std-vga" -Simulate a standard \s-1VGA\s0 card with Bochs \s-1VBE\s0 extensions (default is -Cirrus Logic \s-1GD5446\s0 \s-1PCI\s0 \s-1VGA\s0) -.IP "\fB\-loadvm file\fR" 4 -.IX Item "-loadvm file" -Start right away with a saved state (\f(CW\*(C`loadvm\*(C'\fR in monitor) -.PP -During the graphical emulation, you can use the following keys: -.IP "\fBCtrl-Alt-f\fR" 4 -.IX Item "Ctrl-Alt-f" -Toggle full screen -.IP "\fBCtrl-Alt-n\fR" 4 -.IX Item "Ctrl-Alt-n" -Switch to virtual console 'n'. Standard console mappings are: -.RS 4 -.IP "\fI1\fR" 4 -.IX Item "1" -Target system display -.IP "\fI2\fR" 4 -.IX Item "2" -Monitor -.IP "\fI3\fR" 4 -.IX Item "3" -Serial port -.RE -.RS 4 -.RE -.IP "\fBCtrl-Alt\fR" 4 -.IX Item "Ctrl-Alt" -Toggle mouse and keyboard grab. -.PP -In the virtual consoles, you can use \fBCtrl-Up\fR, \fBCtrl-Down\fR, -\&\fBCtrl-PageUp\fR and \fBCtrl-PageDown\fR to move in the back log. -.PP -During emulation, if you are using the \fB\-nographic\fR option, use -\&\fBCtrl-a h\fR to get terminal commands: -.IP "\fBCtrl-a h\fR" 4 -.IX Item "Ctrl-a h" -Print this help -.IP "\fBCtrl-a x\fR" 4 -.IX Item "Ctrl-a x" -Exit emulatior -.IP "\fBCtrl-a s\fR" 4 -.IX Item "Ctrl-a s" -Save disk data back to file (if \-snapshot) -.IP "\fBCtrl-a b\fR" 4 -.IX Item "Ctrl-a b" -Send break (magic sysrq in Linux) -.IP "\fBCtrl-a c\fR" 4 -.IX Item "Ctrl-a c" -Switch between console and monitor -.IP "\fBCtrl-a Ctrl-a\fR" 4 -.IX Item "Ctrl-a Ctrl-a" -Send Ctrl-a -.PP -The following options are specific to the PowerPC emulation: -.IP "\fB\-prep\fR" 4 -.IX Item "-prep" -Simulate a \s-1PREP\s0 system (default is PowerMAC) -.IP "\fB\-g WxH[xDEPTH]\fR" 4 -.IX Item "-g WxH[xDEPTH]" -Set the initial \s-1VGA\s0 graphic mode. The default is 800x600x15. -.SH "SEE ALSO" -.IX Header "SEE ALSO" -The \s-1HTML\s0 documentation of \s-1QEMU\s0 for more precise information and Linux -user mode emulator invocation. -.SH "AUTHOR" -.IX Header "AUTHOR" -Fabrice Bellard diff --git a/tools/ioemu/Makefile.target b/tools/ioemu/target-i386-dm/Makefile index 933e6246a9..933e6246a9 100644 --- a/tools/ioemu/Makefile.target +++ b/tools/ioemu/target-i386-dm/Makefile diff --git a/tools/ioemu/tests/Makefile b/tools/ioemu/tests/Makefile deleted file mode 100644 index c0ee7b2a03..0000000000 --- a/tools/ioemu/tests/Makefile +++ /dev/null @@ -1,84 +0,0 @@ --include ../config-host.mak - -CFLAGS=-Wall -O2 -g -LDFLAGS= - -ifeq ($(ARCH),i386) -TESTS=linux-test testthread sha1-i386 test-i386 runcom -endif -TESTS+=sha1# test_path -#TESTS+=test_path - -QEMU=../i386-user/qemu-i386 - -all: $(TESTS) - -hello-i386: hello-i386.c - $(CC) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $< - strip $@ - -testthread: testthread.c - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lpthread - -test_path: test_path.c - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< - ./$@ || { rm $@; exit 1; } - -# i386 emulation test (test various opcodes) */ -test-i386: test-i386.c test-i386-code16.S test-i386-vm86.S \ - test-i386.h test-i386-shift.h test-i386-muldiv.h - $(CC) $(CFLAGS) $(LDFLAGS) -static -o $@ test-i386.c \ - test-i386-code16.S test-i386-vm86.S -lm - -ifeq ($(ARCH),i386) -test: test-i386 - ./test-i386 > test-i386.ref -else -test: -endif - $(QEMU) test-i386 > test-i386.out - @if diff -u test-i386.ref test-i386.out ; then echo "Auto Test OK"; fi -ifeq ($(ARCH),i386) - $(QEMU) -no-code-copy test-i386 > test-i386.out - @if diff -u test-i386.ref test-i386.out ; then echo "Auto Test OK (no code copy)"; fi -endif - -# generic Linux and CPU test -linux-test: linux-test.c - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lm - -# speed test -sha1-i386: sha1.c - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< - -sha1: sha1.c - $(HOST_CC) $(CFLAGS) $(LDFLAGS) -o $@ $< - -speed: sha1 sha1-i386 - time ./sha1 - time $(QEMU) ./sha1-i386 - -# vm86 test -runcom: runcom.c - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< - -# NOTE: -fomit-frame-pointer is currently needed : this is a bug in libqemu -qruncom: qruncom.c ../i386-user/libqemu.a - $(CC) $(CFLAGS) -fomit-frame-pointer $(LDFLAGS) -I../target-i386 -I.. -I../i386-user \ - -o $@ $< -L../i386-user -lqemu -lm - -# arm test -hello-arm: hello-arm.o - arm-linux-ld -o $@ $< - -hello-arm.o: hello-arm.c - arm-linux-gcc -Wall -g -O2 -c -o $@ $< - -# XXX: find a way to compile easily a test for each arch -test2: - @for arch in i386 arm sparc ppc; do \ - ../$${arch}-user/qemu-$${arch} $${arch}/ls -l linux-test.c ; \ - done - -clean: - rm -f *~ *.o test-i386.out test-i386.ref qruncom $(TESTS) diff --git a/tools/ioemu/tests/hello-arm.c b/tools/ioemu/tests/hello-arm.c deleted file mode 100644 index f84e6cb368..0000000000 --- a/tools/ioemu/tests/hello-arm.c +++ /dev/null @@ -1,113 +0,0 @@ -#define __NR_SYSCALL_BASE 0x900000 -#define __NR_exit1 (__NR_SYSCALL_BASE+ 1) -#define __NR_write (__NR_SYSCALL_BASE+ 4) - -#define __sys2(x) #x -#define __sys1(x) __sys2(x) - -#ifndef __syscall -#define __syscall(name) "swi\t" __sys1(__NR_##name) "\n\t" -#endif - -#define __syscall_return(type, res) \ -do { \ - return (type) (res); \ -} while (0) - -#define _syscall0(type,name) \ -type name(void) { \ - long __res; \ - __asm__ __volatile__ ( \ - __syscall(name) \ - "mov %0,r0" \ - :"=r" (__res) : : "r0","lr"); \ - __syscall_return(type,__res); \ -} - -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) { \ - long __res; \ - __asm__ __volatile__ ( \ - "mov\tr0,%1\n\t" \ - __syscall(name) \ - "mov %0,r0" \ - : "=r" (__res) \ - : "r" ((long)(arg1)) \ - : "r0","lr"); \ - __syscall_return(type,__res); \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1,type2 arg2) { \ - long __res; \ - __asm__ __volatile__ ( \ - "mov\tr0,%1\n\t" \ - "mov\tr1,%2\n\t" \ - __syscall(name) \ - "mov\t%0,r0" \ - : "=r" (__res) \ - : "r" ((long)(arg1)),"r" ((long)(arg2)) \ - : "r0","r1","lr"); \ - __syscall_return(type,__res); \ -} - - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1,type2 arg2,type3 arg3) { \ - long __res; \ - __asm__ __volatile__ ( \ - "mov\tr0,%1\n\t" \ - "mov\tr1,%2\n\t" \ - "mov\tr2,%3\n\t" \ - __syscall(name) \ - "mov\t%0,r0" \ - : "=r" (__res) \ - : "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)) \ - : "r0","r1","r2","lr"); \ - __syscall_return(type,__res); \ -} - - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ - long __res; \ - __asm__ __volatile__ ( \ - "mov\tr0,%1\n\t" \ - "mov\tr1,%2\n\t" \ - "mov\tr2,%3\n\t" \ - "mov\tr3,%4\n\t" \ - __syscall(name) \ - "mov\t%0,r0" \ - : "=r" (__res) \ - : "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)),"r" ((long)(arg4)) \ - : "r0","r1","r2","r3","lr"); \ - __syscall_return(type,__res); \ -} - - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \ - long __res; \ - __asm__ __volatile__ ( \ - "mov\tr0,%1\n\t" \ - "mov\tr1,%2\n\t" \ - "mov\tr2,%3\n\t" \ - "mov\tr3,%4\n\t" \ - "mov\tr4,%5\n\t" \ - __syscall(name) \ - "mov\t%0,r0" \ - : "=r" (__res) \ - : "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)),"r" ((long)(arg4)), \ - "r" ((long)(arg5)) \ - : "r0","r1","r2","r3","r4","lr"); \ - __syscall_return(type,__res); \ -} - -_syscall1(int,exit1,int,status); -_syscall3(int,write,int,fd,const char *,buf, int, len); - -void _start(void) -{ - write(1, "Hello World\n", 12); - exit1(0); -} diff --git a/tools/ioemu/tests/hello-i386.c b/tools/ioemu/tests/hello-i386.c deleted file mode 100644 index e00245d3fe..0000000000 --- a/tools/ioemu/tests/hello-i386.c +++ /dev/null @@ -1,26 +0,0 @@ -#include <asm/unistd.h> - -extern inline volatile void exit(int status) -{ - int __res; - __asm__ volatile ("movl %%ecx,%%ebx\n"\ - "int $0x80" \ - : "=a" (__res) : "0" (__NR_exit),"c" ((long)(status))); -} - -extern inline int write(int fd, const char * buf, int len) -{ - int status; - __asm__ volatile ("pushl %%ebx\n"\ - "movl %%esi,%%ebx\n"\ - "int $0x80\n" \ - "popl %%ebx\n"\ - : "=a" (status) \ - : "0" (__NR_write),"S" ((long)(fd)),"c" ((long)(buf)),"d" ((long)(len))); -} - -void _start(void) -{ - write(1, "Hello World\n", 12); - exit(0); -} diff --git a/tools/ioemu/tests/linux-test.c b/tools/ioemu/tests/linux-test.c deleted file mode 100644 index 6ca9029650..0000000000 --- a/tools/ioemu/tests/linux-test.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - * linux and CPU test - * - * Copyright (c) 2003 Fabrice Bellard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include <stdarg.h> -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <fcntl.h> -#include <inttypes.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <errno.h> -#include <utime.h> -#include <time.h> -#include <sys/time.h> -#include <sys/uio.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sched.h> -#include <dirent.h> -#include <setjmp.h> -#include <sys/shm.h> - -#define TESTPATH "/tmp/linux-test.tmp" -#define TESTPORT 7654 -#define STACK_SIZE 16384 - -void error1(const char *filename, int line, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - fprintf(stderr, "%s:%d: ", filename, line); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - exit(1); -} - -int __chk_error(const char *filename, int line, int ret) -{ - if (ret < 0) { - error1(filename, line, "%m (ret=%d, errno=%d)", - ret, errno); - } - return ret; -} - -#define error(fmt, args...) error1(__FILE__, __LINE__, fmt, ##args) - -#define chk_error(ret) __chk_error(__FILE__, __LINE__, (ret)) - -/*******************************************************/ - -#define FILE_BUF_SIZE 300 - -void test_file(void) -{ - int fd, i, len, ret; - uint8_t buf[FILE_BUF_SIZE]; - uint8_t buf2[FILE_BUF_SIZE]; - uint8_t buf3[FILE_BUF_SIZE]; - char cur_dir[1024]; - struct stat st; - struct utimbuf tbuf; - struct iovec vecs[2]; - DIR *dir; - struct dirent *de; - - /* clean up, just in case */ - unlink(TESTPATH "/file1"); - unlink(TESTPATH "/file2"); - unlink(TESTPATH "/file3"); - rmdir(TESTPATH); - - if (getcwd(cur_dir, sizeof(cur_dir)) == NULL) - error("getcwd"); - - chk_error(mkdir(TESTPATH, 0755)); - - chk_error(chdir(TESTPATH)); - - /* open/read/write/close/readv/writev/lseek */ - - fd = chk_error(open("file1", O_WRONLY | O_TRUNC | O_CREAT, 0644)); - for(i=0;i < FILE_BUF_SIZE; i++) - buf[i] = i; - len = chk_error(write(fd, buf, FILE_BUF_SIZE / 2)); - if (len != (FILE_BUF_SIZE / 2)) - error("write"); - vecs[0].iov_base = buf + (FILE_BUF_SIZE / 2); - vecs[0].iov_len = 16; - vecs[1].iov_base = buf + (FILE_BUF_SIZE / 2) + 16; - vecs[1].iov_len = (FILE_BUF_SIZE / 2) - 16; - len = chk_error(writev(fd, vecs, 2)); - if (len != (FILE_BUF_SIZE / 2)) - error("writev"); - chk_error(close(fd)); - - chk_error(rename("file1", "file2")); - - fd = chk_error(open("file2", O_RDONLY)); - - len = chk_error(read(fd, buf2, FILE_BUF_SIZE)); - if (len != FILE_BUF_SIZE) - error("read"); - if (memcmp(buf, buf2, FILE_BUF_SIZE) != 0) - error("memcmp"); - -#define FOFFSET 16 - ret = chk_error(lseek(fd, FOFFSET, SEEK_SET)); - if (ret != 16) - error("lseek"); - vecs[0].iov_base = buf3; - vecs[0].iov_len = 32; - vecs[1].iov_base = buf3 + 32; - vecs[1].iov_len = FILE_BUF_SIZE - FOFFSET - 32; - len = chk_error(readv(fd, vecs, 2)); - if (len != FILE_BUF_SIZE - FOFFSET) - error("readv"); - if (memcmp(buf + FOFFSET, buf3, FILE_BUF_SIZE - FOFFSET) != 0) - error("memcmp"); - - chk_error(close(fd)); - - /* access */ - chk_error(access("file2", R_OK)); - - /* stat/chmod/utime/truncate */ - - chk_error(chmod("file2", 0600)); - tbuf.actime = 1001; - tbuf.modtime = 1000; - chk_error(truncate("file2", 100)); - chk_error(utime("file2", &tbuf)); - chk_error(stat("file2", &st)); - if (st.st_size != 100) - error("stat size"); - if (!S_ISREG(st.st_mode)) - error("stat mode"); - if ((st.st_mode & 0777) != 0600) - error("stat mode2"); - if (st.st_atime != 1001 || - st.st_mtime != 1000) - error("stat time"); - - chk_error(stat(TESTPATH, &st)); - if (!S_ISDIR(st.st_mode)) - error("stat mode"); - - /* fstat */ - fd = chk_error(open("file2", O_RDWR)); - chk_error(ftruncate(fd, 50)); - chk_error(fstat(fd, &st)); - chk_error(close(fd)); - - if (st.st_size != 50) - error("stat size"); - if (!S_ISREG(st.st_mode)) - error("stat mode"); - - /* symlink/lstat */ - chk_error(symlink("file2", "file3")); - chk_error(lstat("file3", &st)); - if (!S_ISLNK(st.st_mode)) - error("stat mode"); - - /* getdents */ - dir = opendir(TESTPATH); - if (!dir) - error("opendir"); - len = 0; - for(;;) { - de = readdir(dir); - if (!de) - break; - if (strcmp(de->d_name, ".") != 0 && - strcmp(de->d_name, "..") != 0 && - strcmp(de->d_name, "file2") != 0 && - strcmp(de->d_name, "file3") != 0) - error("readdir"); - len++; - } - closedir(dir); - if (len != 4) - error("readdir"); - - chk_error(unlink("file3")); - chk_error(unlink("file2")); - chk_error(chdir(cur_dir)); - chk_error(rmdir(TESTPATH)); -} - -void test_fork(void) -{ - int pid, status; - - pid = chk_error(fork()); - if (pid == 0) { - /* child */ - exit(2); - } - chk_error(waitpid(pid, &status, 0)); - if (!WIFEXITED(status) || WEXITSTATUS(status) != 2) - error("waitpid status=0x%x", status); -} - -void test_time(void) -{ - struct timeval tv, tv2; - struct timespec ts, rem; - struct rusage rusg1, rusg2; - int ti, i; - - chk_error(gettimeofday(&tv, NULL)); - rem.tv_sec = 1; - ts.tv_sec = 0; - ts.tv_nsec = 20 * 1000000; - chk_error(nanosleep(&ts, &rem)); - if (rem.tv_sec != 1) - error("nanosleep"); - chk_error(gettimeofday(&tv2, NULL)); - ti = tv2.tv_sec - tv.tv_sec; - if (ti >= 2) - error("gettimeofday"); - - chk_error(getrusage(RUSAGE_SELF, &rusg1)); - for(i = 0;i < 10000; i++); - chk_error(getrusage(RUSAGE_SELF, &rusg2)); - if ((rusg2.ru_utime.tv_sec - rusg1.ru_utime.tv_sec) < 0 || - (rusg2.ru_stime.tv_sec - rusg1.ru_stime.tv_sec) < 0) - error("getrusage"); -} - -void pstrcpy(char *buf, int buf_size, const char *str) -{ - int c; - char *q = buf; - - if (buf_size <= 0) - return; - - for(;;) { - c = *str++; - if (c == 0 || q >= buf + buf_size - 1) - break; - *q++ = c; - } - *q = '\0'; -} - -/* strcat and truncate. */ -char *pstrcat(char *buf, int buf_size, const char *s) -{ - int len; - len = strlen(buf); - if (len < buf_size) - pstrcpy(buf + len, buf_size - len, s); - return buf; -} - -int server_socket(void) -{ - int val, fd; - struct sockaddr_in sockaddr; - - /* server socket */ - fd = chk_error(socket(PF_INET, SOCK_STREAM, 0)); - - val = 1; - chk_error(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))); - - sockaddr.sin_family = AF_INET; - sockaddr.sin_port = htons(TESTPORT); - sockaddr.sin_addr.s_addr = 0; - chk_error(bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))); - chk_error(listen(fd, 0)); - return fd; - -} - -int client_socket(void) -{ - int fd; - struct sockaddr_in sockaddr; - - /* server socket */ - fd = chk_error(socket(PF_INET, SOCK_STREAM, 0)); - sockaddr.sin_family = AF_INET; - sockaddr.sin_port = htons(TESTPORT); - inet_aton("127.0.0.1", &sockaddr.sin_addr); - chk_error(connect(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))); - return fd; -} - -const char socket_msg[] = "hello socket\n"; - -void test_socket(void) -{ - int server_fd, client_fd, fd, pid, ret, val; - struct sockaddr_in sockaddr; - socklen_t len; - char buf[512]; - - server_fd = server_socket(); - - /* test a few socket options */ - len = sizeof(val); - chk_error(getsockopt(server_fd, SOL_SOCKET, SO_TYPE, &val, &len)); - if (val != SOCK_STREAM) - error("getsockopt"); - - pid = chk_error(fork()); - if (pid == 0) { - client_fd = client_socket(); - send(client_fd, socket_msg, sizeof(socket_msg), 0); - close(client_fd); - exit(0); - } - len = sizeof(sockaddr); - fd = chk_error(accept(server_fd, (struct sockaddr *)&sockaddr, &len)); - - ret = chk_error(recv(fd, buf, sizeof(buf), 0)); - if (ret != sizeof(socket_msg)) - error("recv"); - if (memcmp(buf, socket_msg, sizeof(socket_msg)) != 0) - error("socket_msg"); - chk_error(close(fd)); - chk_error(close(server_fd)); -} - -#define WCOUNT_MAX 512 - -void test_pipe(void) -{ - fd_set rfds, wfds; - int fds[2], fd_max, ret; - uint8_t ch; - int wcount, rcount; - - chk_error(pipe(fds)); - chk_error(fcntl(fds[0], F_SETFL, O_NONBLOCK)); - chk_error(fcntl(fds[1], F_SETFL, O_NONBLOCK)); - wcount = 0; - rcount = 0; - for(;;) { - FD_ZERO(&rfds); - fd_max = fds[0]; - FD_SET(fds[0], &rfds); - - FD_ZERO(&wfds); - FD_SET(fds[1], &wfds); - if (fds[1] > fd_max) - fd_max = fds[1]; - - ret = chk_error(select(fd_max + 1, &rfds, &wfds, NULL, NULL)); - if (ret > 0) { - if (FD_ISSET(fds[0], &rfds)) { - chk_error(read(fds[0], &ch, 1)); - rcount++; - if (rcount >= WCOUNT_MAX) - break; - } - if (FD_ISSET(fds[1], &wfds)) { - ch = 'a'; - chk_error(write(fds[0], &ch, 1)); - wcount++; - } - } - } - chk_error(close(fds[0])); - chk_error(close(fds[1])); -} - -int thread1_res; -int thread2_res; - -int thread1_func(void *arg) -{ - int i; - for(i=0;i<5;i++) { - thread1_res++; - usleep(10 * 1000); - } - return 0; -} - -int thread2_func(void *arg) -{ - int i; - for(i=0;i<6;i++) { - thread2_res++; - usleep(10 * 1000); - } - return 0; -} - -void test_clone(void) -{ - uint8_t *stack1, *stack2; - int pid1, pid2, status1, status2; - - stack1 = malloc(STACK_SIZE); - pid1 = chk_error(clone(thread1_func, stack1 + STACK_SIZE, - CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello1")); - - stack2 = malloc(STACK_SIZE); - pid2 = chk_error(clone(thread2_func, stack2 + STACK_SIZE, - CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello2")); - - while (waitpid(pid1, &status1, 0) != pid1); - while (waitpid(pid2, &status2, 0) != pid2); - if (thread1_res != 5 || - thread2_res != 6) - error("clone"); -} - -/***********************************/ - -volatile int alarm_count; -jmp_buf jmp_env; - -void sig_alarm(int sig) -{ - if (sig != SIGALRM) - error("signal"); - alarm_count++; -} - -void sig_segv(int sig, siginfo_t *info, void *puc) -{ - if (sig != SIGSEGV) - error("signal"); - longjmp(jmp_env, 1); -} - -void test_signal(void) -{ - struct sigaction act; - struct itimerval it, oit; - - /* timer test */ - - alarm_count = 0; - - act.sa_handler = sig_alarm; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - chk_error(sigaction(SIGALRM, &act, NULL)); - - it.it_interval.tv_sec = 0; - it.it_interval.tv_usec = 10 * 1000; - it.it_value.tv_sec = 0; - it.it_value.tv_usec = 10 * 1000; - chk_error(setitimer(ITIMER_REAL, &it, NULL)); - chk_error(getitimer(ITIMER_REAL, &oit)); - if (oit.it_value.tv_sec != it.it_value.tv_sec || - oit.it_value.tv_usec != it.it_value.tv_usec) - error("itimer"); - - while (alarm_count < 5) { - usleep(10 * 1000); - } - - it.it_interval.tv_sec = 0; - it.it_interval.tv_usec = 0; - it.it_value.tv_sec = 0; - it.it_value.tv_usec = 0; - memset(&oit, 0xff, sizeof(oit)); - chk_error(setitimer(ITIMER_REAL, &it, &oit)); - if (oit.it_value.tv_sec != 0 || - oit.it_value.tv_usec != 10 * 1000) - error("setitimer"); - - /* SIGSEGV test */ - act.sa_sigaction = sig_segv; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_SIGINFO; - chk_error(sigaction(SIGSEGV, &act, NULL)); - if (setjmp(jmp_env) == 0) { - *(uint8_t *)0 = 0; - } - - act.sa_handler = SIG_DFL; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - chk_error(sigaction(SIGSEGV, &act, NULL)); -} - -#define SHM_SIZE 32768 - -void test_shm(void) -{ - void *ptr; - int shmid; - - shmid = chk_error(shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0777)); - ptr = shmat(shmid, NULL, 0); - if (!ptr) - error("shmat"); - - memset(ptr, 0, SHM_SIZE); - - chk_error(shmctl(shmid, IPC_RMID, 0)); - chk_error(shmdt(ptr)); -} - -int main(int argc, char **argv) -{ - test_file(); - test_fork(); - test_time(); - test_socket(); - // test_clone(); - test_signal(); - test_shm(); - return 0; -} diff --git a/tools/ioemu/tests/pi_10.com b/tools/ioemu/tests/pi_10.com Binary files differdeleted file mode 100644 index 8993ba1a51..0000000000 --- a/tools/ioemu/tests/pi_10.com +++ /dev/null diff --git a/tools/ioemu/tests/qruncom.c b/tools/ioemu/tests/qruncom.c deleted file mode 100644 index fcc069f6d0..0000000000 --- a/tools/ioemu/tests/qruncom.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Example of use of user mode libqemu: launch a basic .com DOS - * executable - */ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <inttypes.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <signal.h> - -#include "cpu.h" - -//#define SIGTEST - -CPUState *cpu_single_env = NULL; - -void cpu_outb(CPUState *env, int addr, int val) -{ - fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val); -} - -void cpu_outw(CPUState *env, int addr, int val) -{ - fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val); -} - -void cpu_outl(CPUState *env, int addr, int val) -{ - fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val); -} - -int cpu_inb(CPUState *env, int addr) -{ - fprintf(stderr, "inb: port=0x%04x\n", addr); - return 0; -} - -int cpu_inw(CPUState *env, int addr) -{ - fprintf(stderr, "inw: port=0x%04x\n", addr); - return 0; -} - -int cpu_inl(CPUState *env, int addr) -{ - fprintf(stderr, "inl: port=0x%04x\n", addr); - return 0; -} - -int cpu_get_pic_interrupt(CPUState *env) -{ - return -1; -} - -uint64_t cpu_get_tsc(CPUState *env) -{ - return 0; -} - -static void set_gate(void *ptr, unsigned int type, unsigned int dpl, - unsigned long addr, unsigned int sel) -{ - unsigned int e1, e2; - e1 = (addr & 0xffff) | (sel << 16); - e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8); - stl((uint8_t *)ptr, e1); - stl((uint8_t *)ptr + 4, e2); -} - -uint64_t idt_table[256]; - -/* only dpl matters as we do only user space emulation */ -static void set_idt(int n, unsigned int dpl) -{ - set_gate(idt_table + n, 0, dpl, 0, 0); -} - -void qemu_free(void *ptr) -{ - free(ptr); -} - -void *qemu_malloc(size_t size) -{ - return malloc(size); -} - -void qemu_printf(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); -} - -/* XXX: this is a bug in helper2.c */ -int errno; - -/**********************************************/ - -#define COM_BASE_ADDR 0x10100 - -void usage(void) -{ - printf("qruncom version 0.1 (c) 2003 Fabrice Bellard\n" - "usage: qruncom file.com\n" - "user mode libqemu demo: run simple .com DOS executables\n"); - exit(1); -} - -static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg) -{ - return (uint8_t *)((seg << 4) + (reg & 0xffff)); -} - -static inline void pushw(CPUState *env, int val) -{ - env->regs[R_ESP] = (env->regs[R_ESP] & ~0xffff) | ((env->regs[R_ESP] - 2) & 0xffff); - *(uint16_t *)seg_to_linear(env->segs[R_SS].selector, env->regs[R_ESP]) = val; -} - -static void host_segv_handler(int host_signum, siginfo_t *info, - void *puc) -{ - if (cpu_signal_handler(host_signum, info, puc)) { - return; - } - abort(); -} - -int main(int argc, char **argv) -{ - uint8_t *vm86_mem; - const char *filename; - int fd, ret, seg; - CPUState *env; - - if (argc != 2) - usage(); - filename = argv[1]; - - vm86_mem = mmap((void *)0x00000000, 0x110000, - PROT_WRITE | PROT_READ | PROT_EXEC, - MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0); - if (vm86_mem == MAP_FAILED) { - perror("mmap"); - exit(1); - } - - /* load the MSDOS .com executable */ - fd = open(filename, O_RDONLY); - if (fd < 0) { - perror(filename); - exit(1); - } - ret = read(fd, vm86_mem + COM_BASE_ADDR, 65536 - 256); - if (ret < 0) { - perror("read"); - exit(1); - } - close(fd); - - /* install exception handler for CPU emulator */ - { - struct sigaction act; - - sigfillset(&act.sa_mask); - act.sa_flags = SA_SIGINFO; - // act.sa_flags |= SA_ONSTACK; - - act.sa_sigaction = host_segv_handler; - sigaction(SIGSEGV, &act, NULL); - sigaction(SIGBUS, &act, NULL); -#if defined (TARGET_I386) && defined(USE_CODE_COPY) - sigaction(SIGFPE, &act, NULL); -#endif - } - - // cpu_set_log(CPU_LOG_TB_IN_ASM | CPU_LOG_TB_OUT_ASM | CPU_LOG_EXEC); - - env = cpu_init(); - - /* disable code copy to simplify debugging */ - code_copy_enabled = 0; - - /* set user mode state (XXX: should be done automatically by - cpu_init ?) */ - env->user_mode_only = 1; - - cpu_x86_set_cpl(env, 3); - - env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK; - /* NOTE: hflags duplicates some of the virtual CPU state */ - env->hflags |= HF_PE_MASK | VM_MASK; - - /* flags setup : we activate the IRQs by default as in user - mode. We also activate the VM86 flag to run DOS code */ - env->eflags |= IF_MASK | VM_MASK; - - /* init basic registers */ - env->eip = 0x100; - env->regs[R_ESP] = 0xfffe; - seg = (COM_BASE_ADDR - 0x100) >> 4; - - cpu_x86_load_seg_cache(env, R_CS, seg, - (uint8_t *)(seg << 4), 0xffff, 0); - cpu_x86_load_seg_cache(env, R_SS, seg, - (uint8_t *)(seg << 4), 0xffff, 0); - cpu_x86_load_seg_cache(env, R_DS, seg, - (uint8_t *)(seg << 4), 0xffff, 0); - cpu_x86_load_seg_cache(env, R_ES, seg, - (uint8_t *)(seg << 4), 0xffff, 0); - cpu_x86_load_seg_cache(env, R_FS, seg, - (uint8_t *)(seg << 4), 0xffff, 0); - cpu_x86_load_seg_cache(env, R_GS, seg, - (uint8_t *)(seg << 4), 0xffff, 0); - - /* exception support */ - env->idt.base = (void *)idt_table; - env->idt.limit = sizeof(idt_table) - 1; - set_idt(0, 0); - set_idt(1, 0); - set_idt(2, 0); - set_idt(3, 3); - set_idt(4, 3); - set_idt(5, 3); - set_idt(6, 0); - set_idt(7, 0); - set_idt(8, 0); - set_idt(9, 0); - set_idt(10, 0); - set_idt(11, 0); - set_idt(12, 0); - set_idt(13, 0); - set_idt(14, 0); - set_idt(15, 0); - set_idt(16, 0); - set_idt(17, 0); - set_idt(18, 0); - set_idt(19, 0); - - /* put return code */ - *seg_to_linear(env->segs[R_CS].selector, 0) = 0xb4; /* mov ah, $0 */ - *seg_to_linear(env->segs[R_CS].selector, 1) = 0x00; - *seg_to_linear(env->segs[R_CS].selector, 2) = 0xcd; /* int $0x21 */ - *seg_to_linear(env->segs[R_CS].selector, 3) = 0x21; - pushw(env, 0x0000); - - /* the value of these registers seem to be assumed by pi_10.com */ - env->regs[R_ESI] = 0x100; - env->regs[R_ECX] = 0xff; - env->regs[R_EBP] = 0x0900; - env->regs[R_EDI] = 0xfffe; - - /* inform the emulator of the mmaped memory */ - page_set_flags(0x00000000, 0x110000, - PAGE_WRITE | PAGE_READ | PAGE_EXEC | PAGE_VALID); - - for(;;) { - ret = cpu_x86_exec(env); - switch(ret) { - case EXCP0D_GPF: - { - int int_num, ah; - int_num = *(env->segs[R_CS].base + env->eip + 1); - if (int_num != 0x21) - goto unknown_int; - ah = (env->regs[R_EAX] >> 8) & 0xff; - switch(ah) { - case 0x00: /* exit */ - exit(0); - case 0x02: /* write char */ - { - uint8_t c = env->regs[R_EDX]; - write(1, &c, 1); - } - break; - case 0x09: /* write string */ - { - uint8_t c; - for(;;) { - c = *seg_to_linear(env->segs[R_DS].selector, env->regs[R_EAX]); - if (c == '$') - break; - write(1, &c, 1); - } - env->regs[R_EAX] = (env->regs[R_EAX] & ~0xff) | '$'; - } - break; - default: - unknown_int: - fprintf(stderr, "unsupported int 0x%02x\n", int_num); - cpu_dump_state(env, stderr, 0); - // exit(1); - } - env->eip += 2; - } - break; - default: - fprintf(stderr, "unhandled cpu_exec return code (0x%x)\n", ret); - cpu_dump_state(env, stderr, 0); - exit(1); - } - } -} diff --git a/tools/ioemu/tests/runcom.c b/tools/ioemu/tests/runcom.c deleted file mode 100644 index 43deeca098..0000000000 --- a/tools/ioemu/tests/runcom.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Simple example of use of vm86: launch a basic .com DOS executable - */ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <inttypes.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <signal.h> - -#include <linux/unistd.h> -#include <asm/vm86.h> - -//#define SIGTEST - -#undef __syscall_return -#define __syscall_return(type, res) \ -do { \ - return (type) (res); \ -} while (0) - -_syscall2(int, vm86, int, func, struct vm86plus_struct *, v86) - -#define COM_BASE_ADDR 0x10100 - -void usage(void) -{ - printf("runcom version 0.1 (c) 2003 Fabrice Bellard\n" - "usage: runcom file.com\n" - "VM86 Run simple .com DOS executables (linux vm86 test mode)\n"); - exit(1); -} - -static inline void set_bit(uint8_t *a, unsigned int bit) -{ - a[bit / 8] |= (1 << (bit % 8)); -} - -static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg) -{ - return (uint8_t *)((seg << 4) + (reg & 0xffff)); -} - -static inline void pushw(struct vm86_regs *r, int val) -{ - r->esp = (r->esp & ~0xffff) | ((r->esp - 2) & 0xffff); - *(uint16_t *)seg_to_linear(r->ss, r->esp) = val; -} - -void dump_regs(struct vm86_regs *r) -{ - fprintf(stderr, - "EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n" - "ESI=%08lx EDI=%08lx EBP=%08lx ESP=%08lx\n" - "EIP=%08lx EFL=%08lx\n" - "CS=%04x DS=%04x ES=%04x SS=%04x FS=%04x GS=%04x\n", - r->eax, r->ebx, r->ecx, r->edx, r->esi, r->edi, r->ebp, r->esp, - r->eip, r->eflags, - r->cs, r->ds, r->es, r->ss, r->fs, r->gs); -} - -#ifdef SIGTEST -void alarm_handler(int sig) -{ - fprintf(stderr, "alarm signal=%d\n", sig); - alarm(1); -} -#endif - -int main(int argc, char **argv) -{ - uint8_t *vm86_mem; - const char *filename; - int fd, ret, seg; - struct vm86plus_struct ctx; - struct vm86_regs *r; - - if (argc != 2) - usage(); - filename = argv[1]; - - vm86_mem = mmap((void *)0x00000000, 0x110000, - PROT_WRITE | PROT_READ | PROT_EXEC, - MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0); - if (vm86_mem == MAP_FAILED) { - perror("mmap"); - exit(1); - } -#ifdef SIGTEST - { - struct sigaction act; - - act.sa_handler = alarm_handler; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - sigaction(SIGALRM, &act, NULL); - alarm(1); - } -#endif - - /* load the MSDOS .com executable */ - fd = open(filename, O_RDONLY); - if (fd < 0) { - perror(filename); - exit(1); - } - ret = read(fd, vm86_mem + COM_BASE_ADDR, 65536 - 256); - if (ret < 0) { - perror("read"); - exit(1); - } - close(fd); - - memset(&ctx, 0, sizeof(ctx)); - /* init basic registers */ - r = &ctx.regs; - r->eip = 0x100; - r->esp = 0xfffe; - seg = (COM_BASE_ADDR - 0x100) >> 4; - r->cs = seg; - r->ss = seg; - r->ds = seg; - r->es = seg; - r->fs = seg; - r->gs = seg; - r->eflags = VIF_MASK; - - /* put return code */ - set_bit((uint8_t *)&ctx.int_revectored, 0x21); - *seg_to_linear(r->cs, 0) = 0xb4; /* mov ah, $0 */ - *seg_to_linear(r->cs, 1) = 0x00; - *seg_to_linear(r->cs, 2) = 0xcd; /* int $0x21 */ - *seg_to_linear(r->cs, 3) = 0x21; - pushw(&ctx.regs, 0x0000); - - /* the value of these registers seem to be assumed by pi_10.com */ - r->esi = 0x100; - r->ecx = 0xff; - r->ebp = 0x0900; - r->edi = 0xfffe; - - for(;;) { - ret = vm86(VM86_ENTER, &ctx); - switch(VM86_TYPE(ret)) { - case VM86_INTx: - { - int int_num, ah; - - int_num = VM86_ARG(ret); - if (int_num != 0x21) - goto unknown_int; - ah = (r->eax >> 8) & 0xff; - switch(ah) { - case 0x00: /* exit */ - exit(0); - case 0x02: /* write char */ - { - uint8_t c = r->edx; - write(1, &c, 1); - } - break; - case 0x09: /* write string */ - { - uint8_t c; - for(;;) { - c = *seg_to_linear(r->ds, r->edx); - if (c == '$') - break; - write(1, &c, 1); - } - r->eax = (r->eax & ~0xff) | '$'; - } - break; - default: - unknown_int: - fprintf(stderr, "unsupported int 0x%02x\n", int_num); - dump_regs(&ctx.regs); - // exit(1); - } - } - break; - case VM86_SIGNAL: - /* a signal came, we just ignore that */ - break; - case VM86_STI: - break; - default: - fprintf(stderr, "unhandled vm86 return code (0x%x)\n", ret); - dump_regs(&ctx.regs); - exit(1); - } - } -} diff --git a/tools/ioemu/tests/sha1.c b/tools/ioemu/tests/sha1.c deleted file mode 100644 index 31b001920d..0000000000 --- a/tools/ioemu/tests/sha1.c +++ /dev/null @@ -1,242 +0,0 @@ - -/* from valgrind tests */ - -/* ================ sha1.c ================ */ -/* -SHA-1 in C -By Steve Reid <steve@edmweb.com> -100% Public Domain - -Test Vectors (from FIPS PUB 180-1) -"abc" - A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D -"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" - 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 -A million repetitions of "a" - 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F -*/ - -/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */ -/* #define SHA1HANDSOFF * Copies data before messing with it. */ - -#define SHA1HANDSOFF - -#include <stdio.h> -#include <string.h> -#include <sys/types.h> /* for u_int*_t */ - -/* ================ sha1.h ================ */ -/* -SHA-1 in C -By Steve Reid <steve@edmweb.com> -100% Public Domain -*/ - -typedef struct { - u_int32_t state[5]; - u_int32_t count[2]; - unsigned char buffer[64]; -} SHA1_CTX; - -void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64]); -void SHA1Init(SHA1_CTX* context); -void SHA1Update(SHA1_CTX* context, const unsigned char* data, u_int32_t len); -void SHA1Final(unsigned char digest[20], SHA1_CTX* context); -/* ================ end of sha1.h ================ */ -#include <endian.h> - -#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) - -/* blk0() and blk() perform the initial expand. */ -/* I got the idea of expanding during the round function from SSLeay */ -#if BYTE_ORDER == LITTLE_ENDIAN -#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ - |(rol(block->l[i],8)&0x00FF00FF)) -#elif BYTE_ORDER == BIG_ENDIAN -#define blk0(i) block->l[i] -#else -#error "Endianness not defined!" -#endif -#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ - ^block->l[(i+2)&15]^block->l[i&15],1)) - -/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ -#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); -#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); -#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); - - -/* Hash a single 512-bit block. This is the core of the algorithm. */ - -void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64]) -{ -u_int32_t a, b, c, d, e; -typedef union { - unsigned char c[64]; - u_int32_t l[16]; -} CHAR64LONG16; -#ifdef SHA1HANDSOFF -CHAR64LONG16 block[1]; /* use array to appear as a pointer */ - memcpy(block, buffer, 64); -#else - /* The following had better never be used because it causes the - * pointer-to-const buffer to be cast into a pointer to non-const. - * And the result is written through. I threw a "const" in, hoping - * this will cause a diagnostic. - */ -CHAR64LONG16* block = (const CHAR64LONG16*)buffer; -#endif - /* Copy context->state[] to working vars */ - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - e = state[4]; - /* 4 rounds of 20 operations each. Loop unrolled. */ - R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); - R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); - R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); - R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); - R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); - R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); - R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); - R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); - R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); - R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); - R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); - R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); - R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); - R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); - R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); - R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); - R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); - R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); - R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); - R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); - /* Add the working vars back into context.state[] */ - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - state[4] += e; - /* Wipe variables */ - a = b = c = d = e = 0; -#ifdef SHA1HANDSOFF - memset(block, '\0', sizeof(block)); -#endif -} - - -/* SHA1Init - Initialize new context */ - -void SHA1Init(SHA1_CTX* context) -{ - /* SHA1 initialization constants */ - context->state[0] = 0x67452301; - context->state[1] = 0xEFCDAB89; - context->state[2] = 0x98BADCFE; - context->state[3] = 0x10325476; - context->state[4] = 0xC3D2E1F0; - context->count[0] = context->count[1] = 0; -} - - -/* Run your data through this. */ - -void SHA1Update(SHA1_CTX* context, const unsigned char* data, u_int32_t len) -{ -u_int32_t i; -u_int32_t j; - - j = context->count[0]; - if ((context->count[0] += len << 3) < j) - context->count[1]++; - context->count[1] += (len>>29); - j = (j >> 3) & 63; - if ((j + len) > 63) { - memcpy(&context->buffer[j], data, (i = 64-j)); - SHA1Transform(context->state, context->buffer); - for ( ; i + 63 < len; i += 64) { - SHA1Transform(context->state, &data[i]); - } - j = 0; - } - else i = 0; - memcpy(&context->buffer[j], &data[i], len - i); -} - - -/* Add padding and return the message digest. */ - -void SHA1Final(unsigned char digest[20], SHA1_CTX* context) -{ -unsigned i; -unsigned char finalcount[8]; -unsigned char c; - -#if 0 /* untested "improvement" by DHR */ - /* Convert context->count to a sequence of bytes - * in finalcount. Second element first, but - * big-endian order within element. - * But we do it all backwards. - */ - unsigned char *fcp = &finalcount[8]; - - for (i = 0; i < 2; i++) - { - u_int32_t t = context->count[i]; - int j; - - for (j = 0; j < 4; t >>= 8, j++) - *--fcp = (unsigned char) t - } -#else - for (i = 0; i < 8; i++) { - finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] - >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ - } -#endif - c = 0200; - SHA1Update(context, &c, 1); - while ((context->count[0] & 504) != 448) { - c = 0000; - SHA1Update(context, &c, 1); - } - SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ - for (i = 0; i < 20; i++) { - digest[i] = (unsigned char) - ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); - } - /* Wipe variables */ - memset(context, '\0', sizeof(*context)); - memset(&finalcount, '\0', sizeof(finalcount)); -} -/* ================ end of sha1.c ================ */ - -#define BUFSIZE 4096 - -int -main(int argc, char **argv) -{ - SHA1_CTX ctx; - unsigned char hash[20], buf[BUFSIZE]; - int i; - - for(i=0;i<BUFSIZE;i++) - buf[i] = i; - - SHA1Init(&ctx); - for(i=0;i<1000;i++) - SHA1Update(&ctx, buf, BUFSIZE); - SHA1Final(hash, &ctx); - - printf("SHA1="); - for(i=0;i<20;i++) - printf("%02x", hash[i]); - printf("\n"); - return 0; -} - - diff --git a/tools/ioemu/tests/test-i386-code16.S b/tools/ioemu/tests/test-i386-code16.S deleted file mode 100644 index 78ecc1f77e..0000000000 --- a/tools/ioemu/tests/test-i386-code16.S +++ /dev/null @@ -1,97 +0,0 @@ - .code16 - .globl code16_start - .globl code16_end - -CS_SEG = 0xf - -code16_start: - - .globl code16_func1 - - /* basic test */ -code16_func1 = . - code16_start - mov $1, %eax - data32 lret - -/* test push/pop in 16 bit mode */ - .globl code16_func2 -code16_func2 = . - code16_start - xor %eax, %eax - mov $0x12345678, %ebx - movl %esp, %ecx - push %bx - subl %esp, %ecx - pop %ax - data32 lret - -/* test various jmp opcodes */ - .globl code16_func3 -code16_func3 = . - code16_start - jmp 1f - nop -1: - mov $4, %eax - mov $0x12345678, %ebx - xor %bx, %bx - jz 2f - add $2, %ax -2: - - call myfunc - - lcall $CS_SEG, $(myfunc2 - code16_start) - - ljmp $CS_SEG, $(myjmp1 - code16_start) -myjmp1_next: - - cs lcall myfunc2_addr - code16_start - - cs ljmp myjmp2_addr - code16_start -myjmp2_next: - - data32 lret - -myfunc2_addr: - .short myfunc2 - code16_start - .short CS_SEG - -myjmp2_addr: - .short myjmp2 - code16_start - .short CS_SEG - -myjmp1: - add $8, %ax - jmp myjmp1_next - -myjmp2: - add $16, %ax - jmp myjmp2_next - -myfunc: - add $1, %ax - ret - -myfunc2: - add $4, %ax - lret - - -code16_end: - - -/* other 32 bits tests */ - .code32 - - .globl func_lret32 -func_lret32: - movl $0x87654321, %eax - lret - - .globl func_iret32 -func_iret32: - movl $0xabcd4321, %eax - iret - - - -
\ No newline at end of file diff --git a/tools/ioemu/tests/test-i386-muldiv.h b/tools/ioemu/tests/test-i386-muldiv.h deleted file mode 100644 index 5dba315c24..0000000000 --- a/tools/ioemu/tests/test-i386-muldiv.h +++ /dev/null @@ -1,56 +0,0 @@ - -void glue(glue(test_, OP), b)(int op0, int op1) -{ - int res, s1, s0, flags; - s0 = op0; - s1 = op1; - res = s0; - flags = 0; - asm ("push %4\n\t" - "popf\n\t" - stringify(OP)"b %b2\n\t" - "pushf\n\t" - "popl %1\n\t" - : "=a" (res), "=g" (flags) - : "q" (s1), "0" (res), "1" (flags)); - printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n", - stringify(OP) "b", s0, s1, res, flags & CC_MASK); -} - -void glue(glue(test_, OP), w)(int op0h, int op0, int op1) -{ - int res, s1, flags, resh; - s1 = op1; - resh = op0h; - res = op0; - flags = 0; - asm ("push %5\n\t" - "popf\n\t" - stringify(OP) "w %w3\n\t" - "pushf\n\t" - "popl %1\n\t" - : "=a" (res), "=g" (flags), "=d" (resh) - : "q" (s1), "0" (res), "1" (flags), "2" (resh)); - printf("%-10s AH=%08x AL=%08x B=%08x RH=%08x RL=%08x CC=%04x\n", - stringify(OP) "w", op0h, op0, s1, resh, res, flags & CC_MASK); -} - -void glue(glue(test_, OP), l)(int op0h, int op0, int op1) -{ - int res, s1, flags, resh; - s1 = op1; - resh = op0h; - res = op0; - flags = 0; - asm ("push %5\n\t" - "popf\n\t" - stringify(OP) "l %3\n\t" - "pushf\n\t" - "popl %1\n\t" - : "=a" (res), "=g" (flags), "=d" (resh) - : "q" (s1), "0" (res), "1" (flags), "2" (resh)); - printf("%-10s AH=%08x AL=%08x B=%08x RH=%08x RL=%08x CC=%04x\n", - stringify(OP) "l", op0h, op0, s1, resh, res, flags & CC_MASK); -} - -#undef OP diff --git a/tools/ioemu/tests/test-i386-shift.h b/tools/ioemu/tests/test-i386-shift.h deleted file mode 100644 index c3d8793b8b..0000000000 --- a/tools/ioemu/tests/test-i386-shift.h +++ /dev/null @@ -1,143 +0,0 @@ - -#define exec_op glue(exec_, OP) -#define exec_opl glue(glue(exec_, OP), l) -#define exec_opw glue(glue(exec_, OP), w) -#define exec_opb glue(glue(exec_, OP), b) - -#ifndef OP_SHIFTD - -#ifdef OP_NOBYTE -#define EXECSHIFT(size, res, s1, s2, flags) \ - asm ("push %4\n\t"\ - "popf\n\t"\ - stringify(OP) size " %" size "2, %" size "0\n\t" \ - "pushf\n\t"\ - "popl %1\n\t"\ - : "=g" (res), "=g" (flags)\ - : "r" (s1), "0" (res), "1" (flags)); -#else -#define EXECSHIFT(size, res, s1, s2, flags) \ - asm ("push %4\n\t"\ - "popf\n\t"\ - stringify(OP) size " %%cl, %" size "0\n\t" \ - "pushf\n\t"\ - "popl %1\n\t"\ - : "=q" (res), "=g" (flags)\ - : "c" (s1), "0" (res), "1" (flags)); -#endif - -void exec_opl(int s2, int s0, int s1, int iflags) -{ - int res, flags; - res = s0; - flags = iflags; - EXECSHIFT("", res, s1, s2, flags); - /* overflow is undefined if count != 1 */ - if (s1 != 1) - flags &= ~CC_O; - printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n", - stringify(OP) "l", s0, s1, res, iflags, flags & CC_MASK); -} - -void exec_opw(int s2, int s0, int s1, int iflags) -{ - int res, flags; - res = s0; - flags = iflags; - EXECSHIFT("w", res, s1, s2, flags); - /* overflow is undefined if count != 1 */ - if (s1 != 1) - flags &= ~CC_O; - printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n", - stringify(OP) "w", s0, s1, res, iflags, flags & CC_MASK); -} - -#else -#define EXECSHIFT(size, res, s1, s2, flags) \ - asm ("push %4\n\t"\ - "popf\n\t"\ - stringify(OP) size " %%cl, %" size "5, %" size "0\n\t" \ - "pushf\n\t"\ - "popl %1\n\t"\ - : "=g" (res), "=g" (flags)\ - : "c" (s1), "0" (res), "1" (flags), "r" (s2)); - -void exec_opl(int s2, int s0, int s1, int iflags) -{ - int res, flags; - res = s0; - flags = iflags; - EXECSHIFT("", res, s1, s2, flags); - /* overflow is undefined if count != 1 */ - if (s1 != 1) - flags &= ~CC_O; - printf("%-10s A=%08x B=%08x C=%08x R=%08x CCIN=%04x CC=%04x\n", - stringify(OP) "l", s0, s2, s1, res, iflags, flags & CC_MASK); -} - -void exec_opw(int s2, int s0, int s1, int iflags) -{ - int res, flags; - res = s0; - flags = iflags; - EXECSHIFT("w", res, s1, s2, flags); - /* overflow is undefined if count != 1 */ - if (s1 != 1) - flags &= ~CC_O; - printf("%-10s A=%08x B=%08x C=%08x R=%08x CCIN=%04x CC=%04x\n", - stringify(OP) "w", s0, s2, s1, res, iflags, flags & CC_MASK); -} - -#endif - -#ifndef OP_NOBYTE -void exec_opb(int s0, int s1, int iflags) -{ - int res, flags; - res = s0; - flags = iflags; - EXECSHIFT("b", res, s1, 0, flags); - /* overflow is undefined if count != 1 */ - if (s1 != 1) - flags &= ~CC_O; - printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n", - stringify(OP) "b", s0, s1, res, iflags, flags & CC_MASK); -} -#endif - -void exec_op(int s2, int s0, int s1) -{ - exec_opl(s2, s0, s1, 0); -#ifdef OP_SHIFTD - if (s1 <= 15) - exec_opw(s2, s0, s1, 0); -#else - exec_opw(s2, s0, s1, 0); -#endif -#ifndef OP_NOBYTE - exec_opb(s0, s1, 0); -#endif -#ifdef OP_CC - exec_opl(s2, s0, s1, CC_C); - exec_opw(s2, s0, s1, CC_C); - exec_opb(s0, s1, CC_C); -#endif -} - -void glue(test_, OP)(void) -{ - int i; - for(i = 0; i < 32; i++) - exec_op(0x21ad3d34, 0x12345678, i); - for(i = 0; i < 32; i++) - exec_op(0x813f3421, 0x82345678, i); -} - -void *glue(_test_, OP) __init_call = glue(test_, OP); - -#undef OP -#undef OP_CC -#undef OP_SHIFTD -#undef OP_NOBYTE -#undef EXECSHIFT - diff --git a/tools/ioemu/tests/test-i386-vm86.S b/tools/ioemu/tests/test-i386-vm86.S deleted file mode 100644 index a972f1b81e..0000000000 --- a/tools/ioemu/tests/test-i386-vm86.S +++ /dev/null @@ -1,104 +0,0 @@ - .code16 - .globl vm86_code_start - .globl vm86_code_end - -#define GET_OFFSET(x) ((x) - vm86_code_start + 0x100) - -vm86_code_start: - movw $GET_OFFSET(hello_world), %dx - movb $0x09, %ah - int $0x21 - - /* prepare int 0x90 vector */ - xorw %ax, %ax - movw %ax, %es - es movw $GET_OFFSET(int90_test), 0x90 * 4 - es movw %cs, 0x90 * 4 + 2 - - /* launch int 0x90 */ - - int $0x90 - - /* test IF support */ - movw $GET_OFFSET(IF_msg), %dx - movb $0x09, %ah - int $0x21 - - pushf - popw %dx - movb $0xff, %ah - int $0x21 - - cli - pushf - popw %dx - movb $0xff, %ah - int $0x21 - - sti - pushfl - popl %edx - movb $0xff, %ah - int $0x21 - -#if 0 - movw $GET_OFFSET(IF_msg1), %dx - movb $0x09, %ah - int $0x21 - - pushf - movw %sp, %bx - andw $~0x200, (%bx) - popf -#else - cli -#endif - - pushf - popw %dx - movb $0xff, %ah - int $0x21 - - pushfl - movw %sp, %bx - orw $0x200, (%bx) - popfl - - pushfl - popl %edx - movb $0xff, %ah - int $0x21 - - movb $0x00, %ah - int $0x21 - -int90_test: - pushf - pop %dx - movb $0xff, %ah - int $0x21 - - movw %sp, %bx - movw 4(%bx), %dx - movb $0xff, %ah - int $0x21 - - movw $GET_OFFSET(int90_msg), %dx - movb $0x09, %ah - int $0x21 - iret - -int90_msg: - .string "INT90 started\n$" - -hello_world: - .string "Hello VM86 world\n$" - -IF_msg: - .string "VM86 IF test\n$" - -IF_msg1: - .string "If you see a diff here, your Linux kernel is buggy, please update to 2.4.20 kernel\n$" - -vm86_code_end: -
\ No newline at end of file diff --git a/tools/ioemu/tests/test-i386.c b/tools/ioemu/tests/test-i386.c deleted file mode 100644 index a4bfa34dee..0000000000 --- a/tools/ioemu/tests/test-i386.c +++ /dev/null @@ -1,1706 +0,0 @@ -/* - * x86 CPU test - * - * Copyright (c) 2003 Fabrice Bellard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#define _GNU_SOURCE -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <inttypes.h> -#include <math.h> -#include <signal.h> -#include <setjmp.h> -#include <errno.h> -#include <sys/ucontext.h> -#include <sys/mman.h> -#include <asm/vm86.h> - -#define TEST_CMOV 0 -#define TEST_FCOMI 0 -//#define LINUX_VM86_IOPL_FIX -//#define TEST_P4_FLAGS - -#define xglue(x, y) x ## y -#define glue(x, y) xglue(x, y) -#define stringify(s) tostring(s) -#define tostring(s) #s - -#define CC_C 0x0001 -#define CC_P 0x0004 -#define CC_A 0x0010 -#define CC_Z 0x0040 -#define CC_S 0x0080 -#define CC_O 0x0800 - -#define __init_call __attribute__ ((unused,__section__ (".initcall.init"))) - -static void *call_start __init_call = NULL; - -#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A) - -#define OP add -#include "test-i386.h" - -#define OP sub -#include "test-i386.h" - -#define OP xor -#include "test-i386.h" - -#define OP and -#include "test-i386.h" - -#define OP or -#include "test-i386.h" - -#define OP cmp -#include "test-i386.h" - -#define OP adc -#define OP_CC -#include "test-i386.h" - -#define OP sbb -#define OP_CC -#include "test-i386.h" - -#define OP inc -#define OP_CC -#define OP1 -#include "test-i386.h" - -#define OP dec -#define OP_CC -#define OP1 -#include "test-i386.h" - -#define OP neg -#define OP_CC -#define OP1 -#include "test-i386.h" - -#define OP not -#define OP_CC -#define OP1 -#include "test-i386.h" - -#undef CC_MASK -#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O) - -#define OP shl -#include "test-i386-shift.h" - -#define OP shr -#include "test-i386-shift.h" - -#define OP sar -#include "test-i386-shift.h" - -#define OP rol -#include "test-i386-shift.h" - -#define OP ror -#include "test-i386-shift.h" - -#define OP rcr -#define OP_CC -#include "test-i386-shift.h" - -#define OP rcl -#define OP_CC -#include "test-i386-shift.h" - -#define OP shld -#define OP_SHIFTD -#define OP_NOBYTE -#include "test-i386-shift.h" - -#define OP shrd -#define OP_SHIFTD -#define OP_NOBYTE -#include "test-i386-shift.h" - -/* XXX: should be more precise ? */ -#undef CC_MASK -#define CC_MASK (CC_C) - -#define OP bt -#define OP_NOBYTE -#include "test-i386-shift.h" - -#define OP bts -#define OP_NOBYTE -#include "test-i386-shift.h" - -#define OP btr -#define OP_NOBYTE -#include "test-i386-shift.h" - -#define OP btc -#define OP_NOBYTE -#include "test-i386-shift.h" - -/* lea test (modrm support) */ -#define TEST_LEA(STR)\ -{\ - asm("leal " STR ", %0"\ - : "=r" (res)\ - : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\ - printf("lea %s = %08x\n", STR, res);\ -} - -#define TEST_LEA16(STR)\ -{\ - asm(".code16 ; .byte 0x67 ; leal " STR ", %0 ; .code32"\ - : "=wq" (res)\ - : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\ - printf("lea %s = %08x\n", STR, res);\ -} - - -void test_lea(void) -{ - int eax, ebx, ecx, edx, esi, edi, res; - eax = 0x0001; - ebx = 0x0002; - ecx = 0x0004; - edx = 0x0008; - esi = 0x0010; - edi = 0x0020; - - TEST_LEA("0x4000"); - - TEST_LEA("(%%eax)"); - TEST_LEA("(%%ebx)"); - TEST_LEA("(%%ecx)"); - TEST_LEA("(%%edx)"); - TEST_LEA("(%%esi)"); - TEST_LEA("(%%edi)"); - - TEST_LEA("0x40(%%eax)"); - TEST_LEA("0x40(%%ebx)"); - TEST_LEA("0x40(%%ecx)"); - TEST_LEA("0x40(%%edx)"); - TEST_LEA("0x40(%%esi)"); - TEST_LEA("0x40(%%edi)"); - - TEST_LEA("0x4000(%%eax)"); - TEST_LEA("0x4000(%%ebx)"); - TEST_LEA("0x4000(%%ecx)"); - TEST_LEA("0x4000(%%edx)"); - TEST_LEA("0x4000(%%esi)"); - TEST_LEA("0x4000(%%edi)"); - - TEST_LEA("(%%eax, %%ecx)"); - TEST_LEA("(%%ebx, %%edx)"); - TEST_LEA("(%%ecx, %%ecx)"); - TEST_LEA("(%%edx, %%ecx)"); - TEST_LEA("(%%esi, %%ecx)"); - TEST_LEA("(%%edi, %%ecx)"); - - TEST_LEA("0x40(%%eax, %%ecx)"); - TEST_LEA("0x4000(%%ebx, %%edx)"); - - TEST_LEA("(%%ecx, %%ecx, 2)"); - TEST_LEA("(%%edx, %%ecx, 4)"); - TEST_LEA("(%%esi, %%ecx, 8)"); - - TEST_LEA("(,%%eax, 2)"); - TEST_LEA("(,%%ebx, 4)"); - TEST_LEA("(,%%ecx, 8)"); - - TEST_LEA("0x40(,%%eax, 2)"); - TEST_LEA("0x40(,%%ebx, 4)"); - TEST_LEA("0x40(,%%ecx, 8)"); - - - TEST_LEA("-10(%%ecx, %%ecx, 2)"); - TEST_LEA("-10(%%edx, %%ecx, 4)"); - TEST_LEA("-10(%%esi, %%ecx, 8)"); - - TEST_LEA("0x4000(%%ecx, %%ecx, 2)"); - TEST_LEA("0x4000(%%edx, %%ecx, 4)"); - TEST_LEA("0x4000(%%esi, %%ecx, 8)"); - - /* limited 16 bit addressing test */ - TEST_LEA16("0x4000"); - TEST_LEA16("(%%bx)"); - TEST_LEA16("(%%si)"); - TEST_LEA16("(%%di)"); - TEST_LEA16("0x40(%%bx)"); - TEST_LEA16("0x40(%%si)"); - TEST_LEA16("0x40(%%di)"); - TEST_LEA16("0x4000(%%bx)"); - TEST_LEA16("0x4000(%%si)"); - TEST_LEA16("(%%bx,%%si)"); - TEST_LEA16("(%%bx,%%di)"); - TEST_LEA16("0x40(%%bx,%%si)"); - TEST_LEA16("0x40(%%bx,%%di)"); - TEST_LEA16("0x4000(%%bx,%%si)"); - TEST_LEA16("0x4000(%%bx,%%di)"); -} - -#define TEST_JCC(JCC, v1, v2)\ -{\ - int res;\ - asm("movl $1, %0\n\t"\ - "cmpl %2, %1\n\t"\ - "j" JCC " 1f\n\t"\ - "movl $0, %0\n\t"\ - "1:\n\t"\ - : "=r" (res)\ - : "r" (v1), "r" (v2));\ - printf("%-10s %d\n", "j" JCC, res);\ -\ - asm("movl $0, %0\n\t"\ - "cmpl %2, %1\n\t"\ - "set" JCC " %b0\n\t"\ - : "=r" (res)\ - : "r" (v1), "r" (v2));\ - printf("%-10s %d\n", "set" JCC, res);\ - if (TEST_CMOV) {\ - asm("movl $0x12345678, %0\n\t"\ - "cmpl %2, %1\n\t"\ - "cmov" JCC "l %3, %0\n\t"\ - : "=r" (res)\ - : "r" (v1), "r" (v2), "m" (1));\ - printf("%-10s R=0x%08x\n", "cmov" JCC "l", res);\ - asm("movl $0x12345678, %0\n\t"\ - "cmpl %2, %1\n\t"\ - "cmov" JCC "w %w3, %w0\n\t"\ - : "=r" (res)\ - : "r" (v1), "r" (v2), "r" (1));\ - printf("%-10s R=0x%08x\n", "cmov" JCC "w", res);\ - } \ -} - -/* various jump tests */ -void test_jcc(void) -{ - TEST_JCC("ne", 1, 1); - TEST_JCC("ne", 1, 0); - - TEST_JCC("e", 1, 1); - TEST_JCC("e", 1, 0); - - TEST_JCC("l", 1, 1); - TEST_JCC("l", 1, 0); - TEST_JCC("l", 1, -1); - - TEST_JCC("le", 1, 1); - TEST_JCC("le", 1, 0); - TEST_JCC("le", 1, -1); - - TEST_JCC("ge", 1, 1); - TEST_JCC("ge", 1, 0); - TEST_JCC("ge", -1, 1); - - TEST_JCC("g", 1, 1); - TEST_JCC("g", 1, 0); - TEST_JCC("g", 1, -1); - - TEST_JCC("b", 1, 1); - TEST_JCC("b", 1, 0); - TEST_JCC("b", 1, -1); - - TEST_JCC("be", 1, 1); - TEST_JCC("be", 1, 0); - TEST_JCC("be", 1, -1); - - TEST_JCC("ae", 1, 1); - TEST_JCC("ae", 1, 0); - TEST_JCC("ae", 1, -1); - - TEST_JCC("a", 1, 1); - TEST_JCC("a", 1, 0); - TEST_JCC("a", 1, -1); - - - TEST_JCC("p", 1, 1); - TEST_JCC("p", 1, 0); - - TEST_JCC("np", 1, 1); - TEST_JCC("np", 1, 0); - - TEST_JCC("o", 0x7fffffff, 0); - TEST_JCC("o", 0x7fffffff, -1); - - TEST_JCC("no", 0x7fffffff, 0); - TEST_JCC("no", 0x7fffffff, -1); - - TEST_JCC("s", 0, 1); - TEST_JCC("s", 0, -1); - TEST_JCC("s", 0, 0); - - TEST_JCC("ns", 0, 1); - TEST_JCC("ns", 0, -1); - TEST_JCC("ns", 0, 0); -} - -#undef CC_MASK -#ifdef TEST_P4_FLAGS -#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A) -#else -#define CC_MASK (CC_O | CC_C) -#endif - -#define OP mul -#include "test-i386-muldiv.h" - -#define OP imul -#include "test-i386-muldiv.h" - -void test_imulw2(int op0, int op1) -{ - int res, s1, s0, flags; - s0 = op0; - s1 = op1; - res = s0; - flags = 0; - asm ("push %4\n\t" - "popf\n\t" - "imulw %w2, %w0\n\t" - "pushf\n\t" - "popl %1\n\t" - : "=q" (res), "=g" (flags) - : "q" (s1), "0" (res), "1" (flags)); - printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n", - "imulw", s0, s1, res, flags & CC_MASK); -} - -void test_imull2(int op0, int op1) -{ - int res, s1, s0, flags; - s0 = op0; - s1 = op1; - res = s0; - flags = 0; - asm ("push %4\n\t" - "popf\n\t" - "imull %2, %0\n\t" - "pushf\n\t" - "popl %1\n\t" - : "=q" (res), "=g" (flags) - : "q" (s1), "0" (res), "1" (flags)); - printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n", - "imull", s0, s1, res, flags & CC_MASK); -} - -#define TEST_IMUL_IM(size, size1, op0, op1)\ -{\ - int res, flags;\ - flags = 0;\ - res = 0;\ - asm ("push %3\n\t"\ - "popf\n\t"\ - "imul" size " $" #op0 ", %" size1 "2, %" size1 "0\n\t" \ - "pushf\n\t"\ - "popl %1\n\t"\ - : "=r" (res), "=g" (flags)\ - : "r" (op1), "1" (flags), "0" (res));\ - printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",\ - "imul" size, op0, op1, res, flags & CC_MASK);\ -} - - -#undef CC_MASK -#define CC_MASK (0) - -#define OP div -#include "test-i386-muldiv.h" - -#define OP idiv -#include "test-i386-muldiv.h" - -void test_mul(void) -{ - test_imulb(0x1234561d, 4); - test_imulb(3, -4); - test_imulb(0x80, 0x80); - test_imulb(0x10, 0x10); - - test_imulw(0, 0x1234001d, 45); - test_imulw(0, 23, -45); - test_imulw(0, 0x8000, 0x8000); - test_imulw(0, 0x100, 0x100); - - test_imull(0, 0x1234001d, 45); - test_imull(0, 23, -45); - test_imull(0, 0x80000000, 0x80000000); - test_imull(0, 0x10000, 0x10000); - - test_mulb(0x1234561d, 4); - test_mulb(3, -4); - test_mulb(0x80, 0x80); - test_mulb(0x10, 0x10); - - test_mulw(0, 0x1234001d, 45); - test_mulw(0, 23, -45); - test_mulw(0, 0x8000, 0x8000); - test_mulw(0, 0x100, 0x100); - - test_mull(0, 0x1234001d, 45); - test_mull(0, 23, -45); - test_mull(0, 0x80000000, 0x80000000); - test_mull(0, 0x10000, 0x10000); - - test_imulw2(0x1234001d, 45); - test_imulw2(23, -45); - test_imulw2(0x8000, 0x8000); - test_imulw2(0x100, 0x100); - - test_imull2(0x1234001d, 45); - test_imull2(23, -45); - test_imull2(0x80000000, 0x80000000); - test_imull2(0x10000, 0x10000); - - TEST_IMUL_IM("w", "w", 45, 0x1234); - TEST_IMUL_IM("w", "w", -45, 23); - TEST_IMUL_IM("w", "w", 0x8000, 0x80000000); - TEST_IMUL_IM("w", "w", 0x7fff, 0x1000); - - TEST_IMUL_IM("l", "", 45, 0x1234); - TEST_IMUL_IM("l", "", -45, 23); - TEST_IMUL_IM("l", "", 0x8000, 0x80000000); - TEST_IMUL_IM("l", "", 0x7fff, 0x1000); - - test_idivb(0x12341678, 0x127e); - test_idivb(0x43210123, -5); - test_idivb(0x12340004, -1); - - test_idivw(0, 0x12345678, 12347); - test_idivw(0, -23223, -45); - test_idivw(0, 0x12348000, -1); - test_idivw(0x12343, 0x12345678, 0x81238567); - - test_idivl(0, 0x12345678, 12347); - test_idivl(0, -233223, -45); - test_idivl(0, 0x80000000, -1); - test_idivl(0x12343, 0x12345678, 0x81234567); - - test_divb(0x12341678, 0x127e); - test_divb(0x43210123, -5); - test_divb(0x12340004, -1); - - test_divw(0, 0x12345678, 12347); - test_divw(0, -23223, -45); - test_divw(0, 0x12348000, -1); - test_divw(0x12343, 0x12345678, 0x81238567); - - test_divl(0, 0x12345678, 12347); - test_divl(0, -233223, -45); - test_divl(0, 0x80000000, -1); - test_divl(0x12343, 0x12345678, 0x81234567); -} - -#define TEST_BSX(op, size, op0)\ -{\ - int res, val, resz;\ - val = op0;\ - asm("xorl %1, %1\n"\ - "movl $0x12345678, %0\n"\ - #op " %" size "2, %" size "0 ; setz %b1" \ - : "=r" (res), "=q" (resz)\ - : "g" (val));\ - printf("%-10s A=%08x R=%08x %d\n", #op, val, res, resz);\ -} - -void test_bsx(void) -{ - TEST_BSX(bsrw, "w", 0); - TEST_BSX(bsrw, "w", 0x12340128); - TEST_BSX(bsrl, "", 0); - TEST_BSX(bsrl, "", 0x00340128); - TEST_BSX(bsfw, "w", 0); - TEST_BSX(bsfw, "w", 0x12340128); - TEST_BSX(bsfl, "", 0); - TEST_BSX(bsfl, "", 0x00340128); -} - -/**********************************************/ - -void test_fops(double a, double b) -{ - printf("a=%f b=%f a+b=%f\n", a, b, a + b); - printf("a=%f b=%f a-b=%f\n", a, b, a - b); - printf("a=%f b=%f a*b=%f\n", a, b, a * b); - printf("a=%f b=%f a/b=%f\n", a, b, a / b); - printf("a=%f b=%f fmod(a, b)=%f\n", a, b, fmod(a, b)); - printf("a=%f sqrt(a)=%f\n", a, sqrt(a)); - printf("a=%f sin(a)=%f\n", a, sin(a)); - printf("a=%f cos(a)=%f\n", a, cos(a)); - printf("a=%f tan(a)=%f\n", a, tan(a)); - printf("a=%f log(a)=%f\n", a, log(a)); - printf("a=%f exp(a)=%f\n", a, exp(a)); - printf("a=%f b=%f atan2(a, b)=%f\n", a, b, atan2(a, b)); - /* just to test some op combining */ - printf("a=%f asin(sin(a))=%f\n", a, asin(sin(a))); - printf("a=%f acos(cos(a))=%f\n", a, acos(cos(a))); - printf("a=%f atan(tan(a))=%f\n", a, atan(tan(a))); - -} - -void test_fcmp(double a, double b) -{ - printf("(%f<%f)=%d\n", - a, b, a < b); - printf("(%f<=%f)=%d\n", - a, b, a <= b); - printf("(%f==%f)=%d\n", - a, b, a == b); - printf("(%f>%f)=%d\n", - a, b, a > b); - printf("(%f<=%f)=%d\n", - a, b, a >= b); - if (TEST_FCOMI) { - unsigned int eflags; - /* test f(u)comi instruction */ - asm("fcomi %2, %1\n" - "pushf\n" - "pop %0\n" - : "=r" (eflags) - : "t" (a), "u" (b)); - printf("fcomi(%f %f)=%08x\n", a, b, eflags & (CC_Z | CC_P | CC_C)); - } -} - -void test_fcvt(double a) -{ - float fa; - long double la; - int16_t fpuc; - int i; - int64_t lla; - int ia; - int16_t wa; - double ra; - - fa = a; - la = a; - printf("(float)%f = %f\n", a, fa); - printf("(long double)%f = %Lf\n", a, la); - printf("a=%016Lx\n", *(long long *)&a); - printf("la=%016Lx %04x\n", *(long long *)&la, - *(unsigned short *)((char *)(&la) + 8)); - - /* test all roundings */ - asm volatile ("fstcw %0" : "=m" (fpuc)); - for(i=0;i<4;i++) { - asm volatile ("fldcw %0" : : "m" ((fpuc & ~0x0c00) | (i << 10))); - asm volatile ("fist %0" : "=m" (wa) : "t" (a)); - asm volatile ("fistl %0" : "=m" (ia) : "t" (a)); - asm volatile ("fistpll %0" : "=m" (lla) : "t" (a) : "st"); - asm volatile ("frndint ; fstl %0" : "=m" (ra) : "t" (a)); - asm volatile ("fldcw %0" : : "m" (fpuc)); - printf("(short)a = %d\n", wa); - printf("(int)a = %d\n", ia); - printf("(int64_t)a = %Ld\n", lla); - printf("rint(a) = %f\n", ra); - } -} - -#define TEST(N) \ - asm("fld" #N : "=t" (a)); \ - printf("fld" #N "= %f\n", a); - -void test_fconst(void) -{ - double a; - TEST(1); - TEST(l2t); - TEST(l2e); - TEST(pi); - TEST(lg2); - TEST(ln2); - TEST(z); -} - -void test_fbcd(double a) -{ - unsigned short bcd[5]; - double b; - - asm("fbstp %0" : "=m" (bcd[0]) : "t" (a) : "st"); - asm("fbld %1" : "=t" (b) : "m" (bcd[0])); - printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n", - a, bcd[4], bcd[3], bcd[2], bcd[1], bcd[0], b); -} - -#define TEST_ENV(env, save, restore)\ -{\ - memset((env), 0xaa, sizeof(*(env)));\ - for(i=0;i<5;i++)\ - asm volatile ("fldl %0" : : "m" (dtab[i]));\ - asm(save " %0\n" : : "m" (*(env)));\ - asm(restore " %0\n": : "m" (*(env)));\ - for(i=0;i<5;i++)\ - asm volatile ("fstpl %0" : "=m" (rtab[i]));\ - for(i=0;i<5;i++)\ - printf("res[%d]=%f\n", i, rtab[i]);\ - printf("fpuc=%04x fpus=%04x fptag=%04x\n",\ - (env)->fpuc,\ - (env)->fpus & 0xff00,\ - (env)->fptag);\ -} - -void test_fenv(void) -{ - struct __attribute__((packed)) { - uint16_t fpuc; - uint16_t dummy1; - uint16_t fpus; - uint16_t dummy2; - uint16_t fptag; - uint16_t dummy3; - uint32_t ignored[4]; - long double fpregs[8]; - } float_env32; - struct __attribute__((packed)) { - uint16_t fpuc; - uint16_t fpus; - uint16_t fptag; - uint16_t ignored[4]; - long double fpregs[8]; - } float_env16; - double dtab[8]; - double rtab[8]; - int i; - - for(i=0;i<8;i++) - dtab[i] = i + 1; - - TEST_ENV(&float_env16, "data16 fnstenv", "data16 fldenv"); - TEST_ENV(&float_env16, "data16 fnsave", "data16 frstor"); - TEST_ENV(&float_env32, "fnstenv", "fldenv"); - TEST_ENV(&float_env32, "fnsave", "frstor"); - - /* test for ffree */ - for(i=0;i<5;i++) - asm volatile ("fldl %0" : : "m" (dtab[i])); - asm volatile("ffree %st(2)"); - asm volatile ("fnstenv %0\n" : : "m" (float_env32)); - asm volatile ("fninit"); - printf("fptag=%04x\n", float_env32.fptag); -} - - -#define TEST_FCMOV(a, b, eflags, CC)\ -{\ - double res;\ - asm("push %3\n"\ - "popf\n"\ - "fcmov" CC " %2, %0\n"\ - : "=t" (res)\ - : "0" (a), "u" (b), "g" (eflags));\ - printf("fcmov%s eflags=0x%04x-> %f\n", \ - CC, eflags, res);\ -} - -void test_fcmov(void) -{ - double a, b; - int eflags, i; - - a = 1.0; - b = 2.0; - for(i = 0; i < 4; i++) { - eflags = 0; - if (i & 1) - eflags |= CC_C; - if (i & 2) - eflags |= CC_Z; - TEST_FCMOV(a, b, eflags, "b"); - TEST_FCMOV(a, b, eflags, "e"); - TEST_FCMOV(a, b, eflags, "be"); - TEST_FCMOV(a, b, eflags, "nb"); - TEST_FCMOV(a, b, eflags, "ne"); - TEST_FCMOV(a, b, eflags, "nbe"); - } - TEST_FCMOV(a, b, 0, "u"); - TEST_FCMOV(a, b, CC_P, "u"); - TEST_FCMOV(a, b, 0, "nu"); - TEST_FCMOV(a, b, CC_P, "nu"); -} - -void test_floats(void) -{ - test_fops(2, 3); - test_fops(1.4, -5); - test_fcmp(2, -1); - test_fcmp(2, 2); - test_fcmp(2, 3); - test_fcvt(0.5); - test_fcvt(-0.5); - test_fcvt(1.0/7.0); - test_fcvt(-1.0/9.0); - test_fcvt(32768); - test_fcvt(-1e20); - test_fconst(); - test_fbcd(1234567890123456); - test_fbcd(-123451234567890); - test_fenv(); - if (TEST_CMOV) { - test_fcmov(); - } -} - -/**********************************************/ - -#define TEST_BCD(op, op0, cc_in, cc_mask)\ -{\ - int res, flags;\ - res = op0;\ - flags = cc_in;\ - asm ("push %3\n\t"\ - "popf\n\t"\ - #op "\n\t"\ - "pushf\n\t"\ - "popl %1\n\t"\ - : "=a" (res), "=g" (flags)\ - : "0" (res), "1" (flags));\ - printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n",\ - #op, op0, res, cc_in, flags & cc_mask);\ -} - -void test_bcd(void) -{ - TEST_BCD(daa, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(daa, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(daa, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(daa, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(daa, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(daa, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(daa, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(daa, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(daa, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(daa, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(daa, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(daa, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(daa, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - - TEST_BCD(das, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(das, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(das, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(das, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(das, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(das, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(das, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(das, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(das, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(das, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(das, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(das, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - TEST_BCD(das, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); - - TEST_BCD(aaa, 0x12340205, CC_A, (CC_C | CC_A)); - TEST_BCD(aaa, 0x12340306, CC_A, (CC_C | CC_A)); - TEST_BCD(aaa, 0x1234040a, CC_A, (CC_C | CC_A)); - TEST_BCD(aaa, 0x123405fa, CC_A, (CC_C | CC_A)); - TEST_BCD(aaa, 0x12340205, 0, (CC_C | CC_A)); - TEST_BCD(aaa, 0x12340306, 0, (CC_C | CC_A)); - TEST_BCD(aaa, 0x1234040a, 0, (CC_C | CC_A)); - TEST_BCD(aaa, 0x123405fa, 0, (CC_C | CC_A)); - - TEST_BCD(aas, 0x12340205, CC_A, (CC_C | CC_A)); - TEST_BCD(aas, 0x12340306, CC_A, (CC_C | CC_A)); - TEST_BCD(aas, 0x1234040a, CC_A, (CC_C | CC_A)); - TEST_BCD(aas, 0x123405fa, CC_A, (CC_C | CC_A)); - TEST_BCD(aas, 0x12340205, 0, (CC_C | CC_A)); - TEST_BCD(aas, 0x12340306, 0, (CC_C | CC_A)); - TEST_BCD(aas, 0x1234040a, 0, (CC_C | CC_A)); - TEST_BCD(aas, 0x123405fa, 0, (CC_C | CC_A)); - - TEST_BCD(aam, 0x12340547, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)); - TEST_BCD(aad, 0x12340407, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)); -} - -#define TEST_XCHG(op, size, opconst)\ -{\ - int op0, op1;\ - op0 = 0x12345678;\ - op1 = 0xfbca7654;\ - asm(#op " %" size "0, %" size "1" \ - : "=q" (op0), opconst (op1) \ - : "0" (op0), "1" (op1));\ - printf("%-10s A=%08x B=%08x\n",\ - #op, op0, op1);\ -} - -#define TEST_CMPXCHG(op, size, opconst, eax)\ -{\ - int op0, op1;\ - op0 = 0x12345678;\ - op1 = 0xfbca7654;\ - asm(#op " %" size "0, %" size "1" \ - : "=q" (op0), opconst (op1) \ - : "0" (op0), "1" (op1), "a" (eax));\ - printf("%-10s EAX=%08x A=%08x C=%08x\n",\ - #op, eax, op0, op1);\ -} - -void test_xchg(void) -{ - TEST_XCHG(xchgl, "", "=q"); - TEST_XCHG(xchgw, "w", "=q"); - TEST_XCHG(xchgb, "b", "=q"); - - TEST_XCHG(xchgl, "", "=m"); - TEST_XCHG(xchgw, "w", "=m"); - TEST_XCHG(xchgb, "b", "=m"); - - TEST_XCHG(xaddl, "", "=q"); - TEST_XCHG(xaddw, "w", "=q"); - TEST_XCHG(xaddb, "b", "=q"); - - { - int res; - res = 0x12345678; - asm("xaddl %1, %0" : "=r" (res) : "0" (res)); - printf("xaddl same res=%08x\n", res); - } - - TEST_XCHG(xaddl, "", "=m"); - TEST_XCHG(xaddw, "w", "=m"); - TEST_XCHG(xaddb, "b", "=m"); - - TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfbca7654); - TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfbca7654); - TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfbca7654); - - TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfffefdfc); - TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfffefdfc); - TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfffefdfc); - - TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfbca7654); - TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfbca7654); - TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfbca7654); - - TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfffefdfc); - TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfffefdfc); - TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfffefdfc); - - { - uint64_t op0, op1, op2; - int i, eflags; - - for(i = 0; i < 2; i++) { - op0 = 0x123456789abcd; - if (i == 0) - op1 = 0xfbca765423456; - else - op1 = op0; - op2 = 0x6532432432434; - asm("cmpxchg8b %1\n" - "pushf\n" - "popl %2\n" - : "=A" (op0), "=m" (op1), "=g" (eflags) - : "0" (op0), "m" (op1), "b" ((int)op2), "c" ((int)(op2 >> 32))); - printf("cmpxchg8b: op0=%016llx op1=%016llx CC=%02x\n", - op0, op1, eflags & CC_Z); - } - } -} - -/**********************************************/ -/* segmentation tests */ - -#include <asm/ldt.h> -#include <linux/unistd.h> -#include <linux/version.h> - -_syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount) - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 66) -#define modify_ldt_ldt_s user_desc -#endif - -uint8_t seg_data1[4096]; -uint8_t seg_data2[4096]; - -#define MK_SEL(n) (((n) << 3) | 7) - -#define TEST_LR(op, size, seg, mask)\ -{\ - int res, res2;\ - res = 0x12345678;\ - asm (op " %" size "2, %" size "0\n" \ - "movl $0, %1\n"\ - "jnz 1f\n"\ - "movl $1, %1\n"\ - "1:\n"\ - : "=r" (res), "=r" (res2) : "m" (seg), "0" (res));\ - printf(op ": Z=%d %08x\n", res2, res & ~(mask));\ -} - -/* NOTE: we use Linux modify_ldt syscall */ -void test_segs(void) -{ - struct modify_ldt_ldt_s ldt; - long long ldt_table[3]; - int res, res2; - char tmp; - struct { - uint32_t offset; - uint16_t seg; - } __attribute__((packed)) segoff; - - ldt.entry_number = 1; - ldt.base_addr = (unsigned long)&seg_data1; - ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12; - ldt.seg_32bit = 1; - ldt.contents = MODIFY_LDT_CONTENTS_DATA; - ldt.read_exec_only = 0; - ldt.limit_in_pages = 1; - ldt.seg_not_present = 0; - ldt.useable = 1; - modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ - - ldt.entry_number = 2; - ldt.base_addr = (unsigned long)&seg_data2; - ldt.limit = (sizeof(seg_data2) + 0xfff) >> 12; - ldt.seg_32bit = 1; - ldt.contents = MODIFY_LDT_CONTENTS_DATA; - ldt.read_exec_only = 0; - ldt.limit_in_pages = 1; - ldt.seg_not_present = 0; - ldt.useable = 1; - modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ - - modify_ldt(0, &ldt_table, sizeof(ldt_table)); /* read ldt entries */ -#if 0 - { - int i; - for(i=0;i<3;i++) - printf("%d: %016Lx\n", i, ldt_table[i]); - } -#endif - /* do some tests with fs or gs */ - asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1))); - - seg_data1[1] = 0xaa; - seg_data2[1] = 0x55; - - asm volatile ("fs movzbl 0x1, %0" : "=r" (res)); - printf("FS[1] = %02x\n", res); - - asm volatile ("pushl %%gs\n" - "movl %1, %%gs\n" - "gs movzbl 0x1, %0\n" - "popl %%gs\n" - : "=r" (res) - : "r" (MK_SEL(2))); - printf("GS[1] = %02x\n", res); - - /* tests with ds/ss (implicit segment case) */ - tmp = 0xa5; - asm volatile ("pushl %%ebp\n\t" - "pushl %%ds\n\t" - "movl %2, %%ds\n\t" - "movl %3, %%ebp\n\t" - "movzbl 0x1, %0\n\t" - "movzbl (%%ebp), %1\n\t" - "popl %%ds\n\t" - "popl %%ebp\n\t" - : "=r" (res), "=r" (res2) - : "r" (MK_SEL(1)), "r" (&tmp)); - printf("DS[1] = %02x\n", res); - printf("SS[tmp] = %02x\n", res2); - - segoff.seg = MK_SEL(2); - segoff.offset = 0xabcdef12; - asm volatile("lfs %2, %0\n\t" - "movl %%fs, %1\n\t" - : "=r" (res), "=g" (res2) - : "m" (segoff)); - printf("FS:reg = %04x:%08x\n", res2, res); - - TEST_LR("larw", "w", MK_SEL(2), 0x0100); - TEST_LR("larl", "", MK_SEL(2), 0x0100); - TEST_LR("lslw", "w", MK_SEL(2), 0); - TEST_LR("lsll", "", MK_SEL(2), 0); - - TEST_LR("larw", "w", 0xfff8, 0); - TEST_LR("larl", "", 0xfff8, 0); - TEST_LR("lslw", "w", 0xfff8, 0); - TEST_LR("lsll", "", 0xfff8, 0); -} - -/* 16 bit code test */ -extern char code16_start, code16_end; -extern char code16_func1; -extern char code16_func2; -extern char code16_func3; - -void test_code16(void) -{ - struct modify_ldt_ldt_s ldt; - int res, res2; - - /* build a code segment */ - ldt.entry_number = 1; - ldt.base_addr = (unsigned long)&code16_start; - ldt.limit = &code16_end - &code16_start; - ldt.seg_32bit = 0; - ldt.contents = MODIFY_LDT_CONTENTS_CODE; - ldt.read_exec_only = 0; - ldt.limit_in_pages = 0; - ldt.seg_not_present = 0; - ldt.useable = 1; - modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ - - /* call the first function */ - asm volatile ("lcall %1, %2" - : "=a" (res) - : "i" (MK_SEL(1)), "i" (&code16_func1): "memory", "cc"); - printf("func1() = 0x%08x\n", res); - asm volatile ("lcall %2, %3" - : "=a" (res), "=c" (res2) - : "i" (MK_SEL(1)), "i" (&code16_func2): "memory", "cc"); - printf("func2() = 0x%08x spdec=%d\n", res, res2); - asm volatile ("lcall %1, %2" - : "=a" (res) - : "i" (MK_SEL(1)), "i" (&code16_func3): "memory", "cc"); - printf("func3() = 0x%08x\n", res); -} - -extern char func_lret32; -extern char func_iret32; - -void test_misc(void) -{ - char table[256]; - int res, i; - - for(i=0;i<256;i++) table[i] = 256 - i; - res = 0x12345678; - asm ("xlat" : "=a" (res) : "b" (table), "0" (res)); - printf("xlat: EAX=%08x\n", res); - - asm volatile ("pushl %%cs ; call %1" - : "=a" (res) - : "m" (func_lret32): "memory", "cc"); - printf("func_lret32=%x\n", res); - - asm volatile ("pushfl ; pushl %%cs ; call %1" - : "=a" (res) - : "m" (func_iret32): "memory", "cc"); - printf("func_iret32=%x\n", res); - - /* specific popl test */ - asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popl (%%esp) ; popl %0" - : "=g" (res)); - printf("popl esp=%x\n", res); - - /* specific popw test */ - asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popw (%%esp) ; addl $2, %%esp ; popl %0" - : "=g" (res)); - printf("popw esp=%x\n", res); -} - -uint8_t str_buffer[4096]; - -#define TEST_STRING1(OP, size, DF, REP)\ -{\ - int esi, edi, eax, ecx, eflags;\ -\ - esi = (long)(str_buffer + sizeof(str_buffer) / 2);\ - edi = (long)(str_buffer + sizeof(str_buffer) / 2) + 16;\ - eax = 0x12345678;\ - ecx = 17;\ -\ - asm volatile ("pushl $0\n\t"\ - "popf\n\t"\ - DF "\n\t"\ - REP #OP size "\n\t"\ - "cld\n\t"\ - "pushf\n\t"\ - "popl %4\n\t"\ - : "=S" (esi), "=D" (edi), "=a" (eax), "=c" (ecx), "=g" (eflags)\ - : "0" (esi), "1" (edi), "2" (eax), "3" (ecx));\ - printf("%-10s ESI=%08x EDI=%08x EAX=%08x ECX=%08x EFL=%04x\n",\ - REP #OP size, esi, edi, eax, ecx,\ - eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));\ -} - -#define TEST_STRING(OP, REP)\ - TEST_STRING1(OP, "b", "", REP);\ - TEST_STRING1(OP, "w", "", REP);\ - TEST_STRING1(OP, "l", "", REP);\ - TEST_STRING1(OP, "b", "std", REP);\ - TEST_STRING1(OP, "w", "std", REP);\ - TEST_STRING1(OP, "l", "std", REP) - -void test_string(void) -{ - int i; - for(i = 0;i < sizeof(str_buffer); i++) - str_buffer[i] = i + 0x56; - TEST_STRING(stos, ""); - TEST_STRING(stos, "rep "); - TEST_STRING(lods, ""); /* to verify stos */ - TEST_STRING(lods, "rep "); - TEST_STRING(movs, ""); - TEST_STRING(movs, "rep "); - TEST_STRING(lods, ""); /* to verify stos */ - - /* XXX: better tests */ - TEST_STRING(scas, ""); - TEST_STRING(scas, "repz "); - TEST_STRING(scas, "repnz "); - TEST_STRING(cmps, ""); - TEST_STRING(cmps, "repz "); - TEST_STRING(cmps, "repnz "); -} - -/* VM86 test */ - -static inline void set_bit(uint8_t *a, unsigned int bit) -{ - a[bit / 8] |= (1 << (bit % 8)); -} - -static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg) -{ - return (uint8_t *)((seg << 4) + (reg & 0xffff)); -} - -static inline void pushw(struct vm86_regs *r, int val) -{ - r->esp = (r->esp & ~0xffff) | ((r->esp - 2) & 0xffff); - *(uint16_t *)seg_to_linear(r->ss, r->esp) = val; -} - -#undef __syscall_return -#define __syscall_return(type, res) \ -do { \ - return (type) (res); \ -} while (0) - -_syscall2(int, vm86, int, func, struct vm86plus_struct *, v86) - -extern char vm86_code_start; -extern char vm86_code_end; - -#define VM86_CODE_CS 0x100 -#define VM86_CODE_IP 0x100 - -void test_vm86(void) -{ - struct vm86plus_struct ctx; - struct vm86_regs *r; - uint8_t *vm86_mem; - int seg, ret; - - vm86_mem = mmap((void *)0x00000000, 0x110000, - PROT_WRITE | PROT_READ | PROT_EXEC, - MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0); - if (vm86_mem == MAP_FAILED) { - printf("ERROR: could not map vm86 memory"); - return; - } - memset(&ctx, 0, sizeof(ctx)); - - /* init basic registers */ - r = &ctx.regs; - r->eip = VM86_CODE_IP; - r->esp = 0xfffe; - seg = VM86_CODE_CS; - r->cs = seg; - r->ss = seg; - r->ds = seg; - r->es = seg; - r->fs = seg; - r->gs = seg; - r->eflags = VIF_MASK; - - /* move code to proper address. We use the same layout as a .com - dos program. */ - memcpy(vm86_mem + (VM86_CODE_CS << 4) + VM86_CODE_IP, - &vm86_code_start, &vm86_code_end - &vm86_code_start); - - /* mark int 0x21 as being emulated */ - set_bit((uint8_t *)&ctx.int_revectored, 0x21); - - for(;;) { - ret = vm86(VM86_ENTER, &ctx); - switch(VM86_TYPE(ret)) { - case VM86_INTx: - { - int int_num, ah, v; - - int_num = VM86_ARG(ret); - if (int_num != 0x21) - goto unknown_int; - ah = (r->eax >> 8) & 0xff; - switch(ah) { - case 0x00: /* exit */ - goto the_end; - case 0x02: /* write char */ - { - uint8_t c = r->edx; - putchar(c); - } - break; - case 0x09: /* write string */ - { - uint8_t c, *ptr; - ptr = seg_to_linear(r->ds, r->edx); - for(;;) { - c = *ptr++; - if (c == '$') - break; - putchar(c); - } - r->eax = (r->eax & ~0xff) | '$'; - } - break; - case 0xff: /* extension: write eflags number in edx */ - v = (int)r->edx; -#ifndef LINUX_VM86_IOPL_FIX - v &= ~0x3000; -#endif - printf("%08x\n", v); - break; - default: - unknown_int: - printf("unsupported int 0x%02x\n", int_num); - goto the_end; - } - } - break; - case VM86_SIGNAL: - /* a signal came, we just ignore that */ - break; - case VM86_STI: - break; - default: - printf("ERROR: unhandled vm86 return code (0x%x)\n", ret); - goto the_end; - } - } - the_end: - printf("VM86 end\n"); - munmap(vm86_mem, 0x110000); -} - -/* exception tests */ -#ifndef REG_EAX -#define REG_EAX EAX -#define REG_EBX EBX -#define REG_ECX ECX -#define REG_EDX EDX -#define REG_ESI ESI -#define REG_EDI EDI -#define REG_EBP EBP -#define REG_ESP ESP -#define REG_EIP EIP -#define REG_EFL EFL -#define REG_TRAPNO TRAPNO -#define REG_ERR ERR -#endif - -jmp_buf jmp_env; -int v1; -int tab[2]; - -void sig_handler(int sig, siginfo_t *info, void *puc) -{ - struct ucontext *uc = puc; - - printf("si_signo=%d si_errno=%d si_code=%d", - info->si_signo, info->si_errno, info->si_code); - printf(" si_addr=0x%08lx", - (unsigned long)info->si_addr); - printf("\n"); - - printf("trapno=0x%02x err=0x%08x", - uc->uc_mcontext.gregs[REG_TRAPNO], - uc->uc_mcontext.gregs[REG_ERR]); - printf(" EIP=0x%08x", uc->uc_mcontext.gregs[REG_EIP]); - printf("\n"); - longjmp(jmp_env, 1); -} - -void test_exceptions(void) -{ - struct modify_ldt_ldt_s ldt; - struct sigaction act; - volatile int val; - - act.sa_sigaction = sig_handler; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_SIGINFO; - sigaction(SIGFPE, &act, NULL); - sigaction(SIGILL, &act, NULL); - sigaction(SIGSEGV, &act, NULL); - sigaction(SIGBUS, &act, NULL); - sigaction(SIGTRAP, &act, NULL); - - /* test division by zero reporting */ - printf("DIVZ exception:\n"); - if (setjmp(jmp_env) == 0) { - /* now divide by zero */ - v1 = 0; - v1 = 2 / v1; - } - - printf("BOUND exception:\n"); - if (setjmp(jmp_env) == 0) { - /* bound exception */ - tab[0] = 1; - tab[1] = 10; - asm volatile ("bound %0, %1" : : "r" (11), "m" (tab[0])); - } - - printf("segment exceptions:\n"); - if (setjmp(jmp_env) == 0) { - /* load an invalid segment */ - asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 1)); - } - if (setjmp(jmp_env) == 0) { - /* null data segment is valid */ - asm volatile ("movl %0, %%fs" : : "r" (3)); - /* null stack segment */ - asm volatile ("movl %0, %%ss" : : "r" (3)); - } - - ldt.entry_number = 1; - ldt.base_addr = (unsigned long)&seg_data1; - ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12; - ldt.seg_32bit = 1; - ldt.contents = MODIFY_LDT_CONTENTS_DATA; - ldt.read_exec_only = 0; - ldt.limit_in_pages = 1; - ldt.seg_not_present = 1; - ldt.useable = 1; - modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ - - if (setjmp(jmp_env) == 0) { - /* segment not present */ - asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1))); - } - - /* test SEGV reporting */ - printf("PF exception:\n"); - if (setjmp(jmp_env) == 0) { - val = 1; - /* we add a nop to test a weird PC retrieval case */ - asm volatile ("nop"); - /* now store in an invalid address */ - *(char *)0x1234 = 1; - } - - /* test SEGV reporting */ - printf("PF exception:\n"); - if (setjmp(jmp_env) == 0) { - val = 1; - /* read from an invalid address */ - v1 = *(char *)0x1234; - } - - /* test illegal instruction reporting */ - printf("UD2 exception:\n"); - if (setjmp(jmp_env) == 0) { - /* now execute an invalid instruction */ - asm volatile("ud2"); - } - printf("lock nop exception:\n"); - if (setjmp(jmp_env) == 0) { - /* now execute an invalid instruction */ - asm volatile("lock nop"); - } - - printf("INT exception:\n"); - if (setjmp(jmp_env) == 0) { - asm volatile ("int $0xfd"); - } - if (setjmp(jmp_env) == 0) { - asm volatile ("int $0x01"); - } - if (setjmp(jmp_env) == 0) { - asm volatile (".byte 0xcd, 0x03"); - } - if (setjmp(jmp_env) == 0) { - asm volatile ("int $0x04"); - } - if (setjmp(jmp_env) == 0) { - asm volatile ("int $0x05"); - } - - printf("INT3 exception:\n"); - if (setjmp(jmp_env) == 0) { - asm volatile ("int3"); - } - - printf("CLI exception:\n"); - if (setjmp(jmp_env) == 0) { - asm volatile ("cli"); - } - - printf("STI exception:\n"); - if (setjmp(jmp_env) == 0) { - asm volatile ("cli"); - } - - printf("INTO exception:\n"); - if (setjmp(jmp_env) == 0) { - /* overflow exception */ - asm volatile ("addl $1, %0 ; into" : : "r" (0x7fffffff)); - } - - printf("OUTB exception:\n"); - if (setjmp(jmp_env) == 0) { - asm volatile ("outb %%al, %%dx" : : "d" (0x4321), "a" (0)); - } - - printf("INB exception:\n"); - if (setjmp(jmp_env) == 0) { - asm volatile ("inb %%dx, %%al" : "=a" (val) : "d" (0x4321)); - } - - printf("REP OUTSB exception:\n"); - if (setjmp(jmp_env) == 0) { - asm volatile ("rep outsb" : : "d" (0x4321), "S" (tab), "c" (1)); - } - - printf("REP INSB exception:\n"); - if (setjmp(jmp_env) == 0) { - asm volatile ("rep insb" : : "d" (0x4321), "D" (tab), "c" (1)); - } - - printf("HLT exception:\n"); - if (setjmp(jmp_env) == 0) { - asm volatile ("hlt"); - } - - printf("single step exception:\n"); - val = 0; - if (setjmp(jmp_env) == 0) { - asm volatile ("pushf\n" - "orl $0x00100, (%%esp)\n" - "popf\n" - "movl $0xabcd, %0\n" - "movl $0x0, %0\n" : "=m" (val) : : "cc", "memory"); - } - printf("val=0x%x\n", val); -} - -/* specific precise single step test */ -void sig_trap_handler(int sig, siginfo_t *info, void *puc) -{ - struct ucontext *uc = puc; - printf("EIP=0x%08x\n", uc->uc_mcontext.gregs[REG_EIP]); -} - -const uint8_t sstep_buf1[4] = { 1, 2, 3, 4}; -uint8_t sstep_buf2[4]; - -void test_single_step(void) -{ - struct sigaction act; - volatile int val; - int i; - - val = 0; - act.sa_sigaction = sig_trap_handler; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_SIGINFO; - sigaction(SIGTRAP, &act, NULL); - asm volatile ("pushf\n" - "orl $0x00100, (%%esp)\n" - "popf\n" - "movl $0xabcd, %0\n" - - /* jmp test */ - "movl $3, %%ecx\n" - "1:\n" - "addl $1, %0\n" - "decl %%ecx\n" - "jnz 1b\n" - - /* movsb: the single step should stop at each movsb iteration */ - "movl $sstep_buf1, %%esi\n" - "movl $sstep_buf2, %%edi\n" - "movl $0, %%ecx\n" - "rep movsb\n" - "movl $3, %%ecx\n" - "rep movsb\n" - "movl $1, %%ecx\n" - "rep movsb\n" - - /* cmpsb: the single step should stop at each cmpsb iteration */ - "movl $sstep_buf1, %%esi\n" - "movl $sstep_buf2, %%edi\n" - "movl $0, %%ecx\n" - "rep cmpsb\n" - "movl $4, %%ecx\n" - "rep cmpsb\n" - - /* getpid() syscall: single step should skip one - instruction */ - "movl $20, %%eax\n" - "int $0x80\n" - "movl $0, %%eax\n" - - /* when modifying SS, trace is not done on the next - instruction */ - "movl %%ss, %%ecx\n" - "movl %%ecx, %%ss\n" - "addl $1, %0\n" - "movl $1, %%eax\n" - "movl %%ecx, %%ss\n" - "jmp 1f\n" - "addl $1, %0\n" - "1:\n" - "movl $1, %%eax\n" - "pushl %%ecx\n" - "popl %%ss\n" - "addl $1, %0\n" - "movl $1, %%eax\n" - - "pushf\n" - "andl $~0x00100, (%%esp)\n" - "popf\n" - : "=m" (val) - : - : "cc", "memory", "eax", "ecx", "esi", "edi"); - printf("val=%d\n", val); - for(i = 0; i < 4; i++) - printf("sstep_buf2[%d] = %d\n", i, sstep_buf2[i]); -} - -/* self modifying code test */ -uint8_t code[] = { - 0xb8, 0x1, 0x00, 0x00, 0x00, /* movl $1, %eax */ - 0xc3, /* ret */ -}; - -asm("smc_code2:\n" - "movl 4(%esp), %eax\n" - "movl %eax, smc_patch_addr2 + 1\n" - "nop\n" - "nop\n" - "nop\n" - "nop\n" - "nop\n" - "nop\n" - "nop\n" - "nop\n" - "smc_patch_addr2:\n" - "movl $1, %eax\n" - "ret\n"); - -typedef int FuncType(void); -extern int smc_code2(int); -void test_self_modifying_code(void) -{ - int i; - - printf("self modifying code:\n"); - printf("func1 = 0x%x\n", ((FuncType *)code)()); - for(i = 2; i <= 4; i++) { - code[1] = i; - printf("func%d = 0x%x\n", i, ((FuncType *)code)()); - } - - /* more difficult test : the modified code is just after the - modifying instruction. It is forbidden in Intel specs, but it - is used by old DOS programs */ - for(i = 2; i <= 4; i++) { - printf("smc_code2(%d) = %d\n", i, smc_code2(i)); - } -} - -int enter_stack[4096]; - -#define TEST_ENTER(size, stack_type, level)\ -{\ - int esp_save, esp_val, ebp_val, ebp_save, i;\ - stack_type *ptr, *stack_end, *stack_ptr;\ - memset(enter_stack, 0, sizeof(enter_stack));\ - stack_end = stack_ptr = (stack_type *)(enter_stack + 4096);\ - ebp_val = (long)stack_ptr;\ - for(i=1;i<=32;i++)\ - *--stack_ptr = i;\ - esp_val = (long)stack_ptr;\ - asm("movl %%esp, %[esp_save]\n"\ - "movl %%ebp, %[ebp_save]\n"\ - "movl %[esp_val], %%esp\n"\ - "movl %[ebp_val], %%ebp\n"\ - "enter" size " $12, $" #level "\n"\ - "movl %%esp, %[esp_val]\n"\ - "movl %%ebp, %[ebp_val]\n"\ - "movl %[esp_save], %%esp\n"\ - "movl %[ebp_save], %%ebp\n"\ - : [esp_save] "=r" (esp_save),\ - [ebp_save] "=r" (ebp_save),\ - [esp_val] "=r" (esp_val),\ - [ebp_val] "=r" (ebp_val)\ - : "[esp_val]" (esp_val),\ - "[ebp_val]" (ebp_val));\ - printf("level=%d:\n", level);\ - printf("esp_val=0x%08lx\n", esp_val - (long)stack_end);\ - printf("ebp_val=0x%08lx\n", ebp_val - (long)stack_end);\ - for(ptr = (stack_type *)esp_val; ptr < stack_end; ptr++)\ - printf("%08x\n", ptr[0]);\ -} - -static void test_enter(void) -{ - TEST_ENTER("l", uint32_t, 0); - TEST_ENTER("l", uint32_t, 1); - TEST_ENTER("l", uint32_t, 2); - TEST_ENTER("l", uint32_t, 31); - - TEST_ENTER("w", uint16_t, 0); - TEST_ENTER("w", uint16_t, 1); - TEST_ENTER("w", uint16_t, 2); - TEST_ENTER("w", uint16_t, 31); -} - - -static void *call_end __init_call = NULL; - -int main(int argc, char **argv) -{ - void **ptr; - void (*func)(void); - - ptr = &call_start + 1; - while (*ptr != NULL) { - func = *ptr++; - func(); - } - test_bsx(); - test_mul(); - test_jcc(); - test_floats(); - test_bcd(); - test_xchg(); - test_string(); - test_misc(); - test_lea(); - test_segs(); - test_code16(); - test_vm86(); - test_exceptions(); - test_self_modifying_code(); - test_single_step(); - test_enter(); - return 0; -} diff --git a/tools/ioemu/tests/test-i386.h b/tools/ioemu/tests/test-i386.h deleted file mode 100644 index 7d1812c883..0000000000 --- a/tools/ioemu/tests/test-i386.h +++ /dev/null @@ -1,131 +0,0 @@ - -#define exec_op glue(exec_, OP) -#define exec_opl glue(glue(exec_, OP), l) -#define exec_opw glue(glue(exec_, OP), w) -#define exec_opb glue(glue(exec_, OP), b) - -#define EXECOP2(size, res, s1, flags) \ - asm ("push %4\n\t"\ - "popf\n\t"\ - stringify(OP) size " %" size "2, %" size "0\n\t" \ - "pushf\n\t"\ - "popl %1\n\t"\ - : "=q" (res), "=g" (flags)\ - : "q" (s1), "0" (res), "1" (flags)); - -#define EXECOP1(size, res, flags) \ - asm ("push %3\n\t"\ - "popf\n\t"\ - stringify(OP) size " %" size "0\n\t" \ - "pushf\n\t"\ - "popl %1\n\t"\ - : "=q" (res), "=g" (flags)\ - : "0" (res), "1" (flags)); - -#ifdef OP1 -void exec_opl(int s0, int s1, int iflags) -{ - int res, flags; - res = s0; - flags = iflags; - EXECOP1("", res, flags); - printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n", - stringify(OP) "l", s0, res, iflags, flags & CC_MASK); -} - -void exec_opw(int s0, int s1, int iflags) -{ - int res, flags; - res = s0; - flags = iflags; - EXECOP1("w", res, flags); - printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n", - stringify(OP) "w", s0, res, iflags, flags & CC_MASK); -} - -void exec_opb(int s0, int s1, int iflags) -{ - int res, flags; - res = s0; - flags = iflags; - EXECOP1("b", res, flags); - printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n", - stringify(OP) "b", s0, res, iflags, flags & CC_MASK); -} -#else -void exec_opl(int s0, int s1, int iflags) -{ - int res, flags; - res = s0; - flags = iflags; - EXECOP2("", res, s1, flags); - printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n", - stringify(OP) "l", s0, s1, res, iflags, flags & CC_MASK); -} - -void exec_opw(int s0, int s1, int iflags) -{ - int res, flags; - res = s0; - flags = iflags; - EXECOP2("w", res, s1, flags); - printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n", - stringify(OP) "w", s0, s1, res, iflags, flags & CC_MASK); -} - -void exec_opb(int s0, int s1, int iflags) -{ - int res, flags; - res = s0; - flags = iflags; - EXECOP2("b", res, s1, flags); - printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n", - stringify(OP) "b", s0, s1, res, iflags, flags & CC_MASK); -} -#endif - -void exec_op(int s0, int s1) -{ - exec_opl(s0, s1, 0); - exec_opw(s0, s1, 0); - exec_opb(s0, s1, 0); -#ifdef OP_CC - exec_opl(s0, s1, CC_C); - exec_opw(s0, s1, CC_C); - exec_opb(s0, s1, CC_C); -#endif -} - -void glue(test_, OP)(void) -{ - exec_op(0x12345678, 0x812FADA); - exec_op(0x12341, 0x12341); - exec_op(0x12341, -0x12341); - exec_op(0xffffffff, 0); - exec_op(0xffffffff, -1); - exec_op(0xffffffff, 1); - exec_op(0xffffffff, 2); - exec_op(0x7fffffff, 0); - exec_op(0x7fffffff, 1); - exec_op(0x7fffffff, -1); - exec_op(0x80000000, -1); - exec_op(0x80000000, 1); - exec_op(0x80000000, -2); - exec_op(0x12347fff, 0); - exec_op(0x12347fff, 1); - exec_op(0x12347fff, -1); - exec_op(0x12348000, -1); - exec_op(0x12348000, 1); - exec_op(0x12348000, -2); - exec_op(0x12347f7f, 0); - exec_op(0x12347f7f, 1); - exec_op(0x12347f7f, -1); - exec_op(0x12348080, -1); - exec_op(0x12348080, 1); - exec_op(0x12348080, -2); -} - -void *glue(_test_, OP) __init_call = glue(test_, OP); - -#undef OP -#undef OP_CC diff --git a/tools/ioemu/tests/test_path.c b/tools/ioemu/tests/test_path.c deleted file mode 100644 index a9b52de378..0000000000 --- a/tools/ioemu/tests/test_path.c +++ /dev/null @@ -1,152 +0,0 @@ -/* Test path override code */ -#define _GNU_SOURCE -#include "../path.c" -#include <stdarg.h> -#include <sys/stat.h> -#include <fcntl.h> - -/* Any log message kills the test. */ -void gemu_log(const char *fmt, ...) -{ - va_list ap; - - fprintf(stderr, "FATAL: "); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - exit(1); -} - -#define NO_CHANGE(_path) \ - do { \ - if (strcmp(path(_path), _path) != 0) return __LINE__; \ - } while(0) - -#define CHANGE_TO(_path, _newpath) \ - do { \ - if (strcmp(path(_path), _newpath) != 0) return __LINE__; \ - } while(0) - -static void cleanup(void) -{ - unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE"); - unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE2"); - unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE3"); - unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE4"); - unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE5"); - rmdir("/tmp/qemu-test_path/DIR1/DIR2"); - rmdir("/tmp/qemu-test_path/DIR1/DIR3"); - rmdir("/tmp/qemu-test_path/DIR1"); - rmdir("/tmp/qemu-test_path"); -} - -static unsigned int do_test(void) -{ - if (mkdir("/tmp/qemu-test_path", 0700) != 0) - return __LINE__; - - if (mkdir("/tmp/qemu-test_path/DIR1", 0700) != 0) - return __LINE__; - - if (mkdir("/tmp/qemu-test_path/DIR1/DIR2", 0700) != 0) - return __LINE__; - - if (mkdir("/tmp/qemu-test_path/DIR1/DIR3", 0700) != 0) - return __LINE__; - - if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE", 0600)) != 0) - return __LINE__; - - if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE2", 0600)) != 0) - return __LINE__; - - if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE3", 0600)) != 0) - return __LINE__; - - if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE4", 0600)) != 0) - return __LINE__; - - if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE5", 0600)) != 0) - return __LINE__; - - init_paths("/tmp/qemu-test_path"); - - NO_CHANGE("/tmp"); - NO_CHANGE("/tmp/"); - NO_CHANGE("/tmp/qemu-test_path"); - NO_CHANGE("/tmp/qemu-test_path/"); - NO_CHANGE("/tmp/qemu-test_path/D"); - NO_CHANGE("/tmp/qemu-test_path/DI"); - NO_CHANGE("/tmp/qemu-test_path/DIR"); - NO_CHANGE("/tmp/qemu-test_path/DIR1"); - NO_CHANGE("/tmp/qemu-test_path/DIR1/"); - - NO_CHANGE("/D"); - NO_CHANGE("/DI"); - NO_CHANGE("/DIR"); - NO_CHANGE("/DIR2"); - NO_CHANGE("/DIR1."); - - CHANGE_TO("/DIR1", "/tmp/qemu-test_path/DIR1"); - CHANGE_TO("/DIR1/", "/tmp/qemu-test_path/DIR1"); - - NO_CHANGE("/DIR1/D"); - NO_CHANGE("/DIR1/DI"); - NO_CHANGE("/DIR1/DIR"); - NO_CHANGE("/DIR1/DIR1"); - - CHANGE_TO("/DIR1/DIR2", "/tmp/qemu-test_path/DIR1/DIR2"); - CHANGE_TO("/DIR1/DIR2/", "/tmp/qemu-test_path/DIR1/DIR2"); - - CHANGE_TO("/DIR1/DIR3", "/tmp/qemu-test_path/DIR1/DIR3"); - CHANGE_TO("/DIR1/DIR3/", "/tmp/qemu-test_path/DIR1/DIR3"); - - NO_CHANGE("/DIR1/DIR2/F"); - NO_CHANGE("/DIR1/DIR2/FI"); - NO_CHANGE("/DIR1/DIR2/FIL"); - NO_CHANGE("/DIR1/DIR2/FIL."); - - CHANGE_TO("/DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); - CHANGE_TO("/DIR1/DIR2/FILE2", "/tmp/qemu-test_path/DIR1/DIR2/FILE2"); - CHANGE_TO("/DIR1/DIR2/FILE3", "/tmp/qemu-test_path/DIR1/DIR2/FILE3"); - CHANGE_TO("/DIR1/DIR2/FILE4", "/tmp/qemu-test_path/DIR1/DIR2/FILE4"); - CHANGE_TO("/DIR1/DIR2/FILE5", "/tmp/qemu-test_path/DIR1/DIR2/FILE5"); - - NO_CHANGE("/DIR1/DIR2/FILE6"); - NO_CHANGE("/DIR1/DIR2/FILE/X"); - - CHANGE_TO("/DIR1/../DIR1", "/tmp/qemu-test_path/DIR1"); - CHANGE_TO("/DIR1/../DIR1/", "/tmp/qemu-test_path/DIR1"); - CHANGE_TO("/../DIR1", "/tmp/qemu-test_path/DIR1"); - CHANGE_TO("/../DIR1/", "/tmp/qemu-test_path/DIR1"); - CHANGE_TO("/DIR1/DIR2/../DIR2", "/tmp/qemu-test_path/DIR1/DIR2"); - CHANGE_TO("/DIR1/DIR2/../DIR2/../../DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); - CHANGE_TO("/DIR1/DIR2/../DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); - - NO_CHANGE("/DIR1/DIR2/../DIR1"); - NO_CHANGE("/DIR1/DIR2/../FILE"); - - CHANGE_TO("/./DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); - CHANGE_TO("/././DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); - CHANGE_TO("/DIR1/./DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); - CHANGE_TO("/DIR1/././DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); - CHANGE_TO("/DIR1/DIR2/./FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); - CHANGE_TO("/DIR1/DIR2/././FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); - CHANGE_TO("/./DIR1/./DIR2/./FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE"); - - return 0; -} - -int main(int argc, char *argv[]) -{ - int ret; - - ret = do_test(); - cleanup(); - if (ret) { - fprintf(stderr, "test_path: failed on line %i\n", ret); - return 1; - } - return 0; -} - diff --git a/tools/ioemu/tests/testthread.c b/tools/ioemu/tests/testthread.c deleted file mode 100644 index 27e4825bc6..0000000000 --- a/tools/ioemu/tests/testthread.c +++ /dev/null @@ -1,51 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <signal.h> -#include <unistd.h> -#include <inttypes.h> -#include <pthread.h> -#include <sys/wait.h> -#include <sched.h> - -void *thread1_func(void *arg) -{ - int i; - char buf[512]; - - for(i=0;i<10;i++) { - snprintf(buf, sizeof(buf), "thread1: %d %s\n", i, (char *)arg); - write(1, buf, strlen(buf)); - usleep(100 * 1000); - } - return NULL; -} - -void *thread2_func(void *arg) -{ - int i; - char buf[512]; - for(i=0;i<20;i++) { - snprintf(buf, sizeof(buf), "thread2: %d %s\n", i, (char *)arg); - write(1, buf, strlen(buf)); - usleep(150 * 1000); - } - return NULL; -} - -void test_pthread(void) -{ - pthread_t tid1, tid2; - - pthread_create(&tid1, NULL, thread1_func, "hello1"); - pthread_create(&tid2, NULL, thread2_func, "hello2"); - pthread_join(tid1, NULL); - pthread_join(tid2, NULL); - printf("End of pthread test.\n"); -} - -int main(int argc, char **argv) -{ - test_pthread(); - return 0; -} diff --git a/tools/ioemu/texi2pod.pl b/tools/ioemu/texi2pod.pl deleted file mode 100755 index 176627e9b9..0000000000 --- a/tools/ioemu/texi2pod.pl +++ /dev/null @@ -1,428 +0,0 @@ -#! /usr/bin/perl -w - -# Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. - -# This file is part of GNU CC. - -# GNU CC is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# GNU CC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with GNU CC; see the file COPYING. If not, write to -# the Free Software Foundation, 59 Temple Place - Suite 330, -# Boston MA 02111-1307, USA. - -# This does trivial (and I mean _trivial_) conversion of Texinfo -# markup to Perl POD format. It's intended to be used to extract -# something suitable for a manpage from a Texinfo document. - -$output = 0; -$skipping = 0; -%sects = (); -$section = ""; -@icstack = (); -@endwstack = (); -@skstack = (); -@instack = (); -$shift = ""; -%defs = (); -$fnno = 1; -$inf = ""; -$ibase = ""; - -while ($_ = shift) { - if (/^-D(.*)$/) { - if ($1 ne "") { - $flag = $1; - } else { - $flag = shift; - } - $value = ""; - ($flag, $value) = ($flag =~ /^([^=]+)(?:=(.+))?/); - die "no flag specified for -D\n" - unless $flag ne ""; - die "flags may only contain letters, digits, hyphens, dashes and underscores\n" - unless $flag =~ /^[a-zA-Z0-9_-]+$/; - $defs{$flag} = $value; - } elsif (/^-/) { - usage(); - } else { - $in = $_, next unless defined $in; - $out = $_, next unless defined $out; - usage(); - } -} - -if (defined $in) { - $inf = gensym(); - open($inf, "<$in") or die "opening \"$in\": $!\n"; - $ibase = $1 if $in =~ m|^(.+)/[^/]+$|; -} else { - $inf = \*STDIN; -} - -if (defined $out) { - open(STDOUT, ">$out") or die "opening \"$out\": $!\n"; -} - -while(defined $inf) { -while(<$inf>) { - # Certain commands are discarded without further processing. - /^\@(?: - [a-z]+index # @*index: useful only in complete manual - |need # @need: useful only in printed manual - |(?:end\s+)?group # @group .. @end group: ditto - |page # @page: ditto - |node # @node: useful only in .info file - |(?:end\s+)?ifnottex # @ifnottex .. @end ifnottex: use contents - )\b/x and next; - - chomp; - - # Look for filename and title markers. - /^\@setfilename\s+([^.]+)/ and $fn = $1, next; - /^\@settitle\s+([^.]+)/ and $tl = postprocess($1), next; - - # Identify a man title but keep only the one we are interested in. - /^\@c\s+man\s+title\s+([A-Za-z0-9-]+)\s+(.+)/ and do { - if (exists $defs{$1}) { - $fn = $1; - $tl = postprocess($2); - } - next; - }; - - # Look for blocks surrounded by @c man begin SECTION ... @c man end. - # This really oughta be @ifman ... @end ifman and the like, but such - # would require rev'ing all other Texinfo translators. - /^\@c\s+man\s+begin\s+([A-Z]+)\s+([A-Za-z0-9-]+)/ and do { - $output = 1 if exists $defs{$2}; - $sect = $1; - next; - }; - /^\@c\s+man\s+begin\s+([A-Z]+)/ and $sect = $1, $output = 1, next; - /^\@c\s+man\s+end/ and do { - $sects{$sect} = "" unless exists $sects{$sect}; - $sects{$sect} .= postprocess($section); - $section = ""; - $output = 0; - next; - }; - - # handle variables - /^\@set\s+([a-zA-Z0-9_-]+)\s*(.*)$/ and do { - $defs{$1} = $2; - next; - }; - /^\@clear\s+([a-zA-Z0-9_-]+)/ and do { - delete $defs{$1}; - next; - }; - - next unless $output; - - # Discard comments. (Can't do it above, because then we'd never see - # @c man lines.) - /^\@c\b/ and next; - - # End-block handler goes up here because it needs to operate even - # if we are skipping. - /^\@end\s+([a-z]+)/ and do { - # Ignore @end foo, where foo is not an operation which may - # cause us to skip, if we are presently skipping. - my $ended = $1; - next if $skipping && $ended !~ /^(?:ifset|ifclear|ignore|menu|iftex)$/; - - die "\@end $ended without \@$ended at line $.\n" unless defined $endw; - die "\@$endw ended by \@end $ended at line $.\n" unless $ended eq $endw; - - $endw = pop @endwstack; - - if ($ended =~ /^(?:ifset|ifclear|ignore|menu|iftex)$/) { - $skipping = pop @skstack; - next; - } elsif ($ended =~ /^(?:example|smallexample|display)$/) { - $shift = ""; - $_ = ""; # need a paragraph break - } elsif ($ended =~ /^(?:itemize|enumerate|[fv]?table)$/) { - $_ = "\n=back\n"; - $ic = pop @icstack; - } else { - die "unknown command \@end $ended at line $.\n"; - } - }; - - # We must handle commands which can cause skipping even while we - # are skipping, otherwise we will not process nested conditionals - # correctly. - /^\@ifset\s+([a-zA-Z0-9_-]+)/ and do { - push @endwstack, $endw; - push @skstack, $skipping; - $endw = "ifset"; - $skipping = 1 unless exists $defs{$1}; - next; - }; - - /^\@ifclear\s+([a-zA-Z0-9_-]+)/ and do { - push @endwstack, $endw; - push @skstack, $skipping; - $endw = "ifclear"; - $skipping = 1 if exists $defs{$1}; - next; - }; - - /^\@(ignore|menu|iftex)\b/ and do { - push @endwstack, $endw; - push @skstack, $skipping; - $endw = $1; - $skipping = 1; - next; - }; - - next if $skipping; - - # Character entities. First the ones that can be replaced by raw text - # or discarded outright: - s/\@copyright\{\}/(c)/g; - s/\@dots\{\}/.../g; - s/\@enddots\{\}/..../g; - s/\@([.!? ])/$1/g; - s/\@[:-]//g; - s/\@bullet(?:\{\})?/*/g; - s/\@TeX\{\}/TeX/g; - s/\@pounds\{\}/\#/g; - s/\@minus(?:\{\})?/-/g; - s/\\,/,/g; - - # Now the ones that have to be replaced by special escapes - # (which will be turned back into text by unmunge()) - s/&/&/g; - s/\@\{/{/g; - s/\@\}/}/g; - s/\@\@/&at;/g; - - # Inside a verbatim block, handle @var specially. - if ($shift ne "") { - s/\@var\{([^\}]*)\}/<$1>/g; - } - - # POD doesn't interpret E<> inside a verbatim block. - if ($shift eq "") { - s/</</g; - s/>/>/g; - } else { - s/</</g; - s/>/>/g; - } - - # Single line command handlers. - - /^\@include\s+(.+)$/ and do { - push @instack, $inf; - $inf = gensym(); - - # Try cwd and $ibase. - open($inf, "<" . $1) - or open($inf, "<" . $ibase . "/" . $1) - or die "cannot open $1 or $ibase/$1: $!\n"; - next; - }; - - /^\@(?:section|unnumbered|unnumberedsec|center)\s+(.+)$/ - and $_ = "\n=head2 $1\n"; - /^\@subsection\s+(.+)$/ - and $_ = "\n=head3 $1\n"; - - # Block command handlers: - /^\@itemize\s+(\@[a-z]+|\*|-)/ and do { - push @endwstack, $endw; - push @icstack, $ic; - $ic = $1; - $_ = "\n=over 4\n"; - $endw = "itemize"; - }; - - /^\@enumerate(?:\s+([a-zA-Z0-9]+))?/ and do { - push @endwstack, $endw; - push @icstack, $ic; - if (defined $1) { - $ic = $1 . "."; - } else { - $ic = "1."; - } - $_ = "\n=over 4\n"; - $endw = "enumerate"; - }; - - /^\@([fv]?table)\s+(\@[a-z]+)/ and do { - push @endwstack, $endw; - push @icstack, $ic; - $endw = $1; - $ic = $2; - $ic =~ s/\@(?:samp|strong|key|gcctabopt|option|env)/B/; - $ic =~ s/\@(?:code|kbd)/C/; - $ic =~ s/\@(?:dfn|var|emph|cite|i)/I/; - $ic =~ s/\@(?:file)/F/; - $_ = "\n=over 4\n"; - }; - - /^\@((?:small)?example|display)/ and do { - push @endwstack, $endw; - $endw = $1; - $shift = "\t"; - $_ = ""; # need a paragraph break - }; - - /^\@itemx?\s*(.+)?$/ and do { - if (defined $1) { - # Entity escapes prevent munging by the <> processing below. -# print "$ic\n"; - $_ = "\n=item $ic\<$1\>\n"; - } else { - $_ = "\n=item $ic\n"; - $ic =~ y/A-Ya-y/B-Zb-z/; - $ic =~ s/(\d+)/$1 + 1/eg; - } - }; - - $section .= $shift.$_."\n"; -} -# End of current file. -close($inf); -$inf = pop @instack; -} - -die "No filename or title\n" unless defined $fn && defined $tl; - -$sects{NAME} = "$fn \- $tl\n"; -$sects{FOOTNOTES} .= "=back\n" if exists $sects{FOOTNOTES}; - -for $sect (qw(NAME SYNOPSIS DESCRIPTION OPTIONS ENVIRONMENT FILES - BUGS NOTES FOOTNOTES SEEALSO AUTHOR COPYRIGHT)) { - if(exists $sects{$sect}) { - $head = $sect; - $head =~ s/SEEALSO/SEE ALSO/; - print "=head1 $head\n\n"; - print scalar unmunge ($sects{$sect}); - print "\n"; - } -} - -sub usage -{ - die "usage: $0 [-D toggle...] [infile [outfile]]\n"; -} - -sub postprocess -{ - local $_ = $_[0]; - - # @value{foo} is replaced by whatever 'foo' is defined as. - while (m/(\@value\{([a-zA-Z0-9_-]+)\})/g) { - if (! exists $defs{$2}) { - print STDERR "Option $2 not defined\n"; - s/\Q$1\E//; - } else { - $value = $defs{$2}; - s/\Q$1\E/$value/; - } - } - - # Formatting commands. - # Temporary escape for @r. - s/\@r\{([^\}]*)\}/R<$1>/g; - s/\@(?:dfn|var|emph|cite|i)\{([^\}]*)\}/I<$1>/g; - s/\@(?:code|kbd)\{([^\}]*)\}/C<$1>/g; - s/\@(?:gccoptlist|samp|strong|key|option|env|command|b)\{([^\}]*)\}/B<$1>/g; - s/\@sc\{([^\}]*)\}/\U$1/g; - s/\@file\{([^\}]*)\}/F<$1>/g; - s/\@w\{([^\}]*)\}/S<$1>/g; - s/\@(?:dmn|math)\{([^\}]*)\}/$1/g; - - # Cross references are thrown away, as are @noindent and @refill. - # (@noindent is impossible in .pod, and @refill is unnecessary.) - # @* is also impossible in .pod; we discard it and any newline that - # follows it. Similarly, our macro @gol must be discarded. - - s/\(?\@xref\{(?:[^\}]*)\}(?:[^.<]|(?:<[^<>]*>))*\.\)?//g; - s/\s+\(\@pxref\{(?:[^\}]*)\}\)//g; - s/;\s+\@pxref\{(?:[^\}]*)\}//g; - s/\@noindent\s*//g; - s/\@refill//g; - s/\@gol//g; - s/\@\*\s*\n?//g; - - # @uref can take one, two, or three arguments, with different - # semantics each time. @url and @email are just like @uref with - # one argument, for our purposes. - s/\@(?:uref|url|email)\{([^\},]*)\}/<B<$1>>/g; - s/\@uref\{([^\},]*),([^\},]*)\}/$2 (C<$1>)/g; - s/\@uref\{([^\},]*),([^\},]*),([^\},]*)\}/$3/g; - - # Turn B<blah I<blah> blah> into B<blah> I<blah> B<blah> to - # match Texinfo semantics of @emph inside @samp. Also handle @r - # inside bold. - s/</</g; - s/>/>/g; - 1 while s/B<((?:[^<>]|I<[^<>]*>)*)R<([^>]*)>/B<$1>${2}B</g; - 1 while (s/B<([^<>]*)I<([^>]+)>/B<$1>I<$2>B</g); - 1 while (s/I<([^<>]*)B<([^>]+)>/I<$1>B<$2>I</g); - s/[BI]<>//g; - s/([BI])<(\s+)([^>]+)>/$2$1<$3>/g; - s/([BI])<([^>]+?)(\s+)>/$1<$2>$3/g; - - # Extract footnotes. This has to be done after all other - # processing because otherwise the regexp will choke on formatting - # inside @footnote. - while (/\@footnote/g) { - s/\@footnote\{([^\}]+)\}/[$fnno]/; - add_footnote($1, $fnno); - $fnno++; - } - - return $_; -} - -sub unmunge -{ - # Replace escaped symbols with their equivalents. - local $_ = $_[0]; - - s/</E<lt>/g; - s/>/E<gt>/g; - s/{/\{/g; - s/}/\}/g; - s/&at;/\@/g; - s/&/&/g; - return $_; -} - -sub add_footnote -{ - unless (exists $sects{FOOTNOTES}) { - $sects{FOOTNOTES} = "\n=over 4\n\n"; - } - - $sects{FOOTNOTES} .= "=item $fnno.\n\n"; $fnno++; - $sects{FOOTNOTES} .= $_[0]; - $sects{FOOTNOTES} .= "\n\n"; -} - -# stolen from Symbol.pm -{ - my $genseq = 0; - sub gensym - { - my $name = "GEN" . $genseq++; - my $ref = \*{$name}; - delete $::{$name}; - return $ref; - } -} |