{ self }: { genodeHost = { config, lib, pkgs, modulesPath, ... }: let apps' = self.apps.x86_64-linux-x86_64-genode; config' = config; lib' = self.lib.x86_64-linux-x86_64-genode; pkgs' = self.packages.x86_64-linux-x86_64-genode; legacyPackages' = self.legacyPackages.x86_64-linux-x86_64-genode; modulesPath' = "${self.inputs.nixpkgs}/nixos/modules"; cfg = config.genode; toVdi = config: import "${modulesPath'}/../lib/make-disk-image.nix" { inherit config lib pkgs; diskSize = config.virtualbox.baseImageSize; partitionTableType = "legacy"; fsType = "ext4"; name = "nixos-${pkgs.stdenv.hostPlatform.system}.vdi"; format = "vdi"; }; console = lib'.runDhallCommand "vbox.dhall" { } '' dhall > $out <<< '${ ./dhall/console.dhall } { bash = "${legacyPackages'.bash}", coreutils = "${legacyPackages'.coreutils}", path = "${ lib.makeSearchPathOutput "bin" "bin" (with legacyPackages'; [ bash coreutils ]) }" }' ''; guestChildren = lib'.runDhallCommand "vbox.dhall" { } ('' dhall > $out << END let Genode = env:DHALL_GENODE in [ '' + builtins.concatStringsSep "," (lib.mapAttrsToList (vmName: cfg: let inherit (cfg) config; vdiRoot = toVdi config; in lib'.runDhallCommand "vbox.dhall" { } '' vdiUuid=$(${pkgs.virtualbox}/bin/VBoxManage showmediuminfo "${vdiRoot}/nixos.vdi" | awk '/^UUID:/ {print $2}') dhall > $out << END { mapKey = "vbox-${vmName}" , mapValue = ${./dhall/vbox-guest.dhall} { vdiFilename = "nixos.vdi" , vdiPkg = "${baseNameOf vdiRoot}" , vdiUuid = "$vdiUuid" , memorySize = ${toString config.virtualbox.memorySize} , vmName = "${vmName}" } } END '') config.genode.guests) + '' ] : Genode.Init.Children.Type END ''); initConfig = let fbDriverConfig = if cfg.fbDriver == "intel" then ./dhall/intel_fb_drv.dhall else if cfg.fbDriver == "vesa" then ./dhall/vesa_fb_drv.dhall else throw ''No driver configuration found for "${cfg.fbDriver}"''; in '' ${ ./dhall/root.dhall } { fbDriver = ${fbDriverConfig}, guests = toMap { console = ${console} } # ${guestChildren}, inputFilterChargens = ${cfg.inputFilter.extraChargen}, partitionType = ${ ./dhall/partition-type }, wm = ${./dhall/wm.dhall} }''; buildBootDescription = self.legacyPackages.x86_64-linux.callPackage ./buildBootDescription.nix { lib = lib'; }; bootDescription = buildBootDescription { inherit initConfig; imageInputs = [ legacyPackages'.bash pkgs'.show_input ] ++ map pkgs'.genodeSources.depot ([ "acpi_drv" "ahci_drv" "cached_fs_rom" "chroot" "decorator" "init" "input_filter" "ipxe_nic_drv" "libc" "libiconv" "log_core" "nit_fb" "nitpicker" "part_block" "platform_drv" "posix" "ps2_drv" "report_rom" "rom_logger" "rtc_drv" "rump" "stdcxx" "terminal" "terminal_log" "usb_drv" "vfs" "vfs_audit" "vfs_import" "vfs_pipe" "vfs_ttf" "window_layouter" "wm" ] ++ lib.optional (cfg.guests != { }) "vbox5" ++ lib.optional (cfg.fbDriver == "vesa") "vesa_drv" ++ lib.optional (cfg.fbDriver == "intel") "intel_fb_drv") ++ (with pkgs'; [ base-nova block_router ]); extraBinaries = [ "ld.lib.so" "libc.so" "libm.so" "libposix.so" "librump.so" "librump_fs.so" "libstdcxx.so" "libvfs.so" "libvfs_audit.so" "libvfs_import.so" "libvfs_pipe.so" "libvfs_rump.so" "libvfs_ttf.so" ] ++ lib.optionals (cfg.guests != { }) [ "libc_pipe.so" "libiconv.so" "libqemu-usb.so" ]; extraRoms = { "Inconsolata.ttf" = "${pkgs.inconsolata}/share/fonts/truetype/inconsolata/Inconsolata-Regular.ttf"; "focus" = builtins.toFile "nitpicker-is-too-complicated.xml" '' ''; }; }; firmware = lib'.novaImage "stage0" { gzip = true; } bootDescription; in { options.genode = with lib; { fbDriver = mkOption { default = "vesa"; type = types.enum [ "intel" "vesa" ]; description = '' Set framebuffer driver. ''; }; guests = mkOption { type = types.attrsOf (types.submodule ({ config, options, name, ... }: { options = { config = mkOption { description = '' A specification of the desired configuration of this guest VM, as a NixOS module. ''; type = mkOptionType { name = "Toplevel NixOS config"; merge = loc: defs: (import "${modulesPath}/../lib/eval-config.nix" { inherit (config'.nixpkgs) system; modules = [ "${modulesPath}/virtualisation/virtualbox-image.nix" ] ++ (map (x: x.value) defs); prefix = [ "guests" name ]; }).config; }; }; }; })); default = { }; }; inputFilter = { extraChargen = mkOption { description = "Dhall expression of the type List Prelude.XML.Type"; type = types.str; default = "${./dhall/qwerty.chargen.dhall}"; }; }; }; config = { system.build.genode = { inherit firmware console; config = lib'.runDhallCommand "config.dhall" { } ''dhall > $out <<< "${initConfig}"''; xml = lib'.runDhallCommand "config.xml" { } ''${apps'.render-init.program} <<< "${initConfig}" > $out''; }; boot.loader.grub = { extraEntries = '' menuentry Genode on NOVA { insmod multiboot2 insmod gzio multiboot2 /bender module2 /hypervisor hypervisor iommu novpid serial logmem module2 /image.elf.gz image.elf } ''; extraFiles = { "bender" = "${pkgs'.genodeSources}/tool/boot/bender"; "hypervisor" = "${pkgs'.NOVA}/hypervisor-x86_64"; "image.elf.gz" = "${firmware}/image.elf.gz"; }; }; }; }; workman-layout.genode.inputFilter.extraChargen = "${./dhall/workman.chargen.dhall}"; }