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:
Running it yourself
To be able to run RISCOS on QEMU, follow this steps:
- Checkout my fork of qemu-rpi, switch to the rpi branch, and build it (you’ll only need the arm-softmmu target).
- Grab a RISCOS for Raspberry Pi SD Card image from here: http://www.raspberrypi.org/downloads
- Get my patched ROM: riscos.rom. Alternatively, if you have access to a RISCOS machine and the DDE, you can download
this patchand build it yourself.
- Uncompress both files.
- 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.