Running RISCOS on QEMU

UPDATE (17/09/14): Some time after writing this, I’ve replaced the QEMU repository referenced here with a clean one without the changes needed for running RISCOS. I’ve just created another repository with the proper sources: https://github.com/slp/qemu-riscos.

Some time ago, while trying to get NetBSD to run on Efika MX Smartbook (I should write about that), I’ve decided that I would never do any serious OS development on a platform without a JTAG interface, or a working emulator. Being able to stop the execution at will, for looking at the CPU registers, or examining an arbitrary memory location, will save you a lot of hours otherwise invested in a painful trial and error cycle.

For this reason, when I’ve decided to try and do some hacking on RISCOS (and I’m not going to lie, I was attracted by their bounty program), the first option I’ve considered was trying to get it to work under QEMU. This serves a double purpose: establishing a comfortable development environment, and getting myself to know RISCOS internals and its build process.

Nowadays, in addition to other platforms, RISCOS is able to run on BeagleBoard (OMAP3) and Raspberry Pi (BCM2835). I have access to a real RPi, so being able to emulate this platform would allow me to do most part of the coding under QEMU, and then verify the results with a physical device.

The bad news is that QEMU, as is, doesn’t emulate the BCM2835 SoC. True, some people are running Raspberry Pi GNU/Linux distributions under QEMU, but this is being done with a trick, replacing the original kernel with one compiled for VersatilePB SoC, which is fully emulated under QEMU. As the userland doesn’t care much about the SoC (it just needs a platform compatible with its ABI, which it’s mostly the case, unless you’re applying some NEON/VFP3 optimizations), this approach works reasonably well. But, for this strategy to work for RISCOS, I would need to do a new port to the VersatilePB platform, and that’s a project far beyond the size of what I initially considered.

Luckily, I’ve came across the amazing work being done by Gregory Estrade to add real BCM2835 emulation on QEMU. Older versions of RISCOS did run on qemu-rpi, but recent ones refused to boot. With a bit of hacking here and there, I’ve managed to get it to boot to the Desktop, but I still needed a working pointer.

As with the real RPi, the emulated one should be able to provide an USB mouse, but with pre-EHCI interfaces, data polling for USB pointer interfaces its just too expensive, and it showed an erratic behavior. I can’t say this came to me as a surprise, as I still remember the days when the first USB mouse got introduced to x86 desktops, and how it jumped around the screen when the CPU was slightly loaded.

Thinking about this problem, I’ve remembered that QEMU also features USB Tablet emulation. A tablet always provides absolute positions for the pointer, which makes it more precise, even when working with a lower interrupt rate. After applying an ugly and crude (but working!) hack to make QEMU provide resolution adjusted values that RISCOS could properly interpret as pointer positions, I’ve finally got a working RISCOS Desktop:

riscos-qemu

Running it yourself

To be able to run RISCOS on QEMU, follow this steps:

  1. Checkout my fork of qemu-rpi, switch to the rpi branch, and build it (you’ll only need the arm-softmmu target).
  2. Grab a RISCOS for Raspberry Pi SD Card image from here: http://www.raspberrypi.org/downloads
  3. Get my patched ROM: riscos.rom. Alternatively, if you have access to a RISCOS machine and the DDE, you can download this patch and build it yourself.
  4. Uncompress both files.
  5. Launch QEMU with something like this:
    qemu-system-arm -kernel riscos.rom -initrd riscos.rom -cpu arm1176 -M raspi -sd riscos-2013-07-10-RC11.img -d guest_errors -serial stdio -device usb-kbd -device usb-tablet -usb

Stuff to be done

  • Support for USB storages. This needs some fixes on the QEMU BCM2835 USB stack.
  • Network support. This needs some of the fixes mentioned above, and extending RISCOS support for USB CDC network devices.
  • Fix some graphic glitches.

20 thoughts to “Running RISCOS on QEMU”

  1. Thanks Sergio for your great work!

    I’ve found a little (administrative) problem: I’ve created a PKGBUILD for Arch Linux which clones your Github repo and builds a package from it. To generate a version for that, I would like to use the nearest Git tag. However, when I run from within this cloned repository:

    $ git describe –tags
    v1.3.0-6277-g0d00f74

    i.e. I get a very old version tag, with a corresponding large distance from that tag.
    I’ve solved this by running:

    $ git fetch –tags git://github.com/qemu/qemu

    i.e. fetch all tags from the upstream repo. Could you please do the same and push the result to your own fork? I think this will make some other people happy, too 🙂

    1. Instead of using a tag, you should check out the “rpi” branch, which contains the changes I’ve applied for running RISCOS.

      BTW, I’m happy to see this work is useful for you.

  2. Would it be possible to provide a Windows binary for this and a patched RISCOS ROM that’s past 20-01-14, when a few bugs were fixed that resolved issues with video output?

    This looks like something that would be very useful for the JASPP project, where all the development is initially tested under emulation. The Pi in the only platform where we have to resort to using physical, which really slows development time.

    1. I think building it for Windows shouldn’t be a problem, but as of today, this emulator doesn’t provide support for network or USB storage, so you’ll probably won’t have a way for installing and testing more software.

      This is still useful for me, as I use it for testing modified ROMs, which are read from the host’s filesystem, making them easily replaceable.

      Anyway, if you think that even in this state it’ll be useful for you (i.e. because you have a way for modifying SD card images from another OS), let me know and I’ll try to build a Windows binary with a recent ROM.

      1. Thankfully, I’m testing games which are already imaged from floppies, so there’s no requirement to get files in/out once the initial SD image is created. If you can build a Windows binary, I can quickly check if games that run on a physical Pi work under QEmu emulation, which will prove if enough of the hardware is emulated.

        1. I’ve just uploaded a ZIP with a win32 patched version of QEMU and a recent ROM. You can download it from this URL:

          http://sinrega.org/wp-content/uploads/2014/02/qemu-riscos.zip

          Just extract the archive in a directory somewhere, put your SD card image in a file named “sdcard.img” inside said directory, and run “qemu-riscos.bat”.

          You’ll also need a VNC viewer, as the SDL version crashes on win32. The batch script makes QEMU listen for VNC connections on 127.0.0.1:1

          Hope this helps.

  3. Thanks for this, have just done a quick test.

    I can see RISC OS fire up in the console and the last entry is “ModuleIinit”, TightVNC refuses to connect however. VNCViewer 5.1.0 does connect, goes to a massive window and then immediately closes down. Do I need a particular VNC client?

    Should sdcard.img be an image with or without the DOS partition? I currently have it with the DOS partition.

    1. It should have the DOS partition. I’ve tried the one found at RPi site (http://downloads.raspberrypi.org/riscos_latest) and it works nicely.

      There’s a restriction, though. Due to a limitation on video emulation, the configuration on the image from the SD card should have a Desktop resolution of 1920×1080. If it tries to set any other resolution, it’ll probably crash.

  4. Do you want to drop me an eMail, instead of discussing via here. I’ve tried with the stock RC11 img and get the same results as with my sdcard.img file. As it’s working for you, the only cause of the problem must be related to the VNC client I’m using, its certainly odd that two clients do different things.

    1. Found the problem with VNC. The VNC startup parameter needs to be “-vnc 127.0.0.1::1:5900”, TightVNC then works on the standard VNC port, VNCViewer still fails though.
      What I’m seeing with TightVNC is the post screen which has hung at “init mod SDIODriver”, so there’s still a problem somewhere.

      1. You’re right, there appears to be timing issue that’s only present on win32. On my desktop computer, where I tested the windows version, it works flawlessly, but on my laptop hangs on “init mod SDIODriver” too.

        I did a quick hack, and now it works consistently on my laptop. I’ve updated the ZIP with this new build (http://sinrega.org/wp-content/uploads/2014/02/qemu-riscos.zip). Give it a try.

        BTW, I’ve noticed the GNU/Linux build runs noticeably faster than its win32 counterpart. Running RiscOS with QEMU on GNU/Linux, even if virtualized with VirtualBox or VMware, would probably give you a better experience.

  5. Its now gets into RISC OS. Next problem, when trying most games QEmu crashes with the following error:
    File: hw/usb/bcm2835_usb.com, Line 171
    Expression: dev != NULL
    Mr Doo showed the loader page, so I think resolution changes are working okay. The missing audio stack will cause some games to crash when they call the audio SWI’s, haven’t got that far yet though. RISC OS is only seeing 64mb of RAM, it really needs 256mb at least.
    Impressive so far though. What date RISC OS ROM did you modify, was it the latest alpha?

    1. I’ve seen that assertion fail a few times. It usually means that some code is misbehaving and trying to write on an unexpected location.

      You can set the RAM for the emulated machine to 256MB by adding “-m 256m” to the argument list on the batch file.

      I built this ROM with the BCM2835Dev source code archive from a few weeks ago.

    1. To solve the DTC dev pack problem:

      To build QEMU, it is recommended to install the following packages:
      sudo apt-get install git
      sudo apt-get install g++
      sudo apt-get install zlib1g-dev
      sudo apt-get install libtool
      sudo apt-get install libglib2.0
      sudo apt-get install libpixman-1-dev
      sudo apt-get install libfdt-dev

      With the above libraries, the QEMU configuration script should complete without problems. If some of them will not be detected, the configuration script may suggest to install additional git submodules, like dtc:
      git submodule update –init dtc

Leave a Reply

Your email address will not be published. Required fields are marked *