Site logo
Stories around the Genode Operating System RSS feed
Johannes Schlatow avatar

How to install a fresh VM on Sculpt

I recently needed to set up a new Linux VM on top of Sculpt. Since I encountered a few pitfalls along the way, I'd like to share my experiences and provide up-to-date instructions.

For the following guide I assume you have a freshly installed Sculpt 22.10. You can either download a pre-built Sculpt image or build your own image.

Sculpt preparations

There are a few prerequisites for running a VM on Sculpt.

  1. I need a window manager. The fast track is to deploy the themed wm as described in the Sculpt manual. Alternatively, I can use a custom deployment. The latter provides the benefit of being able to control and remember the window sizes and the placement of windows on different virtual screens.

  2. I need a file system that provides the VM image and configuration. Sculpt 22.10 comes with a launcher called vm fs, hence I only need to hit the + button and select vm fs. This component will provide the directory /<used_fs>/vm/debian as a distinct file system.

  3. The VM is going to request access to a shared file system. Sculpt 22.10 is also shipped with a ready-to-use shared fs launcher for this.

  4. I am going to deploy the black-hole component. As the name suggests it provides pseudo services for most resources including audio, networking, video capture, USB, and ROM. After enabling the genodelabs depot via + → Depot → Selection → genodelabs, I am able to deploy the black-hole component via + → Depot → genodelabs → Tools → black hole.

  5. I will need a fonts file system when installing the downloader. I installed such a file system via + → Depot → genodelabs → GUI → fonts fs. The ROM (config) service must be connected to system font configuration.

  6. I also need to deploy a system clock via + → Depot → genodelabs → Tools → system clock-pc. For each required service there is only a single choice.

  7. Last, I deployed a usb devices rom component. This component is required to let the VM know about what USB devices to pass through. There is a ready-to-use launcher in Sculpt 22.10 that I may use for this. Yet, if you intend to run multiple VMs, you should replicate this launcher and deploy a separate instance for every VM. Please refer to Martin's instructions on USB device passthrough for how to make use of the usb devices rom component.

Download an installer (iso)

Since the early days of Sculpt, we can find a downloader for Debian's netinstall iso image in cnuke's depot. The component is called download debian and can be deployed by enabling the cnuke depot via + → Depot → Selection → cnuke and installing via + → Depot → cnuke → Virtual machines -> download debian. Connect it as follows:

  • GUI → wm or themed_wm

  • Network → nic router

  • Region maps → custom virtual memory objects

  • File system (target) → vm fs

  • File system (fonts) → fonts fs

This component will download the netinstall iso image and store it in the target file system. The progress is shown in a terminal window for which the component requires GUI access and the fonts file system.

Start the VM and create a launcher

At this point, I can already deploy the vbox6 component and create a launcher for the new VM. The component is installed via + → Depot → genodelabs → Virtual machines → vbox6. Connect it as follows:

  • File system (vm) → vm fs

  • File system (shared) → shared fs

  • Hardware-based virtualization → virtualization hardware

  • GPU → black hole

  • GUI → wm or themed_wm

  • Network → nic router

  • ROM (capslock) → global capslock state

  • ROM (platform info) → platform information

  • Report (shape) → wm or themed_wm The shape report is used for providing an application-defined pointer shape. It is intercepted by the window manager, which applies the shape of the currently focussed window.

  • Report (clipboard) → wm or themed_wm The clipboard report provides write access to the clipboard. It is intercepted by the window manager to restrict access to the global clipboard. See Norman's article for detailed instructions.

  • ROM (clipboard) → wm or themed_wm The clipboard ROM provides read access to the clipboard.

  • ROM (mesa gpu → black hole

  • Region maps → custom virtual memory objects

  • Real-time clock → system clock-pc

  • ROM (usb devices) → usb devices rom

  • USB → direct USB-device access

  • Audio output → black hole

  • Audio input → black hole

Note that the GPU support is experimental so that I have routed GPU and the mesa ROM to the black-hole component. Please refer to this article on how to use 3D acceleration in VirtualBox 6.

Once I gave the vbox6 component a spin, it failed with a "Runtime error opening machine.vbox6 ..." since I have not populated the vm fs with such a file yet.

Anyway, I created a launcher to save the routing decisions. This is achieved by copying the "vbox6" start node from /config/managed/deploy into a launcher file, e.g. /config/launcher/vm. Any attribute other than the pkg attribute can be removed from the start node. Moreover, the start node must also be changed into a launcher node so that I end up with something like this:

 <launcher pkg="genodelabs/pkg/vbox6/...">

Create VM configuration

As we saw in the previous section, the vbox6 component expects the presence of a machine.vbox6 file in the vm fs. A blueprint is provided in the raw/vbox6 archive. We can copy the file in the Inspect view as follows:

 inspect:/> cd /<used_fs>
 inspect:/<used_fs>> cp ./depot/genodelabs/raw/vbox6/<version>/machine.vbox6 ./vm/debian/

Looking into the file, we will find the following lines of interest:

     <HardDisk uuid="{a90a16bf-f724-4321-99df-5498d6e4b796}" location="machine.vdi"
               format="VDI" type="Normal"/>
     <Image uuid="{81763434-9a51-49e8-9444-528a5a28c4bc}" location="installer.iso"/>
   <StorageController name="SATA" type="AHCI" PortCount="4" ...>
     <AttachedDevice type="HardDisk" port="0" device="0">
       <Image uuid="{a90a16bf-f724-4321-99df-5498d6e4b796}"/>
     <AttachedDevice passthrough="false" type="DVD" port="3" device="0">
       <Image uuid="{81763434-9a51-49e8-9444-528a5a28c4bc}"/>

This configuration references two files: installer.iso and machine.vdi. The former I have already downloaded in form of the Debian netinstall image. The latter is the image that I am going to use as a virtual disk for the VM.

Make changes permanent

Creating the virtual disk image will require rebooting the Sculpt system. To spare myself re-doing all the aforementioned steps, I made the customisations permanent. In particular, I executed the following commands in the Inspect view:

 inspect:/> cd /<used_fs>/
 inspect:/<used_fs>> mkdir -p config/22.10/launcher
 inspect:/<used_fs>> cp /config/managed/deploy ./config/22.10
 inspect:/<used_fs>> cp /config/launcher/vm ./config/22.10/launcher

Create a VDI image

In order to create a machine.vdi image, I had to move to a Linux host. I thus powered down my Sculpt system, unplugged the USB stick and plugged it into a Linux host which already had VirtualBox installed. I mounted the third partition of the USB stick at /media/SCULPT and created a 10000MB image as follows:

 VBoxManage createmedium --filename /media/SCULPT/vm/debian/machine.vdi \
                         --size 10000 --variant Fixed

It is also required to adapt the uuid in the machine.vbox6 file. You can get the uuid of the generated image by the following command:

 VBoxManage showmediuminfo /media/SCULPT/vm/debian/machine.vdi

This is an essential change since I got the following error when I started the VM on Sculpt without adapting the uuid:

 [runtime -> vbox6 -> vbox] main     Log created: 2022-10-24T15:02:46.006000000Z
 [runtime -> vbox6 -> vbox] main     Process ID:  0 (0x0)
 [runtime -> vbox6 -> vbox] main     Parent PID:  -1 (0xffffffff)
 [runtime -> vbox6 -> vbox] main     Executable:  /virtualbox6
 [runtime -> vbox6 -> vbox] Error: machine could not enter running state
 [runtime -> vbox6 -> vbox] main
 [runtime -> vbox6 -> vbox] main     !!Assertion Failed!!
 [runtime -> vbox6 -> vbox] main     Expression: state <= 1 && ( (state == 0 && count == 0)
                            || (state == 1 && count < PR_UINT32_MAX/2))
 [runtime -> vbox6 -> vbox] main     Location  : /data/depot/genodelabs/src/vbox6
                            virtual nsrefcnt MachineWrap::AddRef()
 [runtime -> vbox6 -> vbox] main     Stack     :
 [runtime -> vbox6 -> vbox] main     0000000001958bb3
 [runtime -> vbox6 -> vbox] main
 [runtime -> vbox6 -> vbox] 
 [runtime -> vbox6 -> vbox] !!Assertion Failed!!
 [runtime -> vbox6 -> vbox] Expression: state <= 1 && ( (state == 0 && count == 0)
                            || (state == 1 && count < PR_UINT32_MAX/2))
 [runtime -> vbox6 -> vbox] Location  : /data/depot/genodelabs/src/vbox6/2022-10-11/
                            virtual nsrefcnt MachineWrap::AddRef()
 [runtime -> vbox6 -> vbox] Stack     :
 [runtime -> vbox6 -> vbox] 0000000001958bb3
 [runtime -> vbox6 -> vbox] 
 [runtime -> vbox6 -> vbox] main     AddRef: illegal refcnt=3221225469 state=2
 [runtime -> vbox6 -> vbox] AddRef: illegal refcnt=3221225469 state=2
 [runtime -> vbox6 -> vbox] Error: Uncaught exception of type 'Genode::Ipc_error'
 [runtime -> vbox6 -> vbox] Warning: abort called - thread: main
 [core] Warning: unresolvable exception 3, pd 'init -> runtime -> vbox6 -> vbox',
        thread 'ep', cpu 0, ip=0x11bd9bc sp=0x403fe390 bp=0x19ca780 no signal handler

Note that I encountered a similar error when omitting the --variant Fixed option on image creation.


The Debian installation is pretty straightforward. However, to enable shared-folder and clipboard support, we need to install the guest additions of VirtualBox. The following articles may provide help on this matter: