diff --git a/nixos-modules/genode-core.nix b/nixos-modules/genode-core.nix index 736c466..134f2ec 100644 --- a/nixos-modules/genode-core.nix +++ b/nixos-modules/genode-core.nix @@ -82,6 +82,8 @@ in { ''; }; + initInputs = unique config.genode.init.inputs; + mergeManifests = inputs: localPackages.writeTextFile { name = "manifest.dhall"; @@ -99,12 +101,12 @@ in { }; storeManifest = - mergeManifests (map addManifest config.genode.init.inputs); + mergeManifests (map addManifest initInputs); storeTarball = localPackages.runCommand "store" { } '' mkdir -p $out tar cf "$out/store.tar" --absolute-names ${ - toString config.genode.init.inputs + toString initInputs } ''; diff --git a/nixos-modules/genode-init.nix b/nixos-modules/genode-init.nix index 84730ef..ee5b021 100644 --- a/nixos-modules/genode-init.nix +++ b/nixos-modules/genode-init.nix @@ -1,36 +1,54 @@ -# genodeInit.children is an attrset of nixos configurations, like containers - { config, pkgs, lib, ... }: with lib; -{ - imports = [ ]; +let + inputs = mkOption { + description = "List of packages to build a ROM store with."; + type = types.listOf types.package; + }; +in { options.genode.init = { + inherit inputs; config = mkOption { - description = "Dhall configuration of this init instance"; - type = types.nullOr types.str; - default = null; + description = '' + Dhall configuration of this init instance after children have been merged. + ''; + type = types.path; }; - inputs = mkOption { - description = "List of packages to build a ROM store with."; - type = types.listOf types.package; + baseConfig = mkOption { + description = '' + Dhall configuration of this init instance before merging children. + ''; + type = types.str; + default = '' + let Genode = env:DHALL_GENODE + + in Genode.Init::{ routes = [ Genode.Init.ServiceRoute.parent "Timer" ] } + ''; }; children = mkOption { - type = let - childOptions = { name, ... }: { - name = mkOption { type = types.str; }; - dhallAttrs = mkOption { type = types.str; }; - }; - in types.attrsOf (types.submodule childOptions); + type = with types; + attrsOf (submodule { + options = { + inherit inputs; + settings = mkOption { + type = types.path; + description = '' + Dhall configuration of child. + See https://git.sr.ht/~ehmry/dhall-genode/tree/master/Init/Child/Type + ''; + }; + }; + }); }; subinits = mkOption { - type = types.attrsOf (types.submodule ({ config, options, name, ... }: { + type = types.attrsOf (types.submodule ({ config, options, ... }: { options = { config = mkOption { @@ -86,6 +104,20 @@ with lib; config = { + genode.init.inputs = with builtins; + [ pkgs.genodePackages.report_rom ] ++ concatLists + (catAttrs "inputs" (attrValues config.genode.init.children)); + + genode.init.config = builtins.toFile "init.dhall" '' + let baseConfig = ${config.genode.init.baseConfig} + + in baseConfig with children = baseConfig.children # toMap {${ + concatMapStrings + (name: ", `${name}` = ${config.genode.init.children.${name}.settings}") + (builtins.attrNames config.genode.init.children) + } } + ''; + system.build.initXml = pkgs.buildPackages.runCommand "init.xml" { nativeBuildInputs = with pkgs.buildPackages; [ dhall xorg.lndir ]; DHALL_GENODE = "${pkgs.genodePackages.dhallGenode}/binary.dhall"; diff --git a/nixos-modules/hardware.nix b/nixos-modules/hardware.nix index 0c8dde0..8637ee7 100644 --- a/nixos-modules/hardware.nix +++ b/nixos-modules/hardware.nix @@ -1,50 +1,202 @@ { config, pkgs, lib, ... }: -with lib; { - options.genode = { - hardware = { +with lib; - nic = mkOption { - default = { }; - example = { eth0.driver = "virtio"; }; - description = "The configuration for each Nic service."; - type = let - - nicOptions = { name, ... }: { - name = mkOption { - - example = "eth0"; - type = types.str; - description = "Name of the Nic service."; - }; - - driver = mkOption { type = types.enum [ "ipxe" "virtio" ]; }; - - ipStack = mkOption { - type = types.enum [ "lwip" "lxip" ]; - default = "lwip"; - }; +{ + options.genode.hardware.nic = mkOption { + example = { + eth0 = { + driver = "virtio"; + stack = "lwip"; + }; + }; + default = { }; + description = "The configuration for each Nic service."; + type = with types; + attrsOf (submodule { + options = { + driver = mkOption { + type = types.enum [ "ipxe" "virtio" ]; + default = "ipxe"; }; - in types.attrsOf (types.submodule nicOptions); - }; + stack = mkOption { + type = types.enum [ "lwip" "lxip" ]; + default = "lwip"; + }; - }; + }; + }); }; config = { genode.init.children = let - drivers = mapAttrsToList (name: interface: { - name = name + "-nic"; - value = { }; - }) config.networking.interfaces; - sockets = mapAttrsToList (name: interface: { - name = name + "-sockets"; - value = { }; - }) config.networking.interfaces; - in builtins.listToAttrs (drivers ++ sockets); + inherit (builtins) toFile; + + nics = mapAttrs' (name: interface: + let name' = "nic." + name; + in { + name = name'; + value = { + inputs = with pkgs.genodePackages; + { + ipxe = [ ipxe_nic_drv ]; + virtio = [ virtio_nic_drv ]; + }.${config.genode.hardware.nic.${name}.driver}; + settings = toFile "${name'}.dhall" '' + let Genode = env:DHALL_GENODE + + let Init = Genode.Init + + in Init.Child.flat + Init.Child.Attributes::{ + , binary = "virtio_pci_nic" + , provides = [ "Nic" ] + , resources = Init.Resources::{ + , caps = 128 + , ram = Genode.units.MiB 4 + } + , routes = [ Init.ServiceRoute.parent "IO_MEM" ] + , config = Init.Config::{ + , policies = + [ Init.Config.Policy::{ + , service = "Nic" + , label = + Init.LabelSelector.prefix "sockets.${name}" + } + ] + } + } + ''; + }; + }) config.networking.interfaces; + + sockets = mapAttrs' (name: interface: + let name' = "sockets." + name; + in { + name = name'; + value = { + inputs = with pkgs.genodePackages; + { + lwip = [ vfs_lwip ]; + lxip = [ vfs_lixp ]; + }.${config.genode.hardware.nic.${name}.stack}; + settings = let ipv4 = builtins.head interface.ipv4.addresses; + in toFile "${name'}.dhall" '' + let Genode = env:DHALL_GENODE + + let Init = Genode.Init + + in Init.Child.flat + Init.Child.Attributes::{ + , binary = "vfs" + , provides = [ "File_system" ] + , resources = Init.Resources::{ caps = 128, ram = Genode.units.MiB 16 } + , config = Init.Config::{ + , defaultPolicy = Some Init.Config.DefaultPolicy::{ + , attributes = toMap { root = "/", writeable = "yes" } + } + , content = + let XML = Genode.Prelude.XML + + in [ XML.element + { name = "vfs" + , attributes = XML.emptyAttributes + , content = + [ XML.leaf + { name = "lwip" + , attributes = toMap + { ip_addr = "${ipv4.address}", netmask = "${ + if ipv4.prefixLength == 24 then + "255.255.255.0" + else + throw + "missing prefix to netmask conversion" + }" } + } + ] + } + ] + } + } + ''; + }; + }) config.networking.interfaces; + + in nics // sockets // { + + platform_drv = { + inputs = [ pkgs.genodePackages.platform_drv ]; + settings = let + policies = concatMapStrings (name: '' + Init.Config.Policy::{ + , service = "Platform" + , label = Init.LabelSelector.prefix "nic.${name}" + , content = + [ Genode.Prelude.XML.leaf + { name = "pci", attributes = toMap { class = "ETHERNET" } } + ] + } + '') (builtins.attrNames config.networking.interfaces); + in toFile "platform_drv.dhall" '' + let Genode = env:DHALL_GENODE + + let Init = Genode.Init + + let label = \(_ : Text) -> { local = _, route = _ } + + in Init.Child.flat + Init.Child.Attributes::{ + , binary = "platform_drv" + , resources = Init.Resources::{ + , caps = 800 + , ram = Genode.units.MiB 4 + , constrainPhys = True + } + , reportRoms = [ label "acpi" ] + , provides = [ "Platform" ] + , routes = + [ Init.ServiceRoute.parent "IRQ" + , Init.ServiceRoute.parent "IO_MEM" + , Init.ServiceRoute.parent "IO_PORT" + ] + , config = Init.Config::{ + , policies = [ ${policies} ] + } + } + ''; + }; + + acpi_drv = { + inputs = [ pkgs.genodePackages.acpi_drv ]; + settings = toFile "acpi_drv.dhall" '' + let Genode = env:DHALL_GENODE + + let Init = Genode.Init + + 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" ] + , routes = + [ Init.ServiceRoute.parent "IRQ" + , Init.ServiceRoute.parent "IO_MEM" + , Init.ServiceRoute.parent "IO_PORT" + ] + } + ''; + }; + + }; }; diff --git a/tests/lighttpd.nix b/tests/lighttpd.nix index 40c5396..dec2aa5 100644 --- a/tests/lighttpd.nix +++ b/tests/lighttpd.nix @@ -4,10 +4,17 @@ webserver = { imports = [ ../nixos-modules/hardware.nix ]; services.lighttpd.enable = true; + genode.hardware.nic.eth1.driver = "virtio"; + genode.hardware.nic.eth1.stack = "lwip"; }; client = { imports = [ ../nixos-modules/hardware.nix ]; - genode.hardware.nic.eth0.driver = "virtio"; + genode.hardware.nic.eth1.driver = "virtio"; + genode.hardware.nic.eth1.stack = "lwip"; }; }; + testScript = '' + start_all() + client.wait_until_serial_output("forever") + ''; }