From fc114fa9ff4711319ab02ae0c8643c25b86bde24 Mon Sep 17 00:00:00 2001 From: Mazunki Hoksaas Date: Tue, 24 Mar 2026 17:40:05 +0100 Subject: [PATCH 1/7] add flake support --- flake.lock | 63 +++++++++++++++++++++++++++++++++ flake.nix | 93 +++++++++++++++++++++++++++++++++++++++++++++++++ mkUnikernel.nix | 79 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 235 insertions(+) create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 mkUnikernel.nix diff --git a/flake.lock b/flake.lock new file mode 100644 index 000000000..e2b612b34 --- /dev/null +++ b/flake.lock @@ -0,0 +1,63 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1748026580, + "narHash": "sha256-rWtXrcIzU5wm/C8F9LWvUfBGu5U5E7cFzPYT1pHIJaQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "11cb3517b3af6af300dd6c055aeda73c9bf52c48", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "25.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1748026580, + "narHash": "sha256-rWtXrcIzU5wm/C8F9LWvUfBGu5U5E7cFzPYT1pHIJaQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "11cb3517b3af6af300dd6c055aeda73c9bf52c48", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "25.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "vmrunner": "vmrunner" + } + }, + "vmrunner": { + "inputs": { + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1774383306, + "narHash": "sha256-ZX5ONXEGaNx5No6pk9AoO1NoQ25eBzSVCHt/U1jd0eI=", + "owner": "mazunki", + "repo": "vmrunner", + "rev": "bf1db5862c7355f9892c63fa471255dcd46b878a", + "type": "github" + }, + "original": { + "owner": "mazunki", + "ref": "flakify", + "repo": "vmrunner", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 000000000..47f00d546 --- /dev/null +++ b/flake.nix @@ -0,0 +1,93 @@ +{ + description = "IncludeOS"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/25.05"; + vmrunner.url = "github:mazunki/vmrunner/flakify"; + # vmrunner.url = "github:includeos/vmrunner"; + }; + + outputs = { self, nixpkgs, vmrunner }: + let + system = "x86_64-linux"; + + mkIncludeos = { withCcache ? false, smp ? false }: + let + overlays = [ + (import ./overlay.nix { + inherit withCcache smp; + disableTargetWarning = true; + }) + ]; + pkgs = import nixpkgs { config = {}; inherit overlays system; }; + pkgsIncludeOS = pkgs.pkgsIncludeOS; + stdenvIncludeOS = pkgs.stdenvIncludeOS; + includeos = pkgsIncludeOS.includeos; + + chainloader = + let + chainloaderPkgs = import nixpkgs { + inherit system; + config = {}; + overlays = [ + (import ./overlay.nix { inherit withCcache; smp = false; disableTargetWarning = true; }) + ]; + crossSystem = { config = "i686-unknown-linux-musl"; }; + }; + in import ./chainloader.nix { + inherit nixpkgs withCcache; + pkgs = chainloaderPkgs; + }; + in { + inherit stdenvIncludeOS; # modified stdenv scope used by includeos (llvm, musl, libcxx) + inherit pkgsIncludeOS; # the musl/clang package scope used by IncludeOS + inherit pkgs; # nixpkgs with the IncludeOS overlay applied + inherit includeos; # the IncludeOS derivation to add to buildInputs + inherit chainloader; # 32-bit boot stub that hotswaps into the 64-bit unikernel + }; + + default = mkIncludeos {}; + mkUnikernel = import ./mkUnikernel.nix { inherit system default vmrunner; }; + in { + packages.${system} = { + default = default.includeos; + chainloader = default.chainloader; + example = mkUnikernel { unikernel = ./example; }; + }; + + devShells.${system}.default = import ./develop.nix { includeos = default.includeos; }; + + lib.${system} = { inherit mkIncludeos mkUnikernel; }; + + apps.${system} = { + default = self.apps.${system}.boot-unikernel; + + boot = { + type = "app"; + program = "${vmrunner.lib.${system}.mkBoot default.chainloader}/bin/boot"; + }; + + boot-unikernel = { + type = "app"; + program = "${default.pkgs.writeShellScript "boot-unikernel" '' + set -e + dir="''${1:-./result}" + shift || true + exec ${vmrunner.lib.${system}.mkBoot default.chainloader}/bin/boot \ + -j $dir/vm.json \ + $dir/*.elf.bin \ + "$@" + ''}"; + }; + + example = { + type = "app"; + program = "${default.pkgs.writeShellScript "run-example" '' + set -e + built=$(nix build path:${self.outPath}#example --no-link --print-out-paths) + exec ${self.apps.${system}.boot-unikernel.program} $built "$@" + ''}"; + }; + }; + }; +} diff --git a/mkUnikernel.nix b/mkUnikernel.nix new file mode 100644 index 000000000..b90569737 --- /dev/null +++ b/mkUnikernel.nix @@ -0,0 +1,79 @@ +# mkUnikernel.nix +{ system, default, vmrunner }: +args: +let + ios = if args ? includeos then args.includeos else default; + vmrunnerPkg = if args ? vmrunner then args.vmrunner + else vmrunner.packages.${system}.default; + + unikernel = args.unikernel or ./example; + test = args.test or "test.py"; + doCheck = args.doCheck or false; + arch = args.arch or "x86_64"; + forProduction = args.forProduction or false; + + src = unikernel; +in +ios.includeos.stdenv.mkDerivation { + pname = "includeos_unikernel"; + version = "dev"; + dontStrip = true; + inherit doCheck; + inherit src; + + nativeBuildInputs = [ + ios.pkgs.buildPackages.nasm + ios.pkgs.buildPackages.cmake + ios.pkgsIncludeOS.suppressTargetWarningHook + ]; + + buildInputs = [ + ios.includeos + ios.chainloader + ]; + + cmakeFlags = [ + "-DARCH=${arch}" + "-DINCLUDEOS_PACKAGE=${ios.includeos}" + "-DCMAKE_MODULE_PATH=${ios.includeos}/cmake" + "-DFOR_PRODUCTION=${if forProduction then "ON" else "OFF"}" + ]; + + installPhase = '' + runHook preInstall + # we want to place any files required by the test into the output + find -mindepth 1 -maxdepth 1 -type f -exec install -v -D -t "$out/" {} \; + + # especially the unikernel image, in case it wasn't at the rootdir already + find -mindepth 2 -name '*.elf.bin' -exec install -v -t "$out/" {} \; + runHook postInstall + ''; + + nativeCheckInputs = [ + vmrunnerPkg + ios.pkgs.grub2 + ios.pkgs.python3 + ios.pkgs.qemu + ios.pkgs.iputils + ios.pkgs.xorriso + ]; + + checkInputs = [ + ios.includeos.lest + ]; + + checkPhase = '' + runHook preCheck + set -e + if [ -e "${src}/${test}" ]; then + echo "Running IncludeOS test: ${src}/${test}" + python3 "${src}/${test}" + else + echo "Default test script '${test}', but no test was found 😟" + echo "For a custom path, consider specifying the path to the test script:" + echo " --argstr test 'path/to/test.py'" + exit 1 + fi + runHook postCheck + ''; +} From 380ce66abc284c48b9bc27cd1fbc991d163ea60c Mon Sep 17 00:00:00 2001 From: Mazunki Hoksaas Date: Tue, 24 Mar 2026 20:02:12 +0100 Subject: [PATCH 2/7] add stub vm.json for example unikernel this allows us to `-j vm.json` unconditionally --- example/vm.json | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 example/vm.json diff --git a/example/vm.json b/example/vm.json new file mode 100644 index 000000000..2c63c0851 --- /dev/null +++ b/example/vm.json @@ -0,0 +1,2 @@ +{ +} From 5fa93bc1f4427bde8363826c4f2b6a72abf26c10 Mon Sep 17 00:00:00 2001 From: Mazunki Hoksaas Date: Mon, 16 Mar 2026 15:50:50 +0100 Subject: [PATCH 3/7] gitignore nix build dir --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index b55f6b82c..378e4538d 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,9 @@ build_i686/ build_x86_64/ build_conan/ +# nix +/result + # ignore log files in test tree test/**/*.log From 0f110dcd520424adc0ed38c91d60c1d1e50731b7 Mon Sep 17 00:00:00 2001 From: Mazunki Hoksaas Date: Tue, 24 Mar 2026 22:29:26 +0100 Subject: [PATCH 4/7] replace feature branch with upstream --- flake.nix | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/flake.nix b/flake.nix index 47f00d546..4cbdae68c 100644 --- a/flake.nix +++ b/flake.nix @@ -3,8 +3,7 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs/25.05"; - vmrunner.url = "github:mazunki/vmrunner/flakify"; - # vmrunner.url = "github:includeos/vmrunner"; + vmrunner.url = "github:includeos/vmrunner"; }; outputs = { self, nixpkgs, vmrunner }: From c643f1558a53aecc2d1c297365469f013eeef163 Mon Sep 17 00:00:00 2001 From: Mazunki Hoksaas Date: Wed, 22 Apr 2026 12:49:11 +0200 Subject: [PATCH 5/7] update mkBoot to match kvm support of 306bdc40 --- flake.nix | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/flake.nix b/flake.nix index 4cbdae68c..efe828ba5 100644 --- a/flake.nix +++ b/flake.nix @@ -63,7 +63,7 @@ boot = { type = "app"; - program = "${vmrunner.lib.${system}.mkBoot default.chainloader}/bin/boot"; + program = "${vmrunner.lib.${system}.mkBoot default.chainloader {}}/bin/boot"; }; boot-unikernel = { @@ -72,7 +72,20 @@ set -e dir="''${1:-./result}" shift || true - exec ${vmrunner.lib.${system}.mkBoot default.chainloader}/bin/boot \ + exec ${vmrunner.lib.${system}.mkBoot default.chainloader {}}/bin/boot \ + -j $dir/vm.json \ + $dir/*.elf.bin \ + "$@" + ''}"; + }; + + boot-unikernel-kvm = { + type = "app"; + program = "${default.pkgs.writeShellScript "boot-unikernel-kvm" '' + set -e + dir="''${1:-./result}" + shift || true + exec ${vmrunner.lib.${system}.mkBoot default.chainloader { kvm = true; }}/bin/boot \ -j $dir/vm.json \ $dir/*.elf.bin \ "$@" From 8a96ff7d7a11e78005e0330baf2a0967930c5aa5 Mon Sep 17 00:00:00 2001 From: Mazunki Hoksaas Date: Wed, 29 Apr 2026 10:08:16 +0200 Subject: [PATCH 6/7] permit debug information through gdb --- deps/musl/default.nix | 4 +- flake.lock | 8 ++-- flake.nix | 98 +++++++++++++++++++++++-------------------- mkUnikernel.nix | 11 ++++- overlay.nix | 8 +++- 5 files changed, 75 insertions(+), 54 deletions(-) diff --git a/deps/musl/default.nix b/deps/musl/default.nix index 3921abdcd..239cb8943 100644 --- a/deps/musl/default.nix +++ b/deps/musl/default.nix @@ -2,6 +2,7 @@ stdenv , pkgs , linuxHeaders ? null +, debug ? false }: stdenv.mkDerivation rec { pname = "musl-includeos"; @@ -40,7 +41,8 @@ stdenv.mkDerivation rec { ./configure --prefix=$out --disable-shared --enable-debug --with-malloc=oldmalloc CROSS_COMPILE=${stdenv.targetPlatform.config}- ''; - CFLAGS = "-Wno-error=int-conversion -nostdinc"; + dontStrip = debug; + CFLAGS = "-Wno-error=int-conversion -nostdinc${pkgs.lib.optionalString debug " -g"}"; meta = { description = "musl - Linux based libc, built with IncludeOS linux-like syscalls"; diff --git a/flake.lock b/flake.lock index e2b612b34..d804df560 100644 --- a/flake.lock +++ b/flake.lock @@ -43,16 +43,16 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1774383306, - "narHash": "sha256-ZX5ONXEGaNx5No6pk9AoO1NoQ25eBzSVCHt/U1jd0eI=", + "lastModified": 1776892605, + "narHash": "sha256-r64A8ec7eGMReJw4gUKIUM25jNs20HcapzDZLno1Ic8=", "owner": "mazunki", "repo": "vmrunner", - "rev": "bf1db5862c7355f9892c63fa471255dcd46b878a", + "rev": "d07f22b5c1503b58d4fb67d8331efa67564d8db8", "type": "github" }, "original": { "owner": "mazunki", - "ref": "flakify", + "ref": "dev", "repo": "vmrunner", "type": "github" } diff --git a/flake.nix b/flake.nix index efe828ba5..9908dbf66 100644 --- a/flake.nix +++ b/flake.nix @@ -3,18 +3,19 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs/25.05"; - vmrunner.url = "github:includeos/vmrunner"; + # vmrunner.url = "github:includeos/vmrunner"; + vmrunner.url = "github:mazunki/vmrunner/dev"; }; outputs = { self, nixpkgs, vmrunner }: let system = "x86_64-linux"; - mkIncludeos = { withCcache ? false, smp ? false }: + mkIncludeos = { withCcache ? false, smp ? false, debug ? false }: let overlays = [ (import ./overlay.nix { - inherit withCcache smp; + inherit withCcache smp debug; disableTargetWarning = true; }) ]; @@ -45,61 +46,68 @@ inherit chainloader; # 32-bit boot stub that hotswaps into the 64-bit unikernel }; - default = mkIncludeos {}; - mkUnikernel = import ./mkUnikernel.nix { inherit system default vmrunner; }; + default = mkIncludeos {}; + defaultDebug = mkIncludeos { debug = true; }; + mkUnikernel = import ./mkUnikernel.nix { inherit system default defaultDebug vmrunner; }; in { packages.${system} = { - default = default.includeos; + default = default.includeos // { debug = defaultDebug.includeos; }; chainloader = default.chainloader; example = mkUnikernel { unikernel = ./example; }; }; devShells.${system}.default = import ./develop.nix { includeos = default.includeos; }; - lib.${system} = { inherit mkIncludeos mkUnikernel; }; + lib.${system} = { + inherit mkIncludeos mkUnikernel; - apps.${system} = { - default = self.apps.${system}.boot-unikernel; + mkChainloader = { mem }: + vmrunner.lib.${system}.mkBoot default.chainloader { inherit mem; }; - boot = { - type = "app"; - program = "${vmrunner.lib.${system}.mkBoot default.chainloader {}}/bin/boot"; - }; + boot = { kernel ? "service", mem, kvm ? false, debug ? false }: + let + chainloaders = self.lib.${system}.mkChainloader { inherit mem; }; + chainloader = if kvm then chainloaders.kvm + else if debug then chainloaders.debug + else chainloaders.default; + in { + type = "app"; + program = "${default.pkgs.writeShellScript "boot-unikernel" '' + set -e + dir="''${1:-./result}" + ${default.pkgs.lib.optionalString debug ''echo "boot: $dir/${kernel}" >&2''} + exec ${chainloader}/bin/boot "$dir/${kernel}" "$@" + ''}"; + }; - boot-unikernel = { - type = "app"; - program = "${default.pkgs.writeShellScript "boot-unikernel" '' - set -e - dir="''${1:-./result}" - shift || true - exec ${vmrunner.lib.${system}.mkBoot default.chainloader {}}/bin/boot \ - -j $dir/vm.json \ - $dir/*.elf.bin \ - "$@" - ''}"; - }; + mkBoot1 = { src, kernel ? "service", kvm ? false, mem ? "16G", debug ? false }: + let + bootApp = self.lib.${system}.boot { inherit kernel kvm debug mem; }; + in { + type = "app"; + program = "${default.pkgs.writeShellScript "run-flake-package" '' + set -e + exec ${bootApp.program} ${src} "$@" + ''}"; + }; - boot-unikernel-kvm = { - type = "app"; - program = "${default.pkgs.writeShellScript "boot-unikernel-kvm" '' - set -e - dir="''${1:-./result}" - shift || true - exec ${vmrunner.lib.${system}.mkBoot default.chainloader { kvm = true; }}/bin/boot \ - -j $dir/vm.json \ - $dir/*.elf.bin \ - "$@" - ''}"; - }; + mkBoot = args: + let + debugSrc = args.debugSrc or args.src; + base = builtins.removeAttrs args [ "debugSrc" ]; + tcg = self.lib.${system}.mkBoot1 (base // { kvm = false; debug = false; }); + kvm = self.lib.${system}.mkBoot1 (base // { kvm = true; debug = false; }); + debug = self.lib.${system}.mkBoot1 (base // { src = debugSrc; kvm = false; debug = true; }); + in + tcg // { inherit tcg kvm debug; }; + }; - example = { - type = "app"; - program = "${default.pkgs.writeShellScript "run-example" '' - set -e - built=$(nix build path:${self.outPath}#example --no-link --print-out-paths) - exec ${self.apps.${system}.boot-unikernel.program} $built "$@" - ''}"; - }; + apps.${system} = { + default = self.apps.${system}.boot-unikernel; + + boot-unikernel = self.lib.${system}.boot { mem = "128m"; }; + + example = self.lib.${system}.mkBoot { src = self.packages.${system}.example; kernel = "hello_includeos.elf.bin"; }; }; }; } diff --git a/mkUnikernel.nix b/mkUnikernel.nix index b90569737..2958babbb 100644 --- a/mkUnikernel.nix +++ b/mkUnikernel.nix @@ -1,8 +1,11 @@ # mkUnikernel.nix -{ system, default, vmrunner }: +{ system, default, defaultDebug, vmrunner }: args: let - ios = if args ? includeos then args.includeos else default; + debug = args.debug or false; + ios = if args ? includeos then args.includeos + else if debug then defaultDebug + else default; vmrunnerPkg = if args ? vmrunner then args.vmrunner else vmrunner.packages.${system}.default; @@ -37,6 +40,10 @@ ios.includeos.stdenv.mkDerivation { "-DINCLUDEOS_PACKAGE=${ios.includeos}" "-DCMAKE_MODULE_PATH=${ios.includeos}/cmake" "-DFOR_PRODUCTION=${if forProduction then "ON" else "OFF"}" + "-DCMAKE_BUILD_TYPE=${if debug then "Debug" else "Release"}" + ] ++ ios.pkgs.lib.optionals debug [ + "-DCMAKE_C_FLAGS=-ffile-prefix-map=/build/${builtins.baseNameOf src}=/build/unikernel" + "-DCMAKE_CXX_FLAGS=-ffile-prefix-map=/build/${builtins.baseNameOf src}=/build/unikernel" ]; installPhase = '' diff --git a/overlay.nix b/overlay.nix index de76d9084..bb6e9f987 100644 --- a/overlay.nix +++ b/overlay.nix @@ -2,6 +2,7 @@ withCcache, # Enable ccache. Requires correct permissions, see below. disableTargetWarning ? true, # TODO: see https://github.com/NixOS/nixpkgs/issues/395191 smp, # Enable multicore support (SMP) + debug ? false, } : final: prev: { @@ -13,7 +14,7 @@ final: prev: { musl-unpatched = self.callPackage ./deps/musl-unpatched/default.nix { linuxHeaders = prev.linuxHeaders; }; # Import IncludeOS musl which will be built and linked with IncludeOS services - musl-includeos = self.callPackage ./deps/musl/default.nix { }; + musl-includeos = self.callPackage ./deps/musl/default.nix { inherit debug; }; # Clang with unpatched musl for building libcxx clang_musl_unpatched_nolibcxx = self.llvmPkgs.clangNoLibcxx.override (old: { @@ -191,7 +192,10 @@ final: prev: { smpFlags = if smp then [ "-DSMP=ON" ] else []; - cmakeFlags = archFlags ++ smpFlags; + debugFlags = if debug then [ "-DCMAKE_BUILD_TYPE=Debug" ] else []; + dontStrip = debug; + + cmakeFlags = archFlags ++ smpFlags ++ debugFlags; # Add some pasthroughs, for easily building the dependencies (for debugging): # $ nix-build -A NAME From 23b767c6cab9a72426f613d9a5c8a4672b32ed47 Mon Sep 17 00:00:00 2001 From: Mazunki Hoksaas Date: Wed, 29 Apr 2026 15:45:05 +0200 Subject: [PATCH 7/7] fixup! permit debug information through gdb --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 9908dbf66..a95d826a8 100644 --- a/flake.nix +++ b/flake.nix @@ -4,7 +4,7 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs/25.05"; # vmrunner.url = "github:includeos/vmrunner"; - vmrunner.url = "github:mazunki/vmrunner/dev"; + vmrunner.url = "github:mazunki/vmrunner"; }; outputs = { self, nixpkgs, vmrunner }: