From a03f7d7d6365554074540672ca9688105b9295ec Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Mon, 8 Jun 2020 17:48:40 +0530 Subject: [PATCH] Initial NixOS module The module can be tested by the command `nix run .#nixosModule`. --- flake.nix | 95 ++- nixos-modules/buildBootDescription.nix | 67 ++ nixos-modules/default.nix | 235 +++++++ nixos-modules/dhall/console.dhall | 189 ++++++ nixos-modules/dhall/intel_fb_drv.dhall | 23 + nixos-modules/dhall/partition-type | 1 + nixos-modules/dhall/qwerty.chargen.dhall | 297 +++++++++ nixos-modules/dhall/root.dhall | 718 ++++++++++++++++++++++ nixos-modules/dhall/show_input.dhall | 43 ++ nixos-modules/dhall/vbox-guest.dhall | 163 +++++ nixos-modules/dhall/vesa_fb_drv.dhall | 27 + nixos-modules/dhall/wm.dhall | 237 +++++++ nixos-modules/dhall/workman.chargen.dhall | 245 ++++++++ 13 files changed, 2333 insertions(+), 7 deletions(-) create mode 100644 nixos-modules/buildBootDescription.nix create mode 100644 nixos-modules/default.nix create mode 100644 nixos-modules/dhall/console.dhall create mode 100644 nixos-modules/dhall/intel_fb_drv.dhall create mode 100644 nixos-modules/dhall/partition-type create mode 100644 nixos-modules/dhall/qwerty.chargen.dhall create mode 100644 nixos-modules/dhall/root.dhall create mode 100644 nixos-modules/dhall/show_input.dhall create mode 100644 nixos-modules/dhall/vbox-guest.dhall create mode 100644 nixos-modules/dhall/vesa_fb_drv.dhall create mode 100644 nixos-modules/dhall/wm.dhall create mode 100644 nixos-modules/dhall/workman.chargen.dhall diff --git a/flake.nix b/flake.nix index 1e72f0e..bc32f67 100644 --- a/flake.nix +++ b/flake.nix @@ -5,7 +5,7 @@ description = "Genode packages"; - inputs.nixpkgs.url = "github:ehmry/nixpkgs?ref=genode"; + inputs.nixpkgs.url = "github:ehmry/nixpkgs/genode"; outputs = { self, nixpkgs }: let @@ -111,17 +111,52 @@ apps = let apps' = forAllCrossSystems ({ system, localSystem, crossSystem }: import ./apps { - system = crossSystem; + inherit system; self = self.apps.${system}; nixpkgs = nixpkgsFor.${system}; nixpkgsLocal = nixpkgsFor.${localSystem}; packages = self.packages.${system}; + } // { + nixosModule = { + type = "app"; + program = + "${self.checks.${localSystem}.nixosModule}/bin/run-nixos-vm"; + }; }); in apps' // { x86_64-linux = apps'.x86_64-linux-x86_64-genode; }; + nixosModules = import ./nixos-modules { inherit self; }; + checks = let + checks' = forAllCrossSystems ({ system, localSystem, crossSystem }: - import ./tests { + let + nixos = nixpkgs.lib.nixosSystem { + system = localSystem; + modules = [ + self.nixosModules.genodeHost + ({ modulesPath, ... }: { + imports = [ "${modulesPath}/virtualisation/qemu-vm.nix" ]; + boot.loader.grub.extraEntriesBeforeNixOS = true; + genode.inputFilter.extraChargen = + "${./nixos-modules/dhall/workman.chargen.dhall}"; + virtualisation = { + cores = 2; + memorySize = 1024; + useBootLoader = true; + qemu = { + options = + [ "-machine q35" "-cpu phenom" "-serial mon:stdio" ]; + networkingOptions = [ + "-net nic,netdev=user.0,model=e1000" + "-netdev user,id=user.0\${QEMU_NET_OPTS:+,$QEMU_NET_OPTS}" + ]; + }; + }; + }) + ]; + }; + in import ./tests { inherit self; apps = self.apps.${system}; localPackages = nixpkgsFor.${localSystem}; @@ -129,10 +164,56 @@ lib = self.lib.${system}; nixpkgs = nixpkgsFor.${system}; legacyPackages = self.legacyPackages.${system}; + } // { + + ports = nixpkgsFor.${localSystem}.symlinkJoin { + name = "ports"; + paths = (builtins.attrValues + self.packages.${system}.genodeSources.ports); + }; + + nixosModule = nixos.config.system.build.vm; + nixosXML = nixos.config.system.build.genode.xml; + + nixosGuest = let + nixos = nixpkgs.lib.nixosSystem { + system = localSystem; + modules = [ + self.nixosModules.genodeHost + ({ modulesPath, ... }: { + imports = [ "${modulesPath}/virtualisation/qemu-vm.nix" ]; + boot.loader.grub.extraEntriesBeforeNixOS = true; + virtualisation = { + cores = 2; + memorySize = 1024; + useBootLoader = true; + qemu = { + options = + [ "-machine q35" "-cpu phenom" "-serial mon:stdio" ]; + networkingOptions = [ + "-net nic,netdev=user.0,model=e1000" + "-netdev user,id=user.0\${QEMU_NET_OPTS:+,$QEMU_NET_OPTS}" + ]; + }; + }; + genode.guests.flakeCheck = { + config = { config, lib, pkgs, ... }: { + networking.firewall.allowedTCPPorts = [ 80 ]; + services.mingetty.autologinUser = lib.mkDefault "root"; + services.nginx.enable = true; + services.openssh.permitRootLogin = lib.mkDefault "yes"; + services.sshd.enable = true; + users.users.root.password = "nixos"; + virtualbox.memorySize = 128; + }; + }; + }) + ]; + }; + in nixos.config.system.build.vm; + }); - in checks' // { - x86_64-linux = with builtins; - foldl' (x: y: x // y) { } (attrValues checks'); - }; + in { x86_64-linux = checks'.x86_64-linux-x86_64-genode; }; + }; } diff --git a/nixos-modules/buildBootDescription.nix b/nixos-modules/buildBootDescription.nix new file mode 100644 index 0000000..511102e --- /dev/null +++ b/nixos-modules/buildBootDescription.nix @@ -0,0 +1,67 @@ +# SPDX-License-Identifier: CC0-1.0 + +# Generate a total boot description by matching the binaries referred to by an init +# configuration with a list of input packages. + +{ lib, writeText, dhall-json }: + +{ initConfig, imageInputs, extraBinaries ? [ ], extraRoms ? { } }: + +with builtins; +let + extractDrv = lib.runDhallCommand "binaries.json" { + nativeBuildInputs = [ dhall-json ]; + } '' + dhall-to-json << TRUE_DEATH > $out + let Genode = env:DHALL_GENODE + let init = ${initConfig} + in Genode.Init.Child.binaries (Genode.Init.toChild init Genode.Init.Attributes::{=}) + TRUE_DEATH + ''; + binariesJSON = readFile (toString extractDrv); + binaries = lib.unique (fromJSON binariesJSON ++ extraBinaries); + + matches = let + f = binary: { + name = binary; + value = let + f = drv: + if lib.hasPrefix "lib" binary && lib.hasSuffix ".so" binary + && pathExists "${drv.lib or drv}/lib" then + toPath "${drv.lib or drv}/lib/${binary}" + else + toPath (if pathExists "${drv}/bin" then + "${drv}/bin/${binary}" + else + "${drv}/${binary}"); + in filter pathExists (map f imageInputs); + }; + in map f binaries; + + binaryPaths = let + f = { name, value }: + let l = length value; + in if l == 1 then { + inherit name; + value = elemAt value 0; + } else if l == 0 then + throw "${name} not found in imageInputs" + else + throw "${name} found in multiple imageInputs, ${toString value}"; + in map f matches; + + extraList = + lib.mapAttrsToList (name: value: { inherit name value; }) extraRoms; + +in writeText "boot.dhall" '' + let Genode = env:DHALL_GENODE + in { config = ${initConfig} + , rom = Genode.BootModules.toRomPaths ([ + ${ + toString (map ({ name, value }: '' + , { mapKey = "${name}", mapValue = "${value}" } + '') (binaryPaths ++ extraList)) + } + ]) + } +'' diff --git a/nixos-modules/default.nix b/nixos-modules/default.nix new file mode 100644 index 0000000..9f6af90 --- /dev/null +++ b/nixos-modules/default.nix @@ -0,0 +1,235 @@ +{ self }: { + genodeHost = { config, lib, pkgs, ... }: + 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}"; + +} diff --git a/nixos-modules/dhall/console.dhall b/nixos-modules/dhall/console.dhall new file mode 100644 index 0000000..a504af1 --- /dev/null +++ b/nixos-modules/dhall/console.dhall @@ -0,0 +1,189 @@ +-- SPDX-License-Identifier: CC0-1.0 +-- TODO: Move routes passed to toChild into the Init + +let Genode = env:DHALL_GENODE + +let Prelude = Genode.Prelude + +let XML = Prelude.XML + +let Init = Genode.Init + +let Child = Init.Child + +let Resources = Init.Resources + +let ServiceRoute = Init.ServiceRoute + +in λ(params : { bash : Text, coreutils : Text, path : Text }) + → let init = + Init::{ + , verbose = True + , routes = + Prelude.List.map + Text + Init.ServiceRoute.Type + Init.ServiceRoute.parent + [ "Nitpicker", "Rtc", "Timer" ] + , children = toMap + { nit_fb = + Child.flat + Child.Attributes::{ + , binary = "nit_fb" + , config = Init.Config::{ + , attributes = toMap + { xpos = "10" + , ypos = "10" + , initial_width = "800" + , initial_height = "600" + } + } + , provides = [ "Framebuffer", "Input" ] + , resources = Resources::{ ram = Genode.units.MiB 8 } + } + , terminal = + Child.flat + Child.Attributes::{ + , binary = "terminal" + , config = Init.Config::{ + , content = + [ XML.element + { name = "vfs" + , attributes = XML.emptyAttributes + , content = + [ XML.element + { name = "dir" + , attributes = toMap { name = "fonts" } + , content = + [ XML.leaf + { name = "fs" + , attributes = toMap + { label = "fonts" } + } + ] + } + ] + } + ] + } + , provides = [ "Terminal" ] + , resources = Resources::{ + , caps = 256 + , ram = Genode.units.MiB 4 + } + , routes = + [ ServiceRoute.child "Framebuffer" "nit_fb" + , ServiceRoute.child "Input" "nit_fb" + , ServiceRoute.parent "File_system" + ] + } + , vfs = + Child.flat + Child.Attributes::{ + , binary = "vfs" + , config = Init.Config::{ + , content = + [ Prelude.XML.text + '' + + + + + + + + + + + + + + + + '' + ] + } + , provides = [ "File_system" ] + , resources = Resources::{ + , caps = 256 + , ram = Genode.units.MiB 8 + } + , routes = + [ Init.ServiceRoute.parent "File_system" + , Init.ServiceRoute.child "Terminal" "terminal" + ] + } + , store_rom = + Child.flat + Child.Attributes::{ + , binary = "cached_fs_rom" + , provides = [ "ROM" ] + , resources = Resources::{ + , caps = 256 + , ram = Genode.units.MiB 4 + } + , routes = [ Init.ServiceRoute.child "File_system" "vfs" ] + } + , shell = + Child.flat + Child.Attributes::{ + , binary = "bash" + , config = Genode.Init.Config::{ + , content = + [ Prelude.XML.text + '' + + + + + + '' + ] + # Prelude.List.map + Text + XML.Type + ( λ(x : Text) + → XML.leaf + { name = "arg" + , attributes = toMap { value = x } + } + ) + [ "bash" ] + } + , exitPropagate = True + , resources = Resources::{ + , caps = 256 + , ram = Genode.units.MiB 8 + } + , routes = + [ Init.ServiceRoute.child "File_system" "vfs" + , { service = + { name = "ROM" + , label = + Init.LabelSelector.Type.Partial + { prefix = Some "/nix/store/" + , suffix = None Text + } + } + , route = + Init.Route.Type.Child + { name = "store_rom" + , label = None Text + , diag = None Bool + } + } + ] + } + } + } + + in Init.toChild + init + Init.Attributes::{ + , routes = + [ ServiceRoute.parent "File_system" + , ServiceRoute.parent "Nitpicker" + , ServiceRoute.parent "Rtc" + , ServiceRoute.parent "Timer" + ] + } diff --git a/nixos-modules/dhall/intel_fb_drv.dhall b/nixos-modules/dhall/intel_fb_drv.dhall new file mode 100644 index 0000000..2ecb1b9 --- /dev/null +++ b/nixos-modules/dhall/intel_fb_drv.dhall @@ -0,0 +1,23 @@ +let Genode = env:DHALL_GENODE + +let Init = Genode.Init + +let Child = Init.Child + +let ServiceRoute = Init.ServiceRoute + +in Child.flat + Child.Attributes::{ + , binary = "intel_fb_drv" + , provides = [ "Framebuffer" ] + , resources = Init.Resources::{ caps = 256, ram = Genode.units.MiB 48 } + , routes = + [ ServiceRoute.parent "IO_MEM" + , ServiceRoute.parent "IO_PORT" + , ServiceRoute.childLabel + "Platform" + "platform_drv" + (None Text) + (Some "intel_fb_drv") + ] + } diff --git a/nixos-modules/dhall/partition-type b/nixos-modules/dhall/partition-type new file mode 100644 index 0000000..2cca25d --- /dev/null +++ b/nixos-modules/dhall/partition-type @@ -0,0 +1 @@ +"24b69406-18a1-428d-908e-d21a1437122c" diff --git a/nixos-modules/dhall/qwerty.chargen.dhall b/nixos-modules/dhall/qwerty.chargen.dhall new file mode 100644 index 0000000..ad11e92 --- /dev/null +++ b/nixos-modules/dhall/qwerty.chargen.dhall @@ -0,0 +1,297 @@ +let Genode = env:DHALL_GENODE + +let Prelude = Genode.Prelude + +let XML = Prelude.XML + +let Key = < Ascii : Natural | Char : Text | Code : Natural > : Type + +let Map = + { Type = + { keys : Prelude.Map.Type Text Key + , mod1 : Bool + , mod2 : Bool + , mod3 : Bool + , mod4 : Bool + } + , default = { mod1 = False, mod2 = False, mod3 = False, mod4 = False } + } + +let boolToAttr = λ(_ : Bool) → if _ then "yes" else "no" + +let keyToXML = + λ(x : Prelude.Map.Entry Text Key) + → XML.leaf + { name = "key" + , attributes = + [ merge + { Ascii = + λ(_ : Natural) + → { mapKey = "ascii", mapValue = Prelude.Natural.show _ } + , Char = λ(_ : Text) → { mapKey = "char", mapValue = _ } + , Code = + λ(_ : Natural) + → { mapKey = "code", mapValue = Prelude.Natural.show _ } + } + x.mapValue + , { mapKey = "name", mapValue = x.mapKey } + ] + } + +let mapToXML = + λ(map : Map.Type) + → XML.element + { name = "map" + , attributes = toMap + { mod1 = boolToAttr map.mod1 + , mod2 = boolToAttr map.mod2 + , mod3 = boolToAttr map.mod3 + , mod4 = boolToAttr map.mod4 + } + , content = + Prelude.List.map + (Prelude.Map.Entry Text Key) + XML.Type + keyToXML + map.keys + } + +let qwerty = + [ Map::{ + , mod1 = False + , mod2 = False + , mod3 = False + , mod4 = False + , keys = toMap + { KEY_1 = Key.Code 49 + , KEY_2 = Key.Code 50 + , KEY_3 = Key.Code 51 + , KEY_4 = Key.Code 52 + , KEY_5 = Key.Code 53 + , KEY_6 = Key.Code 54 + , KEY_7 = Key.Code 55 + , KEY_8 = Key.Code 56 + , KEY_9 = Key.Code 57 + , KEY_0 = Key.Code 48 + , KEY_MINUS = Key.Code 45 + , KEY_EQUAL = Key.Code 61 + , KEY_Q = Key.Code 113 + , KEY_W = Key.Code 119 + , KEY_E = Key.Code 101 + , KEY_R = Key.Code 114 + , KEY_T = Key.Code 116 + , KEY_Y = Key.Code 121 + , KEY_U = Key.Code 117 + , KEY_I = Key.Code 105 + , KEY_O = Key.Code 111 + , KEY_P = Key.Code 112 + , KEY_LEFTBRACE = Key.Code 91 + , KEY_RIGHTBRACE = Key.Code 93 + , KEY_A = Key.Code 97 + , KEY_S = Key.Code 115 + , KEY_D = Key.Code 100 + , KEY_F = Key.Code 102 + , KEY_G = Key.Code 103 + , KEY_H = Key.Code 104 + , KEY_J = Key.Code 106 + , KEY_K = Key.Code 107 + , KEY_L = Key.Code 108 + , KEY_SEMICOLON = Key.Code 59 + , KEY_APOSTROPHE = Key.Code 39 + , KEY_GRAVE = Key.Code 96 + , KEY_BACKSLASH = Key.Code 92 + , KEY_Z = Key.Code 122 + , KEY_X = Key.Code 120 + , KEY_C = Key.Code 99 + , KEY_V = Key.Code 118 + , KEY_B = Key.Code 98 + , KEY_N = Key.Code 110 + , KEY_M = Key.Code 109 + , KEY_COMMA = Key.Code 44 + , KEY_DOT = Key.Code 46 + , KEY_SLASH = Key.Code 47 + , KEY_KPASTERISK = Key.Code 42 + , KEY_SPACE = Key.Code 32 + , KEY_KP7 = Key.Code 55 + , KEY_KP8 = Key.Code 56 + , KEY_KP9 = Key.Code 57 + , KEY_KPMINUS = Key.Code 45 + , KEY_KP4 = Key.Code 52 + , KEY_KP5 = Key.Code 53 + , KEY_KP6 = Key.Code 54 + , KEY_KPPLUS = Key.Code 43 + , KEY_KP1 = Key.Code 49 + , KEY_KP2 = Key.Code 50 + , KEY_KP3 = Key.Code 51 + , KEY_KP0 = Key.Code 48 + , KEY_KPDOT = Key.Code 46 + , KEY_102ND = Key.Code 60 + , KEY_KPSLASH = Key.Code 47 + , KEY_ESC = Key.Ascii 27 + , KEY_BACKSPACE = Key.Ascii 8 + , KEY_TAB = Key.Ascii 9 + , KEY_ENTER = Key.Ascii 10 + , KEY_KPENTER = Key.Ascii 10 + , KEY_DELETE = Key.Ascii 127 + } + } + , Map::{ + , mod1 = True + , mod2 = False + , mod3 = False + , mod4 = False + , keys = toMap + { KEY_1 = Key.Code 33 + , KEY_2 = Key.Code 64 + , KEY_3 = Key.Code 35 + , KEY_4 = Key.Code 36 + , KEY_5 = Key.Code 37 + , KEY_6 = Key.Code 94 + , KEY_7 = Key.Code 38 + , KEY_8 = Key.Code 42 + , KEY_9 = Key.Code 40 + , KEY_0 = Key.Code 41 + , KEY_MINUS = Key.Code 95 + , KEY_EQUAL = Key.Code 43 + , KEY_Q = Key.Code 81 + , KEY_W = Key.Code 87 + , KEY_E = Key.Code 69 + , KEY_R = Key.Code 82 + , KEY_T = Key.Code 84 + , KEY_Y = Key.Code 89 + , KEY_U = Key.Code 85 + , KEY_I = Key.Code 73 + , KEY_O = Key.Code 79 + , KEY_P = Key.Code 80 + , KEY_LEFTBRACE = Key.Code 123 + , KEY_RIGHTBRACE = Key.Code 125 + , KEY_A = Key.Code 65 + , KEY_S = Key.Code 83 + , KEY_D = Key.Code 68 + , KEY_F = Key.Code 70 + , KEY_G = Key.Code 71 + , KEY_H = Key.Code 72 + , KEY_J = Key.Code 74 + , KEY_K = Key.Code 75 + , KEY_L = Key.Code 76 + , KEY_SEMICOLON = Key.Code 58 + , KEY_APOSTROPHE = Key.Code 34 + , KEY_GRAVE = Key.Code 126 + , KEY_BACKSLASH = Key.Code 124 + , KEY_Z = Key.Code 90 + , KEY_X = Key.Code 88 + , KEY_C = Key.Code 67 + , KEY_V = Key.Code 86 + , KEY_B = Key.Code 66 + , KEY_N = Key.Code 78 + , KEY_M = Key.Code 77 + , KEY_COMMA = Key.Code 60 + , KEY_DOT = Key.Code 62 + , KEY_SLASH = Key.Code 63 + , KEY_KPASTERISK = Key.Code 42 + , KEY_KPMINUS = Key.Code 45 + , KEY_KPPLUS = Key.Code 43 + , KEY_102ND = Key.Code 62 + , KEY_KPSLASH = Key.Code 47 + } + } + , Map::{ + , mod1 = False + , mod2 = False + , mod3 = True + , mod4 = False + , keys = toMap { KEY_5 = Key.Code 8364, KEY_102ND = Key.Code 124 } + } + , Map::{ + , mod1 = False + , mod2 = False + , mod3 = False + , mod4 = True + , keys = toMap + { KEY_Q = Key.Code 81 + , KEY_W = Key.Code 87 + , KEY_E = Key.Code 69 + , KEY_R = Key.Code 82 + , KEY_T = Key.Code 84 + , KEY_Y = Key.Code 89 + , KEY_U = Key.Code 85 + , KEY_I = Key.Code 73 + , KEY_O = Key.Code 79 + , KEY_P = Key.Code 80 + , KEY_A = Key.Code 65 + , KEY_S = Key.Code 83 + , KEY_D = Key.Code 68 + , KEY_F = Key.Code 70 + , KEY_G = Key.Code 71 + , KEY_H = Key.Code 72 + , KEY_J = Key.Code 74 + , KEY_K = Key.Code 75 + , KEY_L = Key.Code 76 + , KEY_Z = Key.Code 90 + , KEY_X = Key.Code 88 + , KEY_C = Key.Code 67 + , KEY_V = Key.Code 86 + , KEY_B = Key.Code 66 + , KEY_N = Key.Code 78 + , KEY_M = Key.Code 77 + } + } + , Map::{ + , mod1 = True + , mod2 = False + , mod3 = False + , mod4 = True + , keys = toMap + { KEY_1 = Key.Code 33 + , KEY_2 = Key.Code 64 + , KEY_3 = Key.Code 35 + , KEY_4 = Key.Code 36 + , KEY_5 = Key.Code 37 + , KEY_6 = Key.Code 94 + , KEY_7 = Key.Code 38 + , KEY_8 = Key.Code 42 + , KEY_9 = Key.Code 40 + , KEY_0 = Key.Code 41 + , KEY_MINUS = Key.Code 95 + , KEY_EQUAL = Key.Code 43 + , KEY_Q = Key.Code 113 + , KEY_W = Key.Code 119 + , KEY_E = Key.Code 101 + , KEY_R = Key.Code 114 + , KEY_T = Key.Code 116 + , KEY_Y = Key.Code 121 + , KEY_U = Key.Code 117 + , KEY_I = Key.Code 105 + , KEY_O = Key.Code 111 + , KEY_P = Key.Code 112 + , KEY_LEFTBRACE = Key.Code 123 + , KEY_RIGHTBRACE = Key.Code 125 + , KEY_A = Key.Code 97 + , KEY_S = Key.Code 115 + , KEY_D = Key.Code 100 + , KEY_F = Key.Code 102 + , KEY_G = Key.Code 103 + , KEY_H = Key.Code 104 + , KEY_J = Key.Code 106 + , KEY_K = Key.Code 107 + , KEY_L = Key.Code 108 + , KEY_SEMICOLON = Key.Code 58 + , KEY_APOSTROPHE = Key.Code 34 + , KEY_GRAVE = Key.Code 126 + , KEY_BACKSLASH = Key.Code 124 + , KEY_Z = Key.Code 122 + , KEY_X = Key.Code 120 + , KEY_C = Key.Code 99 + , KEY_V = Key.Code 118 + , KEY_B = Key.Code 98 + , KEY_N = Key.Code 110 + , KEY_M = Key.Code 109 + , KEY_COMMA = Key.Code 60 + , KEY_DOT = Key.Code 62 + , KEY_SLASH = Key.Code 63 + , KEY_102ND = Key.Code 62 + } + } + ] + +in Prelude.List.map Map.Type XML.Type mapToXML qwerty diff --git a/nixos-modules/dhall/root.dhall b/nixos-modules/dhall/root.dhall new file mode 100644 index 0000000..c2e5c5b --- /dev/null +++ b/nixos-modules/dhall/root.dhall @@ -0,0 +1,718 @@ +-- SPDX-License-Identifier: CC0-1.0 + +let Genode = env:DHALL_GENODE + +let Prelude = Genode.Prelude + +let XML = Prelude.XML + +let Init = Genode.Init + +let Child = Init.Child + +let Resources = Init.Resources + +let ServiceRoute = Init.ServiceRoute + +let Policy = Init.Config.Policy + +let DefaultPolicy = Init.Config.DefaultPolicy + +let LabelSelector = Init.LabelSelector + +let label = + λ(label : Text) + → { local = label, route = label } : Child.Attributes.Label + +let routeLogRom = + λ(label : Text) → ServiceRoute.parentLabel "ROM" (Some "log") (Some label) + +let rootInit = + λ ( params + : { fbDriver : Init.Child.Type + , guests : Init.Children.Type + , inputFilterChargens : List XML.Type + , partitionType : Text + , wm : Init.Type + } + ) + → Init::{ + , children = toMap + { timer = + Child.flat + Child.Attributes::{ + , binary = "timer_drv" + , provides = [ "Timer" ] + } + , rtc = + Child.flat + Child.Attributes::{ + , binary = "rtc_drv" + , provides = [ "Rtc" ] + , routes = + [ ServiceRoute.parent "IO_PORT" + , ServiceRoute.parent "IO_MEM" + ] + } + , acpi_drv = + Child.flat + Child.Attributes::{ + , binary = "acpi_drv" + , priority = 1 + , resources = Resources::{ + , caps = 350 + , ram = Genode.units.MiB 4 + } + , romReports = [ label "acpi", label "smbios_table" ] + , routes = [ ServiceRoute.parent "IO_MEM" ] + } + , platform_drv = + Child.flat + Child.Attributes::{ + , binary = "platform_drv" + , resources = Resources::{ + , caps = 400 + , ram = Genode.units.MiB 4 + , constrainPhys = True + } + , reportRoms = [ label "acpi" ] + , romReports = [ label "pci" ] + , provides = [ "Acpi", "Platform" ] + , routes = + [ ServiceRoute.parent "IRQ" + , ServiceRoute.parent "IO_MEM" + , ServiceRoute.parent "IO_PORT" + , ServiceRoute.parentLabel + "ROM" + (Some "system") + (Some "system") + ] + , config = Init.Config::{ + , attributes = toMap { system = "yes" } + , content = + let PciPolicy/Type = + { labelSuffix : Text, pciClass : Text } + + in [ XML.text + '' + + + + + + + + + + + + + + + '' + ] + # Prelude.List.map + PciPolicy/Type + XML.Type + ( λ(policy : PciPolicy/Type) + → XML.element + { name = "policy" + , attributes = toMap + { label_suffix = policy.labelSuffix } + , content = + [ XML.leaf + { name = "pci" + , attributes = toMap + { class = policy.pciClass } + } + ] + } + ) + [ { labelSuffix = "ahci_drv" + , pciClass = "AHCI" + } + , { labelSuffix = "nic_drv" + , pciClass = "ETHERNET" + } + , { labelSuffix = "usb_drv", pciClass = "USB" } + , { labelSuffix = "vesa_fb_drv" + , pciClass = "VGA" + } + ] + } + } + , framebuffer = params.fbDriver + , input_filter = + Child.flat + Child.Attributes::{ + , binary = "input_filter" + , config = + let key = + λ(name : Text) + → XML.leaf + { name = "key" + , attributes = toMap { name = name } + } + + let remap = + λ(name : Text) + → λ(to : Text) + → XML.leaf + { name = "key" + , attributes = toMap { name = name, to = to } + } + + in Init.Config::{ + , content = + [ XML.leaf + { name = "input" + , attributes = toMap { label = "ps2" } + } + , XML.leaf + { name = "input" + , attributes = toMap { label = "usb" } + } + , XML.element + { name = "output" + , attributes = XML.emptyAttributes + , content = + [ XML.element + { name = "chargen" + , attributes = XML.emptyAttributes + , content = + [ XML.element + { name = "remap" + , attributes = + XML.emptyAttributes + , content = + [ remap + "KEY_LEFTMETA" + "KEY_SCREEN" + , XML.element + { name = "merge" + , attributes = + XML.emptyAttributes + , content = + [ XML.leaf + { name = "input" + , attributes = toMap + { name = "ps2" } + } + , XML.leaf + { name = "input" + , attributes = toMap + { name = "usb" } + } + ] + } + ] + } + , XML.element + { name = "mod1" + , attributes = + XML.emptyAttributes + , content = + [ key "KEY_LEFTSHIFT" + , key "KEY_RIGHTSHIFT" + ] + } + , XML.element + { name = "mod2" + , attributes = + XML.emptyAttributes + , content = + [ key "KEY_LEFTCTRL" + , key "KEY_RIGHTCTRL" + ] + } + , XML.element + { name = "mod3" + , attributes = + XML.emptyAttributes + , content = + [ key "KEY_RIGHTALT" ] + } + ] + # params.inputFilterChargens + } + ] + } + ] + } + , provides = [ "Input" ] + , routes = + [ ServiceRoute.parentLabel + "ROM" + (Some "config") + (Some "config -> input_filter.config") + , ServiceRoute.childLabel + "Input" + "ps2_drv" + (Some "ps2") + (None Text) + , ServiceRoute.childLabel + "Input" + "usb_drv" + (Some "usb") + (None Text) + ] + } + , ps2_drv = + Child.flat + Child.Attributes::{ + , binary = "ps2_drv" + , provides = [ "Input" ] + , routes = + [ ServiceRoute.childLabel + "Platform" + "platform_drv" + (None Text) + (Some "ps2_drv") + ] + } + , usb_drv = + Child.flat + Child.Attributes::{ + , binary = "usb_drv" + , config = Init.Config::{ + , attributes = toMap + { uhci = "yes" + , ohci = "yes" + , ehci = "yes" + , xhci = "yes" + , bios_handoff = "yes" + } + , content = + [ XML.leaf + { name = "hid", attributes = XML.emptyAttributes } + ] + } + , provides = [ "Input" ] + , resources = Init.Resources::{ + , caps = 128 + , ram = Genode.units.MiB 12 + } + , routes = + [ ServiceRoute.childLabel + "Platform" + "platform_drv" + (None Text) + (Some "usb_drv") + ] + } + , wm = + Init.toChild + params.wm + Init.Attributes::{ + , provides = [ "Nitpicker", "Report", "ROM" ] + , romReports = [ label "clipboard", label "shape" ] + , routes = + [ ServiceRoute.child "Framebuffer" "framebuffer" + , ServiceRoute.child "Input" "input_filter" + ] + } + , fonts_fs = + Child.flat + Child.Attributes::{ + , binary = "vfs" + , config = Init.Config::{ + , content = + [ XML.element + { name = "vfs" + , attributes = XML.emptyAttributes + , content = + [ XML.leaf + { name = "rom" + , attributes = toMap + { name = "Inconsolata.ttf" } + } + , XML.element + { name = "dir" + , attributes = toMap { name = "fonts" } + , content = + [ XML.element + { name = "dir" + , attributes = toMap { name = "title" } + , content = + [ XML.leaf + { name = "ttf" + , attributes = toMap + { name = "regular" + , path = "/Inconsolata.ttf" + , size_px = "12" + } + } + ] + } + , XML.element + { name = "dir" + , attributes = toMap { name = "text" } + , content = + [ XML.leaf + { name = "ttf" + , attributes = toMap + { name = "regular" + , path = "/Inconsolata.ttf" + , size_px = "12" + } + } + ] + } + , XML.element + { name = "dir" + , attributes = toMap + { name = "annotation" } + , content = + [ XML.leaf + { name = "ttf" + , attributes = toMap + { name = "regular" + , path = "/Inconsolata.ttf" + , size_px = "12" + } + } + ] + } + , XML.element + { name = "dir" + , attributes = toMap + { name = "monospace" } + , content = + [ XML.leaf + { name = "ttf" + , attributes = toMap + { name = "regular" + , path = "/Inconsolata.ttf" + , size_px = "12" + } + } + ] + } + ] + } + ] + } + ] + , defaultPolicy = Some DefaultPolicy::{ + , attributes = toMap { root = "/fonts" } + } + } + , provides = [ "File_system" ] + , resources = Init.Resources::{ + , caps = 256 + , ram = Genode.units.MiB 12 + } + , routes = [ ServiceRoute.child "Block" "block_router" ] + } + , nit_fb = + Child.flat + Child.Attributes::{ + , binary = "nit_fb" + , config = Init.Config::{ + , attributes = toMap + { xpos = "600", width = "600", height = "768" } + } + , provides = [ "Framebuffer", "Input" ] + , resources = Resources::{ ram = Genode.units.MiB 8 } + , routes = + [ ServiceRoute.childLabel + "Nitpicker" + "wm" + (None Text) + (Some "log") + ] + } + , terminal = + Child.flat + Child.Attributes::{ + , binary = "terminal" + , config = Init.Config::{ + , content = + [ XML.element + { name = "vfs" + , attributes = XML.emptyAttributes + , content = + [ XML.element + { name = "dir" + , attributes = toMap { name = "fonts" } + , content = + [ XML.leaf + { name = "fs" + , attributes = toMap { label = "fonts" } + } + ] + } + ] + } + ] + } + , provides = [ "Terminal" ] + , resources = Resources::{ + , caps = 256 + , ram = Genode.units.MiB 4 + } + , routes = + [ ServiceRoute.child "Framebuffer" "nit_fb" + , ServiceRoute.child "Input" "nit_fb" + , ServiceRoute.child "File_system" "fonts_fs" + ] + } + , terminal_log = + Child.flat + Child.Attributes::{ + , binary = "terminal_log" + , provides = [ "LOG" ] + , routes = [ ServiceRoute.child "Terminal" "terminal" ] + } + , log_core = + Child.flat + Child.Attributes::{ + , binary = "log_core" + , routes = + [ routeLogRom "core_log" + , ServiceRoute.childLabel + "LOG" + "terminal_log" + (Some "log") + (Some "core") + ] + } + , log_kernel = + Child.flat + Child.Attributes::{ + , binary = "log_core" + , routes = + [ routeLogRom "kernel_log" + , ServiceRoute.childLabel + "LOG" + "terminal_log" + (Some "log") + (Some "kernel") + ] + } + , block = + Child.flat + Child.Attributes::{ + , binary = "ahci_drv" + , config = Init.Config::{ + , defaultPolicy = Some DefaultPolicy::{ + , attributes = toMap { device = "0", writeable = "yes" } + } + } + , provides = [ "Block" ] + , resources = Init.Resources::{ + , caps = 256 + , ram = Genode.units.MiB 10 + } + , routes = + [ ServiceRoute.childLabel + "Platform" + "platform_drv" + (None Text) + (Some "ahci_drv") + ] + } + , block_partitions = + Child.flat + Child.Attributes::{ + , binary = "part_block" + , config = Init.Config::{ + , content = + Prelude.List.map + Natural + XML.Type + ( λ(i : Natural) + → XML.leaf + { name = "policy" + , attributes = + let partition = + Prelude.Natural.show (i + 1) + + in toMap + { label_suffix = " ${partition}" + , partition = partition + , writeable = "yes" + } + } + ) + (Prelude.Natural.enumerate 128) + # [ XML.leaf + { name = "report" + , attributes = toMap { partitions = "yes" } + } + ] + } + , resources = Resources::{ + , caps = 256 + , ram = Genode.units.MiB 8 + } + , provides = [ "Block" ] + , routes = + [ ServiceRoute.child "Block" "block" + , ServiceRoute.child "Report" "block_router" + ] + } + , block_router = + Child.flat + Child.Attributes::{ + , binary = "block_router" + , config = Init.Config::{ + , attributes = toMap { verbose = "yes" } + , content = + [ XML.element + { name = "default-policy" + , attributes = XML.emptyAttributes + , content = + [ XML.leaf + { name = "partition" + , attributes = toMap + { type = params.partitionType + , writeable = "yes" + } + } + ] + } + ] + } + , resources = Resources::{ + , caps = 256 + , ram = Genode.units.MiB 8 + } + , provides = [ "Block", "Report" ] + , routes = [ ServiceRoute.child "Block" "block_partitions" ] + } + , file_system = + Child.flat + Child.Attributes::{ + , binary = "vfs" + , config = Init.Config::{ + , content = + [ XML.element + { name = "vfs" + , attributes = XML.emptyAttributes + , content = + [ XML.element + { name = "dir" + , attributes = toMap { name = "ext2" } + , content = + [ XML.leaf + { name = "rump" + , attributes = toMap + { fs = "ext2fs" + , writeable = "yes" + , ram = "8M" + } + } + ] + } + ] + } + ] + , policies = + [ Policy::{ + , label = LabelSelector.suffix "nix/store" + , attributes = toMap + { root = "/ext2/nix/store", writeable = "no" } + } + , Policy::{ + , label = LabelSelector.prefix "chroot" + , attributes = toMap + { root = "/ext2", writeable = "yes" } + } + , Policy::{ + , label = LabelSelector.prefix "init -> console" + , attributes = toMap { root = "/", writeable = "yes" } + } + ] + } + , provides = [ "File_system" ] + , resources = Init.Resources::{ + , caps = 256 + , ram = Genode.units.MiB 12 + } + , routes = [ ServiceRoute.child "Block" "block_router" ] + } + , chroot = + Child.flat + Child.Attributes::{ + , binary = "chroot" + , config = Init.Config::{ + , defaultPolicy = Some DefaultPolicy::{ + , attributes = toMap { writeable = "yes" } + } + } + , provides = [ "File_system" ] + , routes = [ ServiceRoute.child "File_system" "file_system" ] + } + , nic_drv = + Child.flat + Child.Attributes::{ + , binary = "ipxe_nic_drv" + , provides = [ "Nic" ] + , resources = Init.Resources::{ + , caps = 128 + , ram = Genode.units.MiB 4 + } + , routes = + [ ServiceRoute.childLabel + "Platform" + "platform_drv" + (None Text) + (Some "nic_drv") + ] + } + , init = + Init.toChild + Init::{ children = params.guests } + Init.Attributes::{ + , routes = + [ ServiceRoute.parent "VM" + , ServiceRoute.child "Nitpicker" "wm" + , { service = + { name = "File_system" + , label = LabelSelector.last "fonts" + } + , route = + Init.Route.Type.Child + { name = "fonts_fs" + , label = None Text + , diag = None Bool + } + } + , { service = + { name = "File_system" + , label = LabelSelector.suffix "nix/store" + } + , route = + Init.Route.Type.Child + { name = "file_system" + , label = Some "nix/store" + , diag = None Bool + } + } + , { service = + { name = "File_system" + , label = LabelSelector.prefix "console" + } + , route = + Init.Route.Type.Child + { name = "file_system" + , label = None Text + , diag = None Bool + } + } + , ServiceRoute.child "File_system" "chroot" + , ServiceRoute.child "Nic" "nic_drv" + , ServiceRoute.child "Rtc" "rtc" + , ServiceRoute.parentLabel + "ROM" + (Some "platform_info") + (Some "platform_info") + , ServiceRoute.child "Report" "_report_rom" + ] + } + } + , routes = [ ServiceRoute.child "Timer" "timer" ] + } + +in rootInit diff --git a/nixos-modules/dhall/show_input.dhall b/nixos-modules/dhall/show_input.dhall new file mode 100644 index 0000000..3ad9699 --- /dev/null +++ b/nixos-modules/dhall/show_input.dhall @@ -0,0 +1,43 @@ +-- SPDX-License-Identifier: CC0-1.0 + +let Genode = env:DHALL_GENODE + +let Prelude = Genode.Prelude + +let XML = Prelude.XML + +let Init = Genode.Init + +let Child = Init.Child + +let Resources = Init.Resources + +let ServiceRoute = Init.ServiceRoute + +in Child.flat + Child.Attributes::{ + , binary = "show_input" + , config = Init.Config::{ + , content = + [ XML.element + { name = "vfs" + , attributes = XML.emptyAttributes + , content = + [ XML.element + { name = "dir" + , attributes = toMap { name = "fonts" } + , content = + [ XML.leaf + { name = "fs" + , attributes = toMap { label = "fonts" } + } + ] + } + ] + } + ] + } + , resources = Resources::{ ram = Genode.units.MiB 32 } + , routes = + [ ServiceRoute.parent "File_system", ServiceRoute.parent "Nitpicker" ] + } diff --git a/nixos-modules/dhall/vbox-guest.dhall b/nixos-modules/dhall/vbox-guest.dhall new file mode 100644 index 0000000..bd6bb31 --- /dev/null +++ b/nixos-modules/dhall/vbox-guest.dhall @@ -0,0 +1,163 @@ +-- SPDX-License-Identifier: CC0-1.0 + +let Genode = env:DHALL_GENODE + +let Prelude = Genode.Prelude + +let XML = Prelude.XML + +let Init = Genode.Init + +let Child = Init.Child + +let Resources = Init.Resources + +let ServiceRoute = Init.ServiceRoute + +let Vfs/inline = + λ(name : Text) + → λ(body : Text) + → XML.element + { name = "inline" + , attributes = toMap { name = name } + , content = [ XML.text body ] + } + +let toVbox = + λ ( params + : { vdiFilename : Text + , vdiPkg : Text + , vdiUuid : Text + , memorySize : Natural + , vmName : Text + } + ) + → let vboxConfig = + '' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '' + + in Child.flat + Child.Attributes::{ + , binary = "virtualbox5" + , config = Init.Config::{ + , attributes = toMap + { vbox_file = "machine.vbox", vm_name = params.vmName } + , content = + [ XML.leaf + { name = "libc" + , attributes = toMap + { stdout = "/dev/log" + , stderr = "/dev/log" + , rtc = "/dev/rtc" + } + } + , XML.element + { name = "vfs" + , attributes = XML.emptyAttributes + , content = + let tag = + λ(name : Text) + → XML.leaf + { name = name + , attributes = XML.emptyAttributes + } + + in [ Vfs/inline "machine.vbox" vboxConfig + , XML.element + { name = "dir" + , attributes = toMap { name = "dev" } + , content = [ tag "log", tag "rtc" ] + } + , XML.leaf + { name = "fs" + , attributes = toMap { writeable = "yes" } + } + , XML.element + { name = "import" + , attributes = toMap { overwrite = "no" } + , content = + [ XML.leaf + { name = "fs" + , attributes = toMap + { label = "nix/store" + , root = "${params.vdiPkg}" + } + } + ] + } + ] + } + ] + } + , resources = Resources::{ + , caps = 1024 + , ram = + Genode.units.MiB 128 + Genode.units.MiB params.memorySize + } + , routes = + [ ServiceRoute.parent "File_system" + , ServiceRoute.parent "Nic" + , ServiceRoute.parent "Nitpicker" + , ServiceRoute.parent "Rtc" + , ServiceRoute.parent "Timer" + , ServiceRoute.parent "VM" + , ServiceRoute.parent "Report" + , ServiceRoute.parentLabel + "ROM" + (Some "platform_info") + (Some "platform_info") + ] + } + +in toVbox diff --git a/nixos-modules/dhall/vesa_fb_drv.dhall b/nixos-modules/dhall/vesa_fb_drv.dhall new file mode 100644 index 0000000..50c7daa --- /dev/null +++ b/nixos-modules/dhall/vesa_fb_drv.dhall @@ -0,0 +1,27 @@ +let Genode = env:DHALL_GENODE + +let ServiceRoute = Genode.Init.ServiceRoute + +let Child = Genode.Init.Child + +in Child.flat + Child.Attributes::{ + , binary = "vesa_fb_drv" + , config = Genode.Init.Config::{ + , attributes = toMap { width = "1024", height = "768" } + } + , provides = [ "Framebuffer" ] + , resources = Genode.Init.Resources::{ + , caps = 256 + , ram = Genode.units.MiB 16 + } + , routes = + [ ServiceRoute.parent "IO_MEM" + , ServiceRoute.parent "IO_PORT" + , ServiceRoute.childLabel + "Platform" + "platform_drv" + (None Text) + (Some "vesa_fb_drv") + ] + } diff --git a/nixos-modules/dhall/wm.dhall b/nixos-modules/dhall/wm.dhall new file mode 100644 index 0000000..02aee6e --- /dev/null +++ b/nixos-modules/dhall/wm.dhall @@ -0,0 +1,237 @@ +-- SPDX-License-Identifier: CC0-1.0 + +let Genode = env:DHALL_GENODE + +let Prelude = Genode.Prelude + +let XML = Prelude.XML + +let Init = Genode.Init + +let Child = Init.Child + +let Resources = Init.Resources + +let ServiceRoute = Init.ServiceRoute + +let Policy = Init.Config.Policy + +let DefaultPolicy = Init.Config.DefaultPolicy + +let LabelSelector = Init.LabelSelector + +let label = + λ(label : Text) + → { local = label, route = label } : Child.Attributes.Label + +in Init::{ + , children = toMap + { nitpicker = + Child.flat + Child.Attributes::{ + , binary = "nitpicker" + , config = Init.Config::{ + , attributes = toMap { focus = "rom" } + , content = + [ XML.text + '' + + + + + + + '' + ] + , policies = + [ Policy::{ + , label = LabelSelector.prefix "pointer" + , attributes = toMap { domain = "pointer" } + } + , Policy::{ + , label = LabelSelector.suffix "-> decorator" + , attributes = toMap { domain = "decorator" } + } + , Policy::{ + , label = LabelSelector.prefix "wm" + , attributes = toMap { domain = "desktop" } + } + , Policy::{ + , label = LabelSelector.label "backdrop" + , attributes = toMap { domain = "backdrop" } + } + ] + , defaultPolicy = Some DefaultPolicy::{ + , attributes = toMap { domain = "default" } + } + } + , provides = [ "Nitpicker" ] + , resources = Resources::{ caps = 256, ram = Genode.units.MiB 64 } + , routes = + [ ServiceRoute.parent "Framebuffer" + , ServiceRoute.parent "Input" + ] + } + , pointer = + Child.flat + Child.Attributes::{ + , binary = "pointer" + , routes = [ ServiceRoute.child "Nitpicker" "nitpicker" ] + } + , wm = + Child.flat + Child.Attributes::{ + , binary = "wm" + , config = Init.Config::{ + , policies = + [ Policy::{ + , attributes = toMap { role = "decorator" } + , label = LabelSelector.prefix "decorator" + } + , Policy::{ + , attributes = toMap { role = "layouter" } + , label = LabelSelector.prefix "layouter" + } + ] + , defaultPolicy = Some DefaultPolicy::{=} + } + , provides = [ "Nitpicker", "Report", "ROM" ] + , reportRoms = [ label "focus", label "resize_request" ] + , romReports = + [ label "focus_request" + , label "pointer" + , label "shape" + , label "window_list" + ] + , resources = Init.Resources::{ + , caps = 256 + , ram = Genode.units.MiB 8 + } + , routes = + [ ServiceRoute.childLabel + "Nitpicker" + "nitpicker" + (Some "") + (Some "focus") + , ServiceRoute.child "Nitpicker" "nitpicker" + , ServiceRoute.parentLabel + "Report" + (Some "clipboard") + (Some "clipboard") + , ServiceRoute.parentLabel + "Report" + (Some "shape") + (Some "shape") + ] + } + , layouter = + Child.flat + Child.Attributes::{ + , binary = "window_layouter" + , config = Init.Config::{ + , attributes = toMap { rules = "rom" } + , content = + [ XML.text + '' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '' + ] + } + , provides = [ "Nitpicker", "Report", "ROM" ] + , romReports = + [ label "focus" + , label "resize_request" + , label "rules" + , label "window_layout" + ] + , reportRoms = + [ label "decorator_margins" + , label "focus_request" + , label "hover" + , label "rules" + , label "shape" + , label "window_list" + ] + , resources = Init.Resources::{ + , caps = 256 + , ram = Genode.units.MiB 8 + } + , routes = [ ServiceRoute.child "Nitpicker" "wm" ] + } + , decorator = + Child.flat + Child.Attributes::{ + , binary = "decorator" + , config = Init.Config::{ + , content = + [ XML.element + { name = "controls" + , attributes = XML.emptyAttributes + , content = + [ XML.leaf + { name = "maximizer" + , attributes = XML.emptyAttributes + } + , XML.leaf + { name = "title", attributes = XML.emptyAttributes } + ] + } + ] + , defaultPolicy = Some DefaultPolicy::{=} + } + , provides = [ "Nitpicker", "Report", "ROM" ] + , reportRoms = [ label "window_layout", label "pointer" ] + , romReports = [ label "decorator_margins", label "hover" ] + , resources = Init.Resources::{ + , caps = 128 + , ram = Genode.units.MiB 12 + } + , routes = [ ServiceRoute.child "Nitpicker" "wm" ] + } + } + , routes = [ ServiceRoute.parent "Timer" ] + , services = + [ ServiceRoute.child "Nitpicker" "wm" + , ServiceRoute.child "Report" "wm" + , ServiceRoute.child "ROM" "wm" + ] + } diff --git a/nixos-modules/dhall/workman.chargen.dhall b/nixos-modules/dhall/workman.chargen.dhall new file mode 100644 index 0000000..fa83045 --- /dev/null +++ b/nixos-modules/dhall/workman.chargen.dhall @@ -0,0 +1,245 @@ +let Genode = env:DHALL_GENODE + +let Prelude = Genode.Prelude + +let XML = Prelude.XML + +let Key = < Ascii : Natural | Char : Text | Code : Natural > : Type + +let Map = + { Type = + { keys : Prelude.Map.Type Text Key + , mod1 : Bool + , mod2 : Bool + , mod3 : Bool + , mod4 : Bool + } + , default = { mod1 = False, mod2 = False, mod3 = False, mod4 = False } + } + +let boolToAttr = λ(_ : Bool) → if _ then "yes" else "no" + +let keyToXML = + λ(x : Prelude.Map.Entry Text Key) + → XML.leaf + { name = "key" + , attributes = + [ merge + { Ascii = + λ(_ : Natural) + → { mapKey = "ascii", mapValue = Prelude.Natural.show _ } + , Char = λ(_ : Text) → { mapKey = "char", mapValue = _ } + , Code = + λ(_ : Natural) + → { mapKey = "code", mapValue = Prelude.Natural.show _ } + } + x.mapValue + , { mapKey = "name", mapValue = x.mapKey } + ] + } + +let mapToXML = + λ(map : Map.Type) + → XML.element + { name = "map" + , attributes = toMap + { mod1 = boolToAttr map.mod1 + , mod2 = boolToAttr map.mod2 + , mod3 = boolToAttr map.mod3 + , mod4 = boolToAttr map.mod4 + } + , content = + Prelude.List.map + (Prelude.Map.Entry Text Key) + XML.Type + keyToXML + map.keys + } + +let workman = + [ Map::{ + , keys = toMap + { KEY_ESC = Key.Ascii 27 + , KEY_1 = Key.Char "1" + , KEY_2 = Key.Char "2" + , KEY_3 = Key.Char "3" + , KEY_4 = Key.Char "4" + , KEY_5 = Key.Char "5" + , KEY_6 = Key.Char "6" + , KEY_7 = Key.Char "7" + , KEY_8 = Key.Char "8" + , KEY_9 = Key.Char "9" + , KEY_0 = Key.Char "0" + , KEY_MINUS = Key.Char "-" + , KEY_EQUAL = Key.Char "=" + , KEY_BACKSPACE = Key.Ascii 8 + , KEY_TAB = Key.Ascii 9 + , KEY_Q = Key.Char "q" + , KEY_W = Key.Char "d" + , KEY_E = Key.Char "r" + , KEY_R = Key.Char "w" + , KEY_T = Key.Char "b" + , KEY_Y = Key.Char "j" + , KEY_U = Key.Char "f" + , KEY_I = Key.Char "u" + , KEY_O = Key.Char "p" + , KEY_P = Key.Char ";" + , KEY_LEFTBRACE = Key.Char "[" + , KEY_RIGHTBRACE = Key.Char "]" + , KEY_ENTER = Key.Ascii 10 + , KEY_A = Key.Char "a" + , KEY_S = Key.Char "s" + , KEY_D = Key.Char "h" + , KEY_F = Key.Char "t" + , KEY_G = Key.Char "g" + , KEY_H = Key.Char "y" + , KEY_J = Key.Char "n" + , KEY_K = Key.Char "e" + , KEY_L = Key.Char "o" + , KEY_SEMICOLON = Key.Char "i" + , KEY_APOSTROPHE = Key.Char "'" + , KEY_GRAVE = Key.Char "`" + , KEY_BACKSLASH = Key.Ascii 92 + , KEY_Z = Key.Char "z" + , KEY_X = Key.Char "x" + , KEY_C = Key.Char "m" + , KEY_V = Key.Char "c" + , KEY_B = Key.Char "v" + , KEY_N = Key.Char "k" + , KEY_M = Key.Char "l" + , KEY_COMMA = Key.Char "," + , KEY_DOT = Key.Char "." + , KEY_SLASH = Key.Char "/" + , KEY_SPACE = Key.Char " " + , KEY_KP7 = Key.Char "7" + , KEY_KP8 = Key.Char "8" + , KEY_KP9 = Key.Char "9" + , KEY_KPMINUS = Key.Char "-" + , KEY_KP4 = Key.Char "4" + , KEY_KP5 = Key.Char "5" + , KEY_KP6 = Key.Char "6" + , KEY_KPPLUS = Key.Char "+" + , KEY_KP1 = Key.Char "1" + , KEY_KP2 = Key.Char "2" + , KEY_KP3 = Key.Char "3" + , KEY_KP0 = Key.Char "0" + , KEY_KPDOT = Key.Char "." + , KEY_KPENTER = Key.Ascii 10 + , KEY_KPSLASH = Key.Char "/" + } + } + , Map::{ + , mod1 = True + , keys = toMap + { KEY_1 = Key.Char "!" + , KEY_2 = Key.Char "@" + , KEY_3 = Key.Char "#" + , KEY_4 = Key.Char "\$" + , KEY_5 = Key.Char "%" + , KEY_6 = Key.Char "^" + , KEY_7 = Key.Ascii 38 + , KEY_8 = Key.Char "*" + , KEY_9 = Key.Char "(" + , KEY_0 = Key.Char ")" + , KEY_MINUS = Key.Char "_" + , KEY_EQUAL = Key.Char "+" + , KEY_Q = Key.Char "Q" + , KEY_W = Key.Char "D" + , KEY_E = Key.Char "R" + , KEY_R = Key.Char "W" + , KEY_T = Key.Char "B" + , KEY_Y = Key.Char "J" + , KEY_U = Key.Char "F" + , KEY_I = Key.Char "U" + , KEY_O = Key.Char "P" + , KEY_P = Key.Char ":" + , KEY_LEFTBRACE = Key.Char "{" + , KEY_RIGHTBRACE = Key.Char "}" + , KEY_A = Key.Char "A" + , KEY_S = Key.Char "S" + , KEY_D = Key.Char "H" + , KEY_F = Key.Char "T" + , KEY_G = Key.Char "G" + , KEY_H = Key.Char "Y" + , KEY_J = Key.Char "N" + , KEY_K = Key.Char "E" + , KEY_L = Key.Char "O" + , KEY_SEMICOLON = Key.Char "I" + , KEY_APOSTROPHE = Key.Ascii 34 + , KEY_GRAVE = Key.Char "~" + , KEY_BACKSLASH = Key.Char "|" + , KEY_Z = Key.Char "Z" + , KEY_X = Key.Char "X" + , KEY_C = Key.Char "M" + , KEY_V = Key.Char "C" + , KEY_B = Key.Char "V" + , KEY_N = Key.Char "K" + , KEY_M = Key.Char "L" + , KEY_COMMA = Key.Ascii 60 + , KEY_DOT = Key.Ascii 62 + , KEY_SLASH = Key.Char "?" + } + } + , Map::{ + , mod2 = True + , keys = toMap + { KEY_A = Key.Ascii 1 + , KEY_B = Key.Ascii 22 + , KEY_C = Key.Ascii 13 + , KEY_D = Key.Ascii 8 + , KEY_E = Key.Ascii 18 + , KEY_F = Key.Ascii 20 + , KEY_G = Key.Ascii 7 + , KEY_H = Key.Ascii 25 + , KEY_I = Key.Ascii 21 + , KEY_J = Key.Ascii 14 + , KEY_K = Key.Ascii 5 + , KEY_L = Key.Ascii 15 + , KEY_M = Key.Ascii 12 + , KEY_N = Key.Ascii 11 + , KEY_O = Key.Ascii 16 + , KEY_P = Key.Ascii 9 + , KEY_Q = Key.Ascii 17 + , KEY_R = Key.Ascii 23 + , KEY_S = Key.Ascii 19 + , KEY_T = Key.Ascii 2 + , KEY_U = Key.Ascii 6 + , KEY_V = Key.Ascii 3 + , KEY_W = Key.Ascii 4 + , KEY_X = Key.Ascii 24 + , KEY_Y = Key.Ascii 10 + , KEY_Z = Key.Ascii 26 + } + } + , Map::{ + , mod3 = True + , keys = toMap + { KEY_4 = Key.Code 8364 + , KEY_A = Key.Code 228 + , KEY_S = Key.Code 223 + , KEY_I = Key.Code 252 + , KEY_DOT = Key.Code 8230 + , KEY_K = Key.Code 235 + , KEY_C = Key.Code 181 + , KEY_L = Key.Code 246 + } + } + , Map::{ + , mod1 = True + , mod3 = True + , keys = toMap + { KEY_0 = Key.Code 8320 + , KEY_1 = Key.Code 8321 + , KEY_2 = Key.Code 8322 + , KEY_3 = Key.Code 8323 + , KEY_4 = Key.Code 8324 + , KEY_5 = Key.Code 8325 + , KEY_6 = Key.Code 8326 + , KEY_7 = Key.Code 8327 + , KEY_8 = Key.Code 8328 + , KEY_9 = Key.Code 8329 + } + } + ] + +in Prelude.List.map Map.Type XML.Type mapToXML workman