An experimental way to define operating systems in Dhall & Nix



This is a very experimental project to see if we can write operating system definitions using a combination of Dhall & Nix. To play along at home, once you've cloned this repository, you can "boot" the test operating system with the following monstrosity:

mkdir root
cd root
$(nix-build --no-out-link ../build.nix --arg os "$(dhall-to-nix <<< ../Test-OS.dhall)")
sudo systemd-nspawn -b -D . -M test --bind-ro=/nix/store

This will create a new directory called root, cd into it, and then populate it with contents that systemd-nspawn can boot. Unpacking the nix-instantiate line, we:

  • First convert Test-OS.dhall into a Nix expression. This expression will be a function from a nixpkgs package set to a Bash script.
  • We apply that Nix function to import <nixpkgs> {}, giving us just a Bash script
  • We use pkgs.writeScript so that the result of nix-build is this Bash script.
  • We run it with $()

At this point, root should be populated with etc, sbin/init, and a few other things.

Finally, we run systemd-nspawn to boot the OS. We bind mount /nix/store into the container, because the init script will assume various things are available there.

The container currently runs:

  • agetty, so you can login
  • syslogd, so you can understand why you can't login