Skip to content


Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

NUL: NOVA Userland


This is the development version of NUL, the NOVA UserLand, developed at the Operating Systems Group at TU Dresden. It complements the NOVA microhypervisor with applications, mainly a virtual machine monitor and a hardware resource multiplexer.

The code is still experimental and far from feature complete. Use it on your own risk. If it breaks, you get to keep both pieces.

Useful points of reference:

Org-Mode HOWTO

This file uses Org-Mode, which ships with a nice manual that you can find via the Info browser (C-h i). I recommend reading the 5min tutorial, if you are unfamiliar with Org-Mode:

Some hints: C-c C-t: Cycle through TODO states. C-c C-z: Take a note. TAB on section header: Cycle through visibility states. Shift-TAB: Toggle overview. C-c C-e l: Export as LaTeX. :-D


  • Binutils 2.20 or later
  • GCC 4.4.4, 4.5.2 or later
  • SCons 1.2.0 or later
  • Python 2.6 or later

Where To Get It

The latest public version of the NOVA userland is available from Github:

Hypervisor development happens also on Github:


This section is aimed at the prospective NUL hacker. Its purpose is to boot your knowledge about nul to a point where you can start hacking on it.

Directory Layout

The NUL tree consists of several applications and libraries, which are loosely grouped by topic into repositories. Each subdirectory of the top-level directory is a repository.


To build NUL you need a build directory. Luckily, there is already a preconfigured one in build. We use a minimal SCons-based build system that mostly does what we want. So to build the default configuration just cd into build and type scons. Binaries will be installed in build/bin and build/boot by default.

To use a customized build configuration, copy the default build repository and adapt its SConstruct file.

There are some variables that can be passed to SCons in order to control the build process.

target_cc=myccCompile C code with mycc.
target_cxx=myc++Compile C++ code with myc++

To compile nul with an old version of GCC, type: scons target_cc=gcc-4.4.4 target_cxx=g++-4.4.4

To generate HTML documentation run scons doc.

Using Git

We use git to manage our source code. (Un)fortunately, there are many ways to use git. Let’s summarize some hints and “best practices”. If you are completely unfamiliar with Git, you should read one of the many tutorials first. A good one for the Subversion-proficient reader is

User Setup

It is important to use your real name and a working email address as these are stored in your commits. Set them using:

  • git config --global yourname
  • git config --global

Simple Updating and Committing

If you cloned the repository as shown above, you can pull the latest changes from the central repository by simply typing git pull. If you have local commits and someone else committed to the central repository, this will automatically create a merge between your repository head and the head of the central repository.

git push does the reverse and pushes your changes to the central server.


There are two downsides to the simple approach: Pulling blindly might be undesirable in some cases, as it can create a lot of conflicts. A second downside is the creation of a non-linear history, if you push the created merge commits back to the central repository. This is easily avoidable, except for very complex patches and merging of long-lived branches.

A slightly more complex way to update your tree and commit your changes is to first inspect the changes your co-workers commited and then rebase your changes on top of theirs before you push them to the central repository. Rebasing your local changes before committing keeps the central history merge-free and linear, which is a good thing!

The workflow would thus be:

  • git remote update to get the latest changes from the central repository
  • gitk --all (for X11 users) or tig --all (for those console junkies) to see your local branches as well as the remote branches.
  • git rebase origin/master to rebase your local commits on top of the central repository’s head. If you like to reorder or squash your commits, you can pass the -i flag to rebase.

At this point, your local branch contains all commits from the central repository with your commits on top of them. If you wish to commit them, you can now do git push to send them to the central repository.

Automated testing

NUL provides a simple infrastructure for automated testing. It is located in michal/wvtest. To run all tests in qemu, invoke scons test from the build directory.

To write a test you need to:

  1. Write your test program. The easiest way is to include “wvtest.h”, inherit your program from WvProgram instead of NovaProgram and implement wvrun(...) method.

    Somewhere in your code use assert-like macros starting with WV*. See for an example.

  2. Write a novaboot script, make it executable and name it as *.wv.
  3. Run scons test in the build directory. If you see only green “ok” at the right column of your screen, all tests passed.


To boot NOVA you need to setup a multiboot compliant bootloader to load the hypervisor, userland binaries and userland configuration. This procedure is slightly different for various bootloaders and boot methods (PXE, local harddrive, bootable CD, …).

To make it easier to boot NOVA in different environments, there is a novaboot program that reads a so called novaboot script and uses it either to boot NOVA (e.g. in qemu) or to generate the configuration for a specific bootloader and optionally to copy the necessary files to the proper locations.

The novaboot program is currently able to:

  1. run NOVA in qemu,
  2. create GRUB/GRUB2/Pulsar bootloader configuration and copy it with all the needed files to a remote TFTP server,
  3. run DHCP and TFTP server on your development machine to PXE boot NOVA from it,
  4. create bootable ISO images.

novaboot howto

  1. cd michal/boot
  2. Copy novaboot somewhere to your path e.g. cp novaboot ~/bin.
  3. Configure novaboot for your system (optional) novaboot --dump-config > ~/.novaboot vi ~/.novaboot
  4. Try to run “hello world” in qemu ./hello or copy the needed files to your TFTP server ./hello --server

See novaboot --help for more details (you need perl-doc package installed for this to work).

Booting a Vancouver System

An example novaboot script to run the hypervisor and a virtual machine is michal/boot/vancouver.

A GRUB configuration can be found in demo/example.conf. Another example is the Demo CD. For explanation of the individual parameters refer to README.sigma0 and README.vmm.


Bugs can be reported using Github or via sending a mail to Julian Stecklina <>. General discussion is happening on the l4-hackers mailing list:

NUL is the work of Bernhard Kauer <>, Alexander Böttcher <>, Michal Sojka <> and Julian Stecklina <>. The author of the NOVA hypervisor is Udo Steinberg <>.