= QEMU = [[TOC(Developer/Simulators/QEMU, depth=2)]] You can run RTEMS in the open source processor emulator [http://www.nongnu.org/qemu/ QEMU]. The QEMU emulator runs on a number of hosts including Linux and Windows. It also supports a number of [http://www.nongnu.org/qemu/status.html processors]. = QEMU On Windows = Install the RTEMS [wiki:TBR/UserManual/MinGW_Tools_for_Windows 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 https://ftp.rtems.org/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 https://ftp.rtems.org/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 [wiki:TBR/UserManual/MinGW_Tools_for_Windows 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 (it also runs in the [wiki:RTEMS_on_Virtualbox_ VirtualBox 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 [https://ftp.rtems.org/pub/rtems/people/chrisj/grub/rtems-boot.img image] we have made by downloading it from the RTEMS ftp server. The script builds the floppy disk, the grub source as per GPL, and the boot image. Instructions on how to built the image and were run on a Fedora Core 5 Linux host can be found at [http://www.rtems.org/wiki/index.php/Building_Grub http://www.rtems.org/wiki/index.php/Building_Grub] Now we need to setup some disk drivers for Qemu: {{{ $ dd if=/dev/zero of=hda.img count=1000 $ ls -las hda.img }}} The first creates a disk and second shows you the details of the disk you just created. The default '''grub.cfg''' file will attempt to read a GRUB configuration file called '''[https://ftp.rtems.org/pub/rtems/qemu/i386-pc/rtems-grub.cfg rtems-grub.cfg]''' from the root directory of the hard-disk. 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=(hd1,1) multiboot (hd1,1)/hello/hello.exe } menuentry "RTEMS - Ticker" { set root=(hd1,1) multiboot (hd1,1)/ticker/ticker.exe } menuentry "RTEMS - Minimum" { set root=(hd1,1) multiboot (hd1,1)/minimum/minimum.exe } menuentry "RTEMS - Paranoia" { set root=(hd1,1) multiboot (hd1,1)/paranoia/paranoia.exe } menuentry "RTEMS - File IO" { set root=(hd1,1) multiboot (hd1,1)/fileio/fileio.exe } menuentry "RTEMS - Unlimited" { set root=(hd1,1) multiboot (hd1,1)/unlimited/unlimited.exe } menuentry "RTEMS - Loopback" { set root=(hd1,1) multiboot (hd1,1)/loopback/loopback.exe } menuentry "RTEMS - PPPD" { set root=(hd1,1) multiboot (hd1,1)/pppd/pppd.exe } menuentry "RTEMS - Base Mulitprocessor" { set root=(hd1,1) multiboot (hd1,1)/base_mp/base_mp.exe } menuentry "RTEMS - Base Single Processor" { set root=(hd1,1) multiboot (hd1,1)/base_sp/base_sp.exe } menuentry "RTEMS - C++ Static Constructors" { set root=(hd1,1) multiboot (hd1,1)/cdtest/cdtest.exe } menuentry "RTEMS - C++ IO Streams" { set root=(hd1,1) multiboot (hd1,1)/iostream/iostream.exe } }}} To start Qemu 0.9.1 you have to use this script: {{{ $ qemu -m 128 \ -boot a \ -fda <path to rtems-boot.img> \ -hda <path to hda.img> \ -hdb fat:. \ -append "--console=/dev/com1" \ -serial stdio \ -no-reboot \ -s }}} List of the options explained: -m 128:: sets the memory size to 128M -boot a:: boot from the floppy disk a (best option) -fda :: defines the second best floppy disk image -hda :: defines the first hard disk image -hdb fat:: says hdb is fat disk and . is the directory to make the root of that disk and '''-hdb''' is the mapping to the local disk so we can read the RTEMS executable into memory -serial stdio:: directs the serial port to the stdio of qemu -no-reboot':: tells Qemu to not reboot if the code running wants to. Stops an error looping over and over. -s:: tells Qemu to start a GDB server = "Couldn't open file" GRUB Error Message = If GRUB gives this error while trying to load a menu entry, press 'c' on the keyboard at the GRUB menu screen to open the GRUB command prompt. Then type: {{{ grub> ls }}} which should give you a list of the devices currently on the system. Try the following for every device until you find the application you want: {{{ grub> ls DEVICE/ }}} Now edit the entry that gave you the error (press 'e' at the GRUB menu screen) and correct the path. = 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 QEMU as before (or qemu.bat batch file as mentioned above (if you are running windows)). 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=(hd1,1)/ grub> multiboot (hd1,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 "multiboot (hd1,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. = Using the rtems-testing Module = The automated testing infrastructure provided by the rtems-testing (formerly gcc-testing) module can be used to run applications in QEMU. The first step is to check out rtems-testing from Git. Instructions can be found on the [wiki:Developer/Git RTEMS GIT Repository] page. {{{ git clone git://git.rtems.org/rtems-testing.git }}} Create two directories, ~/qemu and ~/qemu/hd. {{{ mkdir ~/qemu mkdir ~/qemu/hd }}} There is a qemu-support directory in rtems-testing with a boot floppy image. Copy rtems-testing/qemu-support/pc386_fda.bz2 to ~/qemu. {{{ cp ./qemu-support/pc386_fda.bz2 ~/qemu }}} Unzip (bunzip or bzip2) pc386_fda.bz2. {{{ bunzip ~/qemu/pc386_fda* }}} Run make at the root of the rtems-testing module. This should create a pc386 script in ./sim-scripts. **Warning: sim-scripts and rtems-testing is obsolete, please refer to the User Manual's Testing section** To use these scripts for pc386, you have to build RTEMS with USE_COM1_AS_CONSOLE=1 and BSP_PRESS_KEY_FOR_RESET=0 on the configure command line. For example, if rtems is checked out at /home/user/rtems/rtems and you build in /home/user/rtems/b-rtems, then from b-rtems you will configure rtems as: {{{ ../rtems/configure --target=i386-rtems4.10 \ --prefix=$INSTALL --disable-multiprocessing \ --disable-cxx --disable-rdbg \ --enable-maintainer-mode --enable-tests \ --enable-networking --enable-posix \ --disable-itron --disable-deprecated \ --disable-ada --disable-expada \ --enable-rtemsbsp=pc386 \ USE_COM1_AS_CONSOLE=1 BSP_PRESS_KEY_FOR_RESET=0 }}} **Warning: sim-scripts and rtems-testing is obsolete, please refer to the User Manual's Testing section** If you run: {{{ ./sim-script/pc386 -i PATH_TO_MY_EXE }}} The pc386 script will copy your executable to ~/qemu/hd/test.exe, which is what pc386_fda boots. You should see the result in your console. Scripts to run other simulators are in the sim-scripts directory. NOTE: If you have a means to pass command line arguments to the RTEMS executable (e.g., this works when booting with grub) then there is no need to specify the serial console at 'configure'-time. You simply add the command line argument {{{ --console=/dev/com1 }}} = Booting an RTEMS executable directly with QEMU = Qemu has a native multiboot implementation that is smart enough to load an ELF .exe into memory and transfer control to it. This makes it unnecessary to prepare a full floppy or harddisk image complete with MBR and boot loader. To use it, provide the -kernel option: {{{ qemu-system-i386 -kernel hello/hello.exe }}} The i386 supports boot options appended to the kernel to control the console, IDE probing and more. You can add options to the boot command line using the `-append` option: {{{ qemu-system-i386 -kernel hello/hello.exe \ -vga cirrus \ -net nic,vlan=0,model=e1000 -net user,vlan=0 \ -append "--console=/dev/com1" \ -serial stdio }}} = Running RTEMS TCP/IP Applications = == Intel i82557b/e100 PCI Card Emulation == The following setup has been tested on actual master (future 5.1) branch with i386 BSP on Linux host. But PCI driver should work with other architectures as well if given BSP supports PCI and is supported by QEMU. The Intel i82557b/e100 PCI NIC is supported by RTEMS [https://git.rtems.org/rtems/tree/c/src/libchip/network/if_fxp.c FXP driver]. The driver is available in classic RTEMS integrated TCP/IP stack when RTEMS build is configured with --enable-networking. Example of selecting the driver in RTEMS application: {{{ #include #include #include int rtems_fxp_attach(struct rtems_bsdnet_ifconfig *config, int attaching); static char ethernet_address[6] = {0x00, 0x04, 0x9F, 0x00, 0x27, 0x50 }; static struct rtems_bsdnet_ifconfig netdriver_config = { .name = "fxp1" /*RTEMS_BSP_NETWORK_DRIVER_NAME*/, .attach = rtems_fxp_attach /*RTEMS_BSP_NETWORK_DRIVER_ATTACH*/, .next = NULL, .ip_address = "192.168.3.66", .ip_netmask = "255.255.255.0", .hardware_address = ethernet_address /* more options can follow */ }; struct rtems_bsdnet_config rtems_bsdnet_config = { .ifconfig = &netdriver_config, .bootp = rtems_bsdnet_do_dhcp_failsafe, /* fill if DHCP is used*/ } }}} Call to rtems_bsdnet_initialize_network() starts networking. The most simple interconnection of emulated NIC to the host system networking is by `user` option. This setup result in the full NAT or better say protocol translation run by QEMU and does not require any elevated privileges for QEMU process on the host system. It has disadvantage that it is able only to repack TCP and UDP traffic to the host system network (no ICMP/ping works). Because of NAT like style this allows only to access/start connection from RTEMS to the outside world. It is not possible to connect server on RTEMS from the host system. The client (RTEMS application) is offered address 10.0.2.15 and gateway address is 10.0.2.2. Example of running QEMU with above described setup {{{ qemu-system-x86_64 -enable-kvm -kernel $APP_BINARY \ -vga cirrus \ -net nic,vlan=1,macaddr=00:04:9F:00:27:50,model=i82557b \ -net user,vlan=1 \ -append "--console=/dev/com1" \ -serial stdio }}} Substitute `$APP_BINARY` by your compiled RTEMS application image (ELF 32-bit LSB executable). Setup select serial console for RTEMS application and QEMU routes RTEMS serial to standard output. If you do not intend to work with graphic at all then use {{{ qemu-system-x86_64 -enable-kvm -kernel $APP_BINARY \ -vga cirrus \ -append "--console=/dev/com1" \ -net nic,vlan=1,macaddr=be:be:be:10:00:01,model=i82557b \ -net tap,ifname=tap1,vlan=1,script=no,downscript=no \ -nographic }}} The next example shows how to build isolates local network to communicate between the host system and RTEMS application on Linux. The example is intended for static address setup without DNS etc. But it is ideal for drivers testing and or server/protocol code testing. Setup TAP device on host side with administrator privileges (run as root). Select local address range which does not overlap with any network in your neighborhood. {{{ ip tuntap add tap1 mode tap user user_running_qemu ip link set tap1 up ip addr add 192.168.3.1/24 dev tap1 }}} Then QEMU can be run {{{ qemu-system-x86_64 -enable-kvm -kernel $APP_BINARY \ -vga cirrus \ -net nic,vlan=1,macaddr=00:04:9F:00:27:50,model=i82557b \ -net tap,ifname=tap1,vlan=1,script=no,downscript=no \ -append "--console=/dev/com1" \ -serial stdio }}} and you can connect for example to RTEMS shell by {{{ telnet 192.168.3.66 }}} for example shown in OMK RTEMS [http://rtime.felk.cvut.cz/gitweb/rtems-devel.git/tree/HEAD:/rtems-omk-template/appnet network application template]. == i386 with NE2000 ISA NIC Emulation == 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 \ -append "--console=/dev/com1" \ -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. == "isa irq 9 already assigned" == With a more recent QEMU (0.13), I needed to add the "-M isapc" flag to make this error message go away. --[wiki:User:SimonPerreault User:SimonPerreault] Mon Nov 29 16:43:38 EST 2010 == Setting the IRQ number == By default, QEMU uses IRQ 9, while RTEMS uses IRQ 5. I just hard-coded the IRQ in my struct rtems_bsdnet_ifconfig, along with the IO address (0x300) while I am at it. {{{ static struct rtems_bsdnet_ifconfig netdriver_config = { (char *)BSP_NE2000_NETWORK_DRIVER_NAME, BSP_NE2000_NETWORK_DRIVER_ATTACH, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0x300, 9, 0, NULL }; }}} --[wiki:User:SimonPerreault User:SimonPerreault] Mon Nov 29 16:43:38 EST 2010 Alternatively, you can simply add {{{ --ne2k-irq=9 }}} to the grub command line to let RTEMS' ne driver know it should use interrupt 9. = Running CAN Applications = See the [wiki:Developer/Simulators/QEMU/CANEmulation QEMU with CAN Emulation] page for more details. = 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 recognised it automatically and it worked. I could never figure out a way to get the USB flash drive recognised. 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. --[wiki:User:JoelSherrill Dr. Joel] 13:25, 10 March 2007 (CST) = QEMU and UEFI (using OVMF / EDK II) = [https://github.com/tianocore/tianocore.github.io/wiki/How-to-build-OVMF OVMF Build instructions are available here]. Duplicated for completeness: {{{ $ git clone git://github.com/tianocore/edk2.git $ cd edk2 $ make -C BaseTools $ . edksetup.sh }}} Then edit `Conf/target.txt` to set the following values: {{{ ACTIVE_PLATFORM = OvmfPkg/OvmfPkgX64.dsc TARGET = DEBUG TARGET_ARCH = X64 # You can use GCC46 as well, if you'd prefer TOOL_CHAIN_TAG = GCC5 }}} Then run `build` in the `edk2` directory - the output should list the location of the `OVMF.fd` file, which can be used with QEMU to boot into a UEFI shell [https://github.com/tianocore/tianocore.github.io/wiki/How-to-run-OVMF as instructed here]. You can find the `OVMF.fd` file like this as well in the `edk2` directory: {{{ $ find . -name "*.fd" ./Build/OvmfX64/DEBUG_GCC5/FV/MEMFD.fd ./Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd <-- the file we're looking for ./Build/OvmfX64/DEBUG_GCC5/FV/OVMF_CODE.fd ./Build/OvmfX64/DEBUG_GCC5/FV/OVMF_VARS.fd }}} And then to boot into a UEFI shell: {{{ qemu-system-x86_64 --bios /path/to/repo/edk2/Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd -net none }}} **Note:** Remember to replace the path to `OVMF.fd` with the actual path! = Emulating Other Platforms with QEMU = === PowerPC PReP Emulation === See [wiki:Developer/Simulators/QEMU/Preparation]. === Motorola Coldfire Emulation === I have this also working but need to document. --[[User:Strauman|Strauman]] 16:43, 18 July 2011 (CDT) === LEON3 Emulation === See [http://lists.rtems.org/pipermail/users/2014-September/028224.html RTEMS/LEON3 on Qemu] email thread.