wiki:Developer/Simulators/QEMU

Version 26 (modified by JoelSherrill, on Jul 18, 2008 at 9:12:08 PM) (diff)

/* Running RTEMS TCP/IP Applications */ New text

QEMU

You can run RTEMS in the open source processor emulator QEMU. The QEMU emulator runs on a number of hosts including Linux and Windows. It also supports a number of processors.

QEMU On Windows

Install the RTEMS MinGW Tools for Windows. Download the processor emulator you wish to use and install. For example we will install the i368 emulator to c:\rtems\i386\qemu-0.8.2-windows. Download the boot floppy image http://www.rtems.org/ftp/pub/rtems/qemu/i386-pc/rtems-boot.img to c:\rtems\i386. To run QEMU create the batch file c:\rtems\i386\qemu.bat with:

rem @echo off set QEMU=C:\rtems\i386\qemu-0.8.2-windows %QEMU%\qemu -L %QEMU% -m 128 -boot a -fda c:\rtems\i386\rtems-boot.img -hda fat:%1

You can download this batch file from http://www.rtems.org/ftp/pub/rtems/qemu/i386-pc/qemu.bat.

The boot floppy will look in the root directory the QEMU C: drive for a file called rtems-grub.cfg. The QEMU C: is a directory on your hard disk passed to QEMU on its command line and can be seen in the qemu.bat file we created as the -hda fat:%1 option. The command line option we pass to qemu.bat is a directory that is the root directory the QEMU C: drive. For example download and build RTEMS for the i386 target as described on the MinGW Tools for Windows page. Then install http://www.rtems.org/ftp/pub/rtems/qemu/i386-pc/rtems-grub.cfg into the c:\rtems\src\i386\i386-rtems4.7\c\pc586\testsuites\samples directory. Open the RTEMS (i386) command window by running c:\rtems\i386\rtems-cmd.bat then enter:

RTEMS(i386) C:\rtems\i386>qemu c:\rtems\src\i386\i386-rtems4.7\c\pc586\testsuites\samples

The QEMU windows will open and GRUB will provide you with a menu of the RTEMS sample applications. Select an application and watch it run.

QEMU PC (i386) Emulator

The RTEMS PC BSP runs in the QEMU emulator. The QEMU emulator needs a boot image that will load RTEMS and we use GRUB for this. The simplest may to do this is to create a floppy disk image and tell QEMU to boot from a floppy disk.

Making a Boot Floppy Disk

We run RTEMS in QEMU by first booting from a floppy disk image containing the GRUB boot loader. You can use the image we have made by downloading it from the RTEMS ftp server. The following instructions built the image and were run on a Fedora Core 5 Linux host.

Download the latest release of version 2 the Grub boot loader from ftp://alpha.gnu.org/gnu/grub/. Build the package with the following configure command:

$ ../grub-1.94/configure --prefix=/tmp/g2/build $ make all install

where the prefix can be anything suitable for your machine. If configure fails with a missing LZO library check you have the lzo-devel package installed.

To make the floppy image follow the instructions in the Grub Wiki at http://grub.enbug.org/TestingOnX86. This script is adapted from the instructions:

#! /bin/sh -x grub=/tmp/g2/build workspace=/tmp/g2 mnt=$workspace/mnt/loop file=$workspace/rtems-boot.img export PATH=$grub/bin:$grub/sbin:$PATH mkdir -p $workspace cd $workspace grub-mkimage -o core.img _chain ls pc multiboot gpt fat boot reboot configfile cat help dd if=/dev/zero of=$file bs=512 count=2880 /sbin/mkdosfs $file mkdir -p $mnt mount -o loop -t vfat $file $mnt mkdir -p $mnt/boot/grub cp $grub/lib/grub/i386-pc/boot.img core.img $grub/lib/grub/i386-pc/*.mod $mnt/boot/grub echo "configfile (hd0,0)/rtems-grub.cfg" > $mnt/boot/grub/grub.cfg echo '(fd0)' $file > tmp_device.map grub-setup -d $mnt/boot/grub -r '(fd0)' -m tmp_device.map '(fd0)' rm -f tmp_device.map umount $mnt

The default grub.cfg file will attempt to read a GRUB configuration file called rtems-grub.cfg from the root directory of the harddisk. This lets you create a specific GRUB configuration for you testing without needing to rebuild the floppy image. An example configuration that lets you run the RTEMS Samples is:

# RTEMS Grub configuration for the Samples

set default=0

menuentry "RTEMS - Hello" {

set root=(hd0,0) multiboot (hd0,0)/hello/hello.exe

}

menuentry "RTEMS - Ticker" {

set root=(hd0,0) multiboot (hd0,0)/ticker/ticker.exe

}

menuentry "RTEMS - Minimum" {

set root=(hd0,0) multiboot (hd0,0)/minimum/minimum.exe

}

menuentry "RTEMS - Paranoia" {

set root=(hd0,0) multiboot (hd0,0)/paranoia/paranoia.exe

}

menuentry "RTEMS - File IO" {

set root=(hd0,0) multiboot (hd0,0)/fileio/fileio.exe

}

menuentry "RTEMS - Unlimited" {

set root=(hd0,0) multiboot (hd0,0)/unlimited/unlimited.exe

}

menuentry "RTEMS - Loopback" {

set root=(hd0,0) multiboot (hd0,0)/loopback/loopback.exe

}

menuentry "RTEMS - PPPD" {

set root=(hd0,0) multiboot (hd0,0)/pppd/pppd.exe

}

menuentry "RTEMS - Base Mulitprocessor" {

set root=(hd0,0) multiboot (hd0,0)/base_mp/base_mp.exe

}

menuentry "RTEMS - Base Single Processor" {

set root=(hd0,0) multiboot (hd0,0)/base_sp/base_sp.exe

}

menuentry "RTEMS - C++ Static Constructors" {

set root=(hd0,0) multiboot (hd0,0)/cdtest/cdtest.exe

}

menuentry "RTEMS - C++ IO Streams" {

set root=(hd0,0) multiboot (hd0,0)/iostream/iostream.exe

}

(Note: I think that all references to (hd0,0) in the script and configuration file above should be changed to (hd0,1). The GRUB partition numbering scheme used in the latest versions of GRUB now start partition numbering at 1 instead of 0.)

Running Other Images

Instead of adding menu entries to the rtems-grub.cfg file, you can instead boot an RTEMS image directly from the GRUB command prompt.

Run the qemu.bat batch file as mentioned above. At the GRUB menu screen, press 'c' on the keyboard to switch from the menu to the GRUB command prompt. At the prompt type:

grub> set root=(hd0,1) grub> multiboot (hd0,1)/myimage.exe

where myimage.exe should be replaced with the name of the RTEMS image that you want to run. GRUB supports filename completion via the TAB key, so you can just type "kernel (hd0,1)/" and then press the TAB key to see a list of all files and directories.

Then just type

grub> boot

to load and run your image.

Running RTEMS TCP/IP Applications

You can run RTEMS applications that use TCP/IP on QEMU. It requires getting a few very picky things just right so hang on and this section should help. The RTEMS application running on QEMU is executing on a virtual machine and thus QEMU must provide a simulation of a real NIC whose I/O is relayed or tunneled through a virtual interface to the real world. For most testing purposes, it is sufficient to have the connection work between just your QEMU session and the host computer running QEMU. AFAIK, for this to work, you must execute qemu as root. In all other cases of running QEMU with RTEMS, you can be a regular user. So the lesson here is only turn on TCP/IP support in QEMU when you really need it.

This is the script I use to start QEMU 0.9.1 with networking enabled:

qemu -cpu 486 -m 8 -boot a \
    -fda /home/joel/qemu/pc386_fda \
    -hda fat:/home/joel/qemu/hd \
    -net nic,macaddr=00:80:7F:22:61:77,model=ne2k_isa \
    -net tap,script=/etc/qemu-ifup  \
    -serial stdio --no-reboot

This says you are simulating an i486 CPU, booting from the floppy image /home/joel/qemu/pc386_fda and using the directory /home/joel/qemu/hd as the HDA presented to the QEMU session as a FAT filesystem. In my case, the floppy has GRUB on and always boots quickly to run the file test.exe from HDA. This is done to assist in automating test execution. All the script has to do it copy an executable to /home/joel/qemu/hd/test.exe and it will quickly run.

This RTEMS BSP is built with the console redirected to COM1 so -serial stdio ensures that the COM1 output goes to stdout. This makes it easier to redirect the output.

The QEMU session is configured to have a single NIC which is a Novell NE2000 ISA NIC with the specified MAC address. This matches the configuration used by the file network-demos/networkconfig-qemu.h from RTEMS. The network uses a GNU/Linux tap interface per the QEMU documentation. You may have to do a modprobe tap command to get this to work and you will definitely have to have the script /etc/qemu-ifup with the following contents.

#!/bin/sh
TUN_DEV=$1
TUN_HOST=10.0.2.2
/sbin/ifconfig $TUN_DEV $TUN_HOST
exit 0

This matches the defaults as presented in the QEMU manual. The single network interface available to the RTEMS application will have the IP address 10.0.2.5. All of the RTEMS network demos can run in this environment given proper configuration.

Debugging with QEMU

You can connect a debugger to QEMU and debug your application. If you start QEMU and load your application then switch consoles by pressing Ctl-Alt-2 to the QEMU command console then enter the command gdbserver. After this start gdb for your target with the ELF image for the execute. Once gdb has started enter the remote target command for localhost:1234. On Windows with and the i386 target the commands are:

RTEMS(i386) C:\rtems\src\i386\i386-rtems4.7\c\pc586\testsuites\samples\capture>i386-rtems4.7-gdb capture.elf GNU gdb 6.5 Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "--host=i686-pc-mingw32 --target=i386-rtems4.7"... (gdb) target remote localhost:1234 Remote debugging using localhost:1234 0x00115c11 in _CPU_Thread_Idle_body ()

at c:/rtems/src/rtems-4.6.99.3/cpukit/score/cpu/i386/cpu.c:92

92 asm volatile ("hlt"); (gdb) l _Exception_Handler 108 frstor (eax) /* restore FP context */ 109 ret 110 111 PUBLIC (_Exception_Handler) 112 SYM (_Exception_Handler): 113 pusha /* Push general purpose registers */ 114 pushl esp /* Push exception frame address */ 115 movl _currentExcHandler, eax /* Call function storead in _currentExcHandler */ 116 call * eax 117 addl $4, esp (gdb)

Do not forget to build RTEMS with the --enable-rtems-debug configure option to get debug information built into RTEMS.

QEMU and USB

As of 10 March 2007, RTEMS does not support USB. One of the issues in RTEMS supporting USB is finding a target BSP where it is easy to debug the USB stack initially. QEMU appears to be a viable candidate for this task. QEMU is supposed to support USB emulation and there are reports on the Internet that it does work. My experimentation was not so lucky.

Since my effort was all about making sure I knew how to setup and use QEMU's emulated USB, I used a Knoppix LiveCD image. I thought that if I could get Knoppix to access a USB mouse and a USB flash drive, I would be happy in the capabilities in QEMU.

The USB mouse emulation worked well enough that Knoppix recognized it automatically and it worked.

I could never figure out a way to get the USB flash drive recognized. There are comments that there might be a patch needed but I wasn't very confident.

I saw a report that someone got a USB GPS working with Windows XP running under QEMU (http://jw.n--tree.net/blog/dev/qemu-usb-garmin) so there must be a magic combination of things that actually make this work

So that's my report. Maybe someone can follow up and make more work.

--[[User:JoelSherrill|Dr. Joel]] 13:25, 10 March 2007 (CST)