diff --git a/nixos-modules/gui/consoleLog.dhall b/nixos-modules/gui/consoleLog.dhall new file mode 100644 index 0000000..80ba1c4 --- /dev/null +++ b/nixos-modules/gui/consoleLog.dhall @@ -0,0 +1,162 @@ +let Genode = env:DHALL_GENODE + +let Prelude = Genode.Prelude + +let VFS = Genode.VFS + +let XML = Prelude.XML + +let Init = Genode.Init + +let Child = Init.Child + +let Resources = Init.Resources + +let ServiceRoute = Init.ServiceRoute + +let routeLogRom = + λ(label : Text) → ServiceRoute.parentLabel "ROM" (Some "log") (Some label) + +in λ(params : { fontFile : Text }) → + Init.toChild + Init::{ + , verbose = True + , routes = + [ Init.ServiceRoute.parent "Gui", Init.ServiceRoute.parent "Timer" ] + , children = toMap + { gui_fb = + Child.flat + Child.Attributes::{ + , binary = "gui_fb" + , exitPropagate = True + , resources = Resources::{ ram = Genode.units.MiB 8 } + , config = Init.Config::{ + , attributes = toMap + { origin = "top_right" + , xpos = "0" + , ypos = "0" + , initial_width = "1024" + , initial_height = "768" + } + , policies = + [ Init.Config.Policy::{ + , service = "Framebuffer" + , label = Init.LabelSelector.prefix "terminal" + } + , Init.Config.Policy::{ + , service = "Input" + , label = Init.LabelSelector.prefix "terminal" + } + ] + } + } + , terminal = + Child.flat + Child.Attributes::{ + , binary = "terminal" + , exitPropagate = True + , resources = Resources::{ + , caps = 256 + , ram = Genode.units.MiB 4 + } + , routes = + [ ServiceRoute.child "Framebuffer" "gui_fb" + , ServiceRoute.child "Input" "gui_fb" + , ServiceRoute.parent "File_system" + ] + , config = Init.Config::{ + , content = + [ XML.element + { name = "palette" + , attributes = toMap + { uri = "https://pippin.gimp.org/ametameric/" } + , content = + let color = + λ(index : Natural) → + λ(value : Text) → + XML.leaf + { name = "color" + , attributes = toMap + { index = Natural/show index + , value + } + } + + in [ color 0 "#000000" + , color 1 "#a02929" + , color 2 "#4aa08b" + , color 3 "#878453" + , color 4 "#2424ed" + , color 5 "#ab4adf" + , color 6 "#3b6bb1" + , color 7 "#c3c3c3" + , color 8 "#6f6f6f" + , color 9 "#edac82" + , color 10 "#99edba" + , color 11 "#e9d808" + , color 12 "#82b4ed" + , color 13 "#d66fed" + , color 14 "#1de1ed" + , color 15 "#ffffff" + ] + } + , VFS.vfs + [ VFS.leafAttrs + "rom" + (toMap { name = params.fontFile }) + , VFS.dir + "fonts" + [ VFS.dir + "monospace" + [ VFS.leafAttrs + "ttf" + ( toMap + { name = "regular" + , path = params.fontFile + , size_px = "10" + } + ) + ] + ] + ] + ] + , policies = + [ Init.Config.Policy::{ + , service = "Terminal" + , label = Init.LabelSelector.prefix "terminal_log" + } + ] + } + } + , terminal_log = + Child.flat + Child.Attributes::{ + , binary = "terminal_log" + , config = Init.Config::{ + , policies = + [ Init.Config.Policy::{ + , service = "LOG" + , label = Init.LabelSelector.prefix "core" + } + , Init.Config.Policy::{ + , service = "LOG" + , label = Init.LabelSelector.prefix "kernel" + } + ] + } + } + , core = + Child.flat + Child.Attributes::{ + , binary = "log_core" + , routes = [ routeLogRom "core_log" ] + } + , kernel = + Child.flat + Child.Attributes::{ + , binary = "log_core" + , routes = [ routeLogRom "kernel_log" ] + } + } + } + Init.Attributes.default diff --git a/nixos-modules/gui/default.nix b/nixos-modules/gui/default.nix new file mode 100644 index 0000000..79bc167 --- /dev/null +++ b/nixos-modules/gui/default.nix @@ -0,0 +1,56 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let cfg = config.genode.gui; +in { + options.genode.gui = { + enable = mkEnableOption "Genode Gui service"; + consoleLog = { enable = mkEnableOption "console log"; }; + }; + + config = { + + genode.gui.enable = cfg.consoleLog.enable; + + hardware.genode.framebuffer.enable = cfg.enable; + + genode.core.children.nitpicker = mkIf cfg.enable { + inputs = [ pkgs.genodePackages.nitpicker ]; + configFile = pkgs.writeText "nitpicker.dhall" '' + let Init = (env:DHALL_GENODE).Init + + in ${./nitpicker.dhall} + { policies = + [ Init.Config.Policy::{ + , service = "Gui" + , label = Init.LabelSelector.prefix "consoleLog" + , attributes = toMap { domain = "default" } + } + ] + } + ''; + }; + + genode.boot.romModules = mkIf cfg.consoleLog.enable { + "TerminusTTF.ttf" = pkgs.buildPackages.terminus_font_ttf + + "/share/fonts/truetype/TerminusTTF.ttf"; + }; + + genode.core.children.consoleLog = mkIf cfg.consoleLog.enable { + inputs = with pkgs.genodePackages; [ + gui_fb + log_core + libc + terminal + terminal_log + vfs_ttf + ]; + coreROMs = [ "core_log" "kernel_log" ]; + configFile = pkgs.writeText "consoleLog.dhall" '' + ${./consoleLog.dhall} { fontFile = "TerminusTTF.ttf" } + ''; + }; + + }; +} diff --git a/nixos-modules/gui/nitpicker.dhall b/nixos-modules/gui/nitpicker.dhall new file mode 100644 index 0000000..4847488 --- /dev/null +++ b/nixos-modules/gui/nitpicker.dhall @@ -0,0 +1,42 @@ +let Genode = env:DHALL_GENODE + +let XML = Genode.Prelude.XML + +let Init = Genode.Init + +in λ(params : { policies : List Init.Config.Policy.Type }) → + Init.Child.flat + Init.Child.Attributes::{ + , binary = "nitpicker" + , resources = Init.Resources::{ ram = Genode.units.MiB 4 } + , config = Init.Config::{ + , attributes = toMap + { note = "Nitpicker config is extremely fragile!" } + , content = + [ XML.leaf { name = "capture", attributes = XML.emptyAttributes } + , XML.leaf + { name = "domain" + , attributes = toMap + { name = "default" + , layer = "1" + , content = "client" + , label = "no" + } + } + , XML.leaf + { name = "background" + , attributes = toMap { color = "#000000" } + } + ] + , policies = + params.policies + # [ Init.Config.Policy::{ + , service = "Capture" + , label = Init.LabelSelector.prefix "fb_drv" + } + ] + , defaultPolicy = Some Init.Config.DefaultPolicy::{ + , attributes = toMap { domain = "default" } + } + } + } diff --git a/nixos-modules/hardware.nix b/nixos-modules/hardware.nix index 9ad92c3..36e458f 100644 --- a/nixos-modules/hardware.nix +++ b/nixos-modules/hardware.nix @@ -10,11 +10,15 @@ with lib; attrsOf (submodule ({ ... }: { options.genode = { - driver = mkOption { type = types.enum [ "ipxe" "virtio" ]; }; + driver = mkOption { + type = types.enum [ "ipxe" "virtio" ]; + description = "Nic driver to use for this interface."; + }; stack = mkOption { type = with types; nullOr (enum [ "lwip" "lxip" ]); default = "lwip"; + description = "IP stack to use for this interface."; }; }; @@ -30,10 +34,20 @@ with lib; ''; }; - hardware.usb.genode.enable = lib.mkEnableOption "USB driver"; + hardware.genode = { - hardware.usb.genode.storage.enable = - lib.mkEnableOption "USB mass storage driver"; + usb.enable = lib.mkEnableOption "USB driver"; + usb.storage.enable = lib.mkEnableOption "USB mass storage driver"; + + framebuffer = { + enable = lib.mkEnableOption "framebuffer driver"; + driver = mkOption { + type = types.enum [ "boot" "vesa" ]; + default = "vesa"; + }; + }; + + }; }; @@ -52,10 +66,10 @@ with lib; in lib.mapAttrsToList addrCheck config.networking.interfaces ++ lib.mapAttrsToList routeCheck config.networking.interfaces; - hardware.usb.genode.storage.enable = config.genode.boot.storeBackend + hardware.genode.usb.storage.enable = config.genode.boot.storeBackend == "usb"; - hardware.usb.genode.enable = config.hardware.usb.genode.storage.enable; + hardware.genode.usb.enable = config.hardware.genode.usb.storage.enable; hardware.genode.platform.policies = lib.lists.imap0 (i: name: builtins.toFile (name + ".platform-policy.dhall") '' @@ -75,7 +89,19 @@ with lib; ] } '') (builtins.attrNames config.networking.interfaces) - ++ lib.optional config.hardware.usb.genode.enable + ++ lib.optional config.hardware.genode.framebuffer.enable + (builtins.toFile ("framebuffer.platform-policy.dhall") '' + let Genode = env:DHALL_GENODE + + in Genode.Init.Config.Policy::{ + , service = "Platform" + , label = Genode.Init.LabelSelector.prefix "fb_drv" + , content = + [ Genode.Prelude.XML.leaf + { name = "pci", attributes = toMap { class = "VGA" } } + ] + } + '') ++ lib.optional config.hardware.genode.usb.enable (builtins.toFile ("usb.platform-policy.dhall") '' let Genode = env:DHALL_GENODE @@ -89,11 +115,6 @@ with lib; } ''); - genode.core.basePackages = with pkgs.genodePackages; - [ acpi_drv platform_drv ] - ++ lib.optional config.hardware.usb.genode.enable - pkgs.genodePackages.usb_drv; - genode.init.children = let nics = mapAttrs' (name: interface: @@ -125,8 +146,7 @@ with lib; in Init.Child.flat Init.Child.Attributes::{ - , binary = "${binary.pname}" - , provides = [ "Nic" ] + , binary = "${binary}/bin/${binary.pname}" , resources = Init.Resources::{ , caps = 128 , ram = Genode.units.MiB 4 @@ -227,112 +247,134 @@ with lib; in lib.filterAttrs (n: v: v != null) (nics // sockets); - genode.core.children = { + genode.core.children.acpi_drv = { + inputs = [ pkgs.genodePackages.acpi_drv ]; + configFile = pkgs.writeText "acpi_drv.dhall" '' + let Genode = env:DHALL_GENODE - acpi_drv = { - coreROMs = [ "acpi_drv" ]; - configFile = pkgs.writeText "acpi_drv.dhall" '' - let Genode = env:DHALL_GENODE + let Init = Genode.Init - let Init = Genode.Init + let label = λ(_ : Text) → { local = _, route = _ } - let label = λ(_ : Text) → { local = _, route = _ } - - in Init.Child.flat - Init.Child.Attributes::{ - , binary = "acpi_drv" - , resources = Init.Resources::{ - , caps = 400 - , ram = Genode.units.MiB 4 - , constrainPhys = True - } - , romReports = [ label "acpi", label "smbios_table" ] - , routes = - [ Init.ServiceRoute.parent "IRQ" - , Init.ServiceRoute.parent "IO_MEM" - , Init.ServiceRoute.parent "IO_PORT" - ] + in Init.Child.flat + Init.Child.Attributes::{ + , binary = "acpi_drv" + , resources = Init.Resources::{ + , caps = 400 + , ram = Genode.units.MiB 4 + , constrainPhys = True } - ''; - }; + , romReports = [ label "acpi", label "smbios_table" ] + , routes = + [ Init.ServiceRoute.parent "IRQ" + , Init.ServiceRoute.parent "IO_MEM" + , Init.ServiceRoute.parent "IO_PORT" + ] + } + ''; + }; - platform_drv = { - coreROMs = [ "platform_drv" ]; + genode.core.children.platform_drv = { + inputs = [ pkgs.genodePackages.platform_drv ]; + configFile = let + policies = + map (policy: ", ${policy}") config.hardware.genode.platform.policies; + in pkgs.writeText "platform_drv.dhall" '' + let Genode = env:DHALL_GENODE + + let Init = Genode.Init + + in Init.Child.flat + Init.Child.Attributes::{ + , binary = "platform_drv" + , resources = Init.Resources::{ + , caps = 800 + , ram = Genode.units.MiB 4 + , constrainPhys = True + } + , reportRoms = let label = "acpi" in [ { local = label, route = label } ] + , routes = + [ Init.ServiceRoute.parent "IRQ" + , Init.ServiceRoute.parent "IO_MEM" + , Init.ServiceRoute.parent "IO_PORT" + ] + , config = Init.Config::{ + , policies = [ ${toString policies} ] + } + } + ''; + }; + + genode.core.children.usb_drv = mkIf config.hardware.genode.usb.enable { + inputs = [ pkgs.genodePackages.usb_drv ]; + configFile = builtins.toFile "usb_drv.dhall" '' + let Genode = env:DHALL_GENODE + + let XML = Genode.Prelude.XML + + let Init = Genode.Init + + let storageEnable = ${ + if config.hardware.genode.usb.storage.enable then "True" else "False" + } + + in Init.Child.flat + Init.Child.Attributes::{ + , binary = "usb_drv" + , resources = Init.Resources::{ caps = 256, ram = Genode.units.MiB 12 } + , routes = [ Init.ServiceRoute.parent "IO_MEM" ] + , config = Init.Config::{ + , attributes = toMap { uhci = "yes", ehci = "yes", xhci = "yes" } + , content = + if storageEnable + then [ XML.leaf + { name = "storage", attributes = XML.emptyAttributes } + ] + else [] : List XML.Type + , policies = + if storageEnable + then [ Init.Config.Policy::{ + , service = "Block" + , label = Init.LabelSelector.prefix "part_block" + } + ] + else [] : List Init.Config.Policy.Type + } + } + ''; + }; + + genode.core.children.fb_drv = + mkIf config.hardware.genode.framebuffer.enable { + inputs = with pkgs.genodePackages; + { + "boot" = [ boot_fb_drv ]; + "vesa" = [ vesa_drv ]; + }.${config.hardware.genode.framebuffer.driver}; configFile = let - policies = map (policy: ", ${policy}") - config.hardware.genode.platform.policies; - in pkgs.writeText "platform_drv.dhall" '' - let Genode = env:DHALL_GENODE - - let Init = Genode.Init - - in Init.Child.flat - Init.Child.Attributes::{ - , binary = "platform_drv" - , resources = Init.Resources::{ - , caps = 800 - , ram = Genode.units.MiB 4 - , constrainPhys = True - } - , reportRoms = let label = "acpi" in [ { local = label, route = label } ] - , provides = [ "Platform" ] - , routes = - [ Init.ServiceRoute.parent "IRQ" - , Init.ServiceRoute.parent "IO_MEM" - , Init.ServiceRoute.parent "IO_PORT" - ] - , config = Init.Config::{ - , policies = [ ${toString policies} ] - } - } - ''; - }; - } // (if config.hardware.usb.genode.enable then { - - usb_drv = { - coreROMs = [ "usb_drv" ]; - configFile = builtins.toFile "usb_drv.dhall" '' + binary = with pkgs.genodePackages; + { + "boot" = "boot_fb_drv"; + "vesa" = "vesa_fb_drv"; + }.${config.hardware.genode.framebuffer.driver}; + in builtins.toFile "fb_drv.dhall" '' let Genode = env:DHALL_GENODE let XML = Genode.Prelude.XML let Init = Genode.Init - let storageEnable = ${ - if config.hardware.usb.genode.storage.enable then - "True" - else - "False" - } - in Init.Child.flat Init.Child.Attributes::{ - , binary = "usb_drv" - , provides = [ "Block", "Usb" ] - , resources = Init.Resources::{ caps = 256, ram = Genode.units.MiB 12 } - , routes = [ Init.ServiceRoute.parent "IO_MEM" ] - , config = Init.Config::{ - , attributes = toMap { uhci = "yes", ehci = "yes", xhci = "yes" } - , content = - if storageEnable - then [ XML.leaf - { name = "storage", attributes = XML.emptyAttributes } - ] - else [] : List XML.Type - , policies = - if storageEnable - then [ Init.Config.Policy::{ - , service = "Block" - , label = Init.LabelSelector.prefix "store_fs" - } - ] - else [] : List Init.Config.Policy.Type - } + , binary = "${binary}" + , resources = Init.Resources::{ caps = 256, ram = Genode.units.MiB 32 } + , routes = + [ Init.ServiceRoute.parent "IO_MEM" + , Init.ServiceRoute.parent "IO_PORT" + ] } ''; }; - } else - { }); }; diff --git a/tests/lib/build-vms.nix b/tests/lib/build-vms.nix index fcc32a6..5729805 100644 --- a/tests/lib/build-vms.nix +++ b/tests/lib/build-vms.nix @@ -29,6 +29,7 @@ rec { baseModules = (import "${modulesPath}/module-list.nix") ++ [ ../../nixos-modules/genode-core.nix ../../nixos-modules/genode-init.nix + ../../nixos-modules/gui ../../nixos-modules/hardware.nix ../../nixos-modules/qemu-vm.nix {