VMWos -- a homebrew operating system for the Raspberry Pi


VMWos is a very small custom operating system that runs on Raspberry Pi Hardware.
You will need a USB/serial cable to do anything useful with it.

It was written in conjunction with the ECE598: Advanced Operating Systems class that I teach at the University of Maine (Spring 2015/2016/2018).

Current Release

The current release is 0.20 (released 21 February 2020)
You can view the CHANGELOG.

Getting the Code

For now, you can download the code at github:
git clone http://www.github.com/deater/vmwos

I don't have any binary images, you'll have to build them (cross-compiled from Linux). Side note: the "Pi on Fire" demo is a version of vmwOS and binaries of that exist if you really want to try w/o building your own.

To run it you'll need to build "kernel.img" or "kernel7.img" and copy the file over that file under /boot on a pre-existing Raspbian image.

Supported Features

Missing Features

Supported Hardware




There isn't much. If you are interested in some more details on the implementation and future plans you can check out our paper about this at MEMSYS'18.

"A Raspberry Pi Operating System for Exploring Advanced Memory System Concepts"

You can find that paper at my research website.

Screenshots and News

28 February 2020

Was working on stdin/stdout redirection (and the dup2() syscall). To get cat to work I have to implemented ICANON cannonical term support, which is an amazing piece of unnecessarily complicated backwards compatability.

Midway through this I reached feature-parity with the Unixes of my youth, as suddenly backspace wasn't working.

21 February 2020

Version 0.20 was finally released!

The VFS (virtual filesystem layer) is more or less complete. There is full abstraction of the filesystem layer, with two filesystems currently supported: romfs (read-only) and the Apple II DOS3.3 filesystem with full write support.

In addition, proper block and character device support was added. Currently ramdisk is the only block device and the console the only character device, but the infrastructure is there for more. You can open raw block devices, and you can use fcntl() to make stdin non-blocking for games.

During this development a lot of utilities were added, and many fixes were made to userspace programs and vlibc.

You can see a video demoing the new functionality here (sorry for the weird timing in the video, vokoscreen and kdenlive don't work well together and I don't have time to go back and re-do the video).

25 January 2020

Spent the week adding a VFS abstraction layer (virtual filesystem) with the goal of allowing modular file system support. Major re-write of file handling, fixing some bugs along the way. Will make things easier, but the 6502 coder in me hates taking a block_read() call and replacing it with something like file->inode->sb->block.ops->read().

15 January 2020

Fixed some more bugs with editor which were primarily in vlibc. Including one really bad memmove() issue that is probably the reason the framebuffer console was so unstable. The memory corruption bug was indeed due to the bss being corrupted (the relocations were accidentally being written there).

14 January 2020

Working on getting a simple editor going. Used the kilo-based example here. This led to fixing up vlibc (fixing various bugs [mostly in printf], but also adding bare-bones malloc() support.

Also the syntax-highlighting had complex enough C that gcc kept generating relocated variables, so this led to getting relocation of bFLT variables at load-time going.

That all mostly seems to work, but now the editor is crashing again for reasons that seem unrelated. The heap and/or bss is getting corrupted somehow and it's trying to dereference a string.

9 November 2019

The Pi On Fire Demo using VMWos won 2nd place in the modern demo competition at Demosplash.

30 October 2019

Work on a demoscene demo that will run on vmwos! Because of this some changes have been made. Full background 44.1kHz/16-bit audio playing is now supported via DMA. There is now a syscall to sync a framebuffer (so graphics can be done from userspace). Also floating point is now enabled by the kernel (though userspace by default doesn't use it).

6 October 2018

A paper about vmwOS won the "Chair's Choice" award at the MEMSYS'18 conference. You can read the paper here.

15 May 2018

When trying to debug a student project ended up adding minimal PWM audio support. For now all it does is beep (though you can use control-G to make the beep happen).

This was a pain, as the PWM interface is not documented well.

12 April 2018

Work in progress on multicore support. It actually can start all four CPUs, but I don't have locks in the console so the output gets all run together.

6 April 2018

Have framebuffer support mostly working again (though still slow). Amazingly works on pi3, despite the fact I can't get the temperature/mailbox to work still.

27 March 2018

Pi-3B+ support added.

25 March 2018

Have MMU memory protection (kernel vs user) finally working, at least on Pi3. Having issues with enabling cache on the Pi3 though.

23 March 2018

Have bflt binary support finally working.

7 March 2018

Code should now work on both Pi2 and Pi3 models now. You might need recent firmware on all models, as it assumes a 48MHz UART clock now.

A huge host of changes had to be made to get it to run on the newer machines and firmware. The biggest was writing a device-tree parser.

There was also a really tricky to debug issue where the aplus DRAM was initializing to zero but the pi3 was initializing to 555555 and some code was accidentally being setup properly due to this.

20 May 2016

Finally have blocking I/O working! Look at this sysinfo update, notice that the system is spending most of its time in the idle thread. This is because console_read() and sleep() both block, putting processes to sleep and the idle thread finally gets to run.

Here's a before shot showing that it didn't idle previously. Also note that we leak memory and processes (i.e. processes aren't freed after an exit() ). Need to fix that.

17 May 2016

Finally implemented enough syscalls (and subdirectory support) that ll now runs under my OS. Had to manually generate PIC assembly code, which wasn't fun.

13 May 2016

Demo of the 0.13 release in action:

Relive the 1990s: the framebuffer console has been extensively tested and supports enough ANSI control characters to display most BBS ANSI art.

April 2015

Version 0.10 showing classic AB multitasking support:

An EeePC acting as a terminal for a Raspberry Pi Model A+ running VMWos:

The local royalty was unimpressed by the A/B multitasking demo:

Performance Numbers

Some results when trying to get maximum memset() performance.

Raspberry Pi A+/B BCM2835 700MHz LPDDR2 RAM

Each test is 16 repetitions of a 1MB memset()

1-byte is just a simple loop, one byte at a time.
4-byte is a simple loop, writing an int at a time.
64-byte uses the arm "stm" instruction to write 64B at a time.
No Cache C 1-byte 936754552 1.338s 12.0 MB/s
L1-I$ C 1-byte 355098645 0.507s 31.5 MB/s
L1-I$+brpred C 1-byte 271038891 0.387s 41.3 MB/s
L1-I$+brpred+D$C 1-byte 116346597 0.166s 96.3 MB/s
No Cache C 4-byte 205749402 0.294s 54.4 MB/s
L1-I$ C 4-byte 67745267 0.097s 165 MB/s
L1-I$+brpred C 4-byte 63533353 0.091s 176 MB/s
L1-I$+brpred+D$C 4-byte 28633484 0.041s 391 MB/s
No Cache ASM 64B 23437080 0.0335s 478 MB/s
L1-I$ ASM 64B 17749501 0.0253s 631 MB/s
L1-I$+brpred ASM 64B 18006681 0.0257s 622 MB/s
L1-I$+brpred+D$ ASM 64B 8829849 0.0126s 1268 MB/s
Theoretical Maximum speed of LPDDR2@400MHZ = 8GB/s
Linux glibc memset() maxes out around 1400 MB/s

Back to the VMW Software Productions website