Home

Awesome

IncludeOS Hello World

A basic example to demonstrate the open source unikernel project - IncludeOS.

IncludeOS is built with nix. Before building the example you need a working nix-installation. To speed up the build process, we also recommend having ccache enabled installed, but this is not a requirement. To use ccache, add --arg withCcache true to the nix commands below.

The source code for the example is in ./src/main.cpp. It prints "Hello world" and calls shutdown:

$ cat ./src/main.cpp
#include <iostream>
#include <os>

int main(){
  std::cout << "Hello world\n";
  os::shutdown();
}

The following steps let you build and boot this example with IncludeOS.

$ nix-build

This will download and build the latest IncludeOS libraries and their dependencies and build the hello-world service. The final binary will be called hello.bin.elf in ./result/bin.

$ ls ./result/bin
hello.elf.bin

To boot the unikernel you need to add a bootloader or use the IncludeOS chainloader. The separate tool vmrunner, can be used to automatically manage this. QEMU and vmrunner is already configured in shell.nix.

To boot the unikernel, run

$ nix-shell --command "boot ./result/bin/hello.elf.bin"
[...]
ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, stripped

SeaBIOS (version rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org)


iPXE (http://ipxe.org) 00:03.0 CA00 PCI2.10 PnP PMM+06FD0E60+06F30E60 CA00
Press Ctrl-B to configure iPXE (PCI 00:03.0)...


Booting from ROM..* Multiboot begin: 0x9500
* Multiboot cmdline @ 0x29d02e: /nix/store/jd9dhri62mz7lm5mld58c7c1wn2dsnbx-chainloader-static-i686-unknown-linux-musl-dev/bin/chainloader ""
* Multiboot end: 0x29d09c
* Module list @ 0x29d000
	 * Module @ 0x29e000
	 * Args: ./result/bin/hello.elf.bin ""
 	 * End: 0x43d6c0
 * Multiboot end: 0x43d6c0
* ELF syms header CRC OK
<Multiboot>Booted with multiboot
	* Boot flags: 0x24f
	* Valid memory (130559 Kib):
	  0x00000000 - 0x0009fbff (639 Kib)
	  0x00100000 - 0x07fdffff (129920 Kib)

	* Booted with parameters @ 0x29d02e: /nix/store/jd9dhri62mz7lm5mld58c7c1wn2dsnbx-chainloader-static-i686-unknown-linux-musl-dev/bin/chainloader ""
	* Multiboot provided memory map  (7 entries @ 0x9000)
	  0x0000000000 - 0x000009fbff FREE (639 Kb.)
	  0x000009fc00 - 0x000009ffff RESERVED (1 Kb.)
	  0x00000f0000 - 0x00000fffff RESERVED (64 Kb.)
	  0x0000100000 - 0x0007fdffff FREE (129920 Kb.)
	  0x0007fe0000 - 0x0007ffffff RESERVED (128 Kb.)
	  0x00fffc0000 - 0x00ffffffff RESERVED (256 Kb.)
	  0x0000000000 - 0x00ffffffff RESERVED (0 Kb.)

<Multiboot>OS loaded with 1 modules
	* ./result/bin/hello.elf.bin "" @ 0x29e000 - 0x43d6c0, size: 1701568b
* Multiboot begin: 0x9500
* Multiboot end: 0x3e59c0
[x86_64 PC] constructor
[ Machine ] Initializing heap
[ Machine ] Main memory detected as 129998656 b
[ Machine ] Reserving 1048576 b for machine use
<Multiboot>Booted with multiboot
	* Boot flags: 0x24f
	* Valid memory (130559 Kib):
	  0x00000000 - 0x0009fbff (639 Kib)
	  0x00100000 - 0x07fdffff (129920 Kib)

	* Booted with parameters @ 0x8000: ./result/bin/hello.elf.bin ""
	* Multiboot provided memory map  (7 entries @ 0x9000)
	  0x0000000000 - 0x000009fbff FREE (639 Kb.)
	  0x000009fc00 - 0x000009ffff RESERVED (1 Kb.)
	  0x00000f0000 - 0x00000fffff RESERVED (64 Kb.)
	  0x0000100000 - 0x0007fdffff FREE (129920 Kb.)
	  0x0007fe0000 - 0x0007ffffff RESERVED (128 Kb.)
	  0x00fffc0000 - 0x00ffffffff RESERVED (256 Kb.)
	  0xfd00000000 - 0xffffffffff RESERVED (12582912 Kb.)

================================================================================
 IncludeOS VERY_DIRTY (x86_64 / 64-bit)
 +--> Running [ Hello world - OS included ]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 +--> WARNING: No good random source found: RDRAND/RDSEED instructions not available.
 +-->        To make this warning fatal, re-compile with FOR_PRODUCTION=ON.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Hello world
       [ main ] returned with status 0
     [ Kernel ] Stopping service
     [ Kernel ] Powering off

[ SUCCESS ] process exited

You can also use shell.nix to rebuild and boot the unikernel during development, without having to invoke nix-shell every time. Just run nix-shell and follow the instructions:

$ nix-shell
To build the hello_world unikernel:
 cmake src/CMakeLists.txt -B ./build
 cd ./build
 make
 boot ./hello.elf.bin

For more details on how to develop with IncludeOS see the main repository.