2
0
Fork 0
Browse Source

Port NixOS module system

Convert the tests to use the module system from NixOS.
posix
Emery Hemingway 2 years ago
parent
commit
ebf3606705
  1. 19
      flake.nix
  2. 34
      lib/default.nix
  3. 27
      nixos-modules/base-hw-pc.nix
  4. 27
      nixos-modules/base-hw-virt_qemu.nix
  5. 157
      nixos-modules/genode-core.nix
  6. 111
      nixos-modules/genode-init.nix
  7. 195
      nixos-modules/hardware.nix
  8. 27
      nixos-modules/nova.nix
  9. 917
      nixos-modules/qemu-vm.nix
  10. 166
      nixos-modules/store-wrapper.dhall
  11. 159
      nixos-modules/systemd-runner.dhall
  12. 33
      nixos-modules/systemd.nix
  13. 23
      packages/genodelabs/targets.nix
  14. 33
      packages/genodelabs/test-pci.patch
  15. 333
      tests/default.nix
  16. 51
      tests/hello.dhall
  17. 28
      tests/hello.nix
  18. 110
      tests/lib/build-vms.nix
  19. 41
      tests/lib/qemu-flags.nix
  20. 967
      tests/lib/test-driver.py
  21. 235
      tests/lib/testing-python.nix
  22. 27
      tests/log.dhall
  23. 11
      tests/log.nix
  24. 24
      tests/solo5/multi.nix
  25. 19
      tests/solo5/solo5.dhall
  26. 23
      tests/vmm_x86.dhall
  27. 10
      tests/vmm_x86.nix
  28. 40
      tests/x86.dhall
  29. 21
      tests/x86.nix

19
flake.nix

@ -65,9 +65,7 @@
forAllCrossSystems ({ system, localSystem, crossSystem }:
nixpkgs.lib // (import ./lib {
inherit system localSystem crossSystem;
localPackages = nixpkgs.legacyPackages.${localSystem};
genodepkgs = self;
nixpkgs = nixpkgsFor.${system};
pkgs = self.legacyPackages.${system};
}));
legacyPackages =
@ -139,15 +137,12 @@
checks =
# Checks for continous testing
with (forAllCrossSystems ({ system, localSystem, crossSystem }:
import ./tests {
inherit self;
apps = self.apps.${system};
localPackages = nixpkgsFor.${localSystem};
genodepkgs = self.packages.${system};
lib = self.lib.${system};
nixpkgs = nixpkgsFor.${system};
legacyPackages = self.legacyPackages.${system};
let tests = import ./tests;
in with (forAllCrossSystems ({ system, localSystem, crossSystem }:
tests {
flake = self;
inherit system localSystem crossSystem;
pkgs = self.legacyPackages.${system};
} // {
ports = nixpkgsFor.${localSystem}.symlinkJoin {
name = "ports";

34
lib/default.nix

@ -1,22 +1,22 @@
{ system, localSystem, crossSystem, genodepkgs, nixpkgs, localPackages }:
{ system, localSystem, crossSystem, pkgs }:
let
thisSystem = builtins.getAttr system;
inherit (nixpkgs) buildPackages;
testPkgs = thisSystem genodepkgs.packages;
inherit (pkgs) buildPackages;
localPackages = pkgs.buildPackages.buildPackages;
inherit (pkgs.genodePackages) dhallGenode genodeSources;
dhallCachePrelude = ''
export XDG_CACHE_HOME=$NIX_BUILD_TOP
export DHALL_GENODE="${testPkgs.dhallGenode}/binary.dhall";
export DHALL_GENODE="${dhallGenode}/binary.dhall";
${buildPackages.xorg.lndir}/bin/lndir -silent \
${testPkgs.dhallGenode}/.cache \
${dhallGenode}/.cache \
$XDG_CACHE_HOME
'';
in rec {
runDhallCommand = name: env: script:
nixpkgs.runCommand name (env // {
pkgs.runCommand name (env // {
nativeBuildInputs = [ localPackages.dhall ]
++ env.nativeBuildInputs or [ ];
}) ''
@ -42,7 +42,7 @@ in rec {
hwImage = coreLinkAddr: bootstrapLinkAddr: basePkg: name:
{ gzip ? false, ... }@env:
boot:
nixpkgs.stdenv.mkDerivation {
pkgs.stdenv.mkDerivation {
name = name + "-hw-image";
build = compileBoot name env boot;
nativeBuildInputs = [ localPackages.dhall ];
@ -74,7 +74,7 @@ in rec {
LD="${buildPackages.binutils}/bin/${buildPackages.binutils.targetPrefix}ld"
$LD \
--strip-all \
-T${testPkgs.genodeSources}/repos/base/src/ld/genode.ld \
-T${genodeSources}/repos/base/src/ld/genode.ld \
-z max-page-size=0x1000 \
-Ttext=$link_address -gc-sections \
"$lib" "boot_modules.o" \
@ -96,13 +96,13 @@ in rec {
bootstrap/modules_asm \
${bootstrapLinkAddr} \
$out/image.elf
'' + nixpkgs.lib.optionalString gzip "gzip $out/image.elf";
'' + pkgs.lib.optionalString gzip "gzip $out/image.elf";
};
novaImage = name:
{ gzip ? false, ... }@env:
boot:
nixpkgs.stdenv.mkDerivation {
pkgs.stdenv.mkDerivation {
name = name + "-nova-image";
build = compileBoot name env boot;
@ -115,17 +115,17 @@ in rec {
# link final image
LD="${buildPackages.binutils}/bin/${buildPackages.binutils.targetPrefix}ld"
$LD --strip-all -nostdlib \
-T${testPkgs.genodeSources}/repos/base/src/ld/genode.ld \
-T${testPkgs.genodeSources}/repos/base-nova/src/core/core-bss.ld \
-T${genodeSources}/repos/base/src/ld/genode.ld \
-T${genodeSources}/repos/base-nova/src/core/core-bss.ld \
-z max-page-size=0x1000 \
-Ttext=0x100000 -gc-sections \
"${testPkgs.base-nova.coreObj}" boot_modules.o \
"${pkgs.genodePackages.base-nova.coreObj}" boot_modules.o \
-o $out/image.elf
'' + nixpkgs.lib.optionalString gzip "gzip $out/image.elf";
'' + pkgs.lib.optionalString gzip "gzip $out/image.elf";
};
mergeManifests = inputs:
nixpkgs.writeTextFile {
pkgs.writeTextFile {
name = "manifest.dhall";
text = with builtins;
let
@ -133,7 +133,7 @@ in rec {
if hasAttr "manifest" input then
''
${head}, { mapKey = "${
nixpkgs.lib.getName input
pkgs.lib.getName input
}", mapValue = ${input.manifest} }''
else
abort "${input.pname} does not have a manifest";

27
nixos-modules/base-hw-pc.nix

@ -0,0 +1,27 @@
{ config, pkgs, lib, ... }:
with lib;
let
localPackages = pkgs.buildPackages;
utils = import ../lib {
inherit (config.nixpkgs) system localSystem crossSystem;
inherit pkgs;
};
in {
genode.core = {
prefix = "hw-pc-";
supportedSystems = [ "x86_64-genode" ];
basePackages = with pkgs.genodePackages; [ base-hw-pc rtc_drv ];
};
genode.boot = {
initrd = "${config.genode.boot.image}/image.elf";
image = utils.hwImage "0xffffffc000000000" "0x00200000"
pkgs.genodePackages.base-hw-pc config.system.name { }
config.genode.boot.configFile;
};
}

27
nixos-modules/base-hw-virt_qemu.nix

@ -0,0 +1,27 @@
{ config, pkgs, lib, ... }:
with lib;
let
localPackages = pkgs.buildPackages;
utils = import ../lib {
inherit (config.nixpkgs) system localSystem crossSystem;
inherit pkgs;
};
in {
genode.core = {
prefix = "hw-virt_qemu";
supportedSystems = [ "aarch64-genode" ];
basePackages = with pkgs.genodePackages; [ base-hw-virt_qemu rtc-dummy ];
};
genode.boot = {
initrd = "${config.genode.boot.image}/image.elf";
image = utils.hwImage "0xffffffc000000000" "0x40000000"
pkgs.genodePackages.base-hw-virt_qemu config.system.name { }
config.genode.boot.configFile;
};
}

157
nixos-modules/genode-core.nix

@ -0,0 +1,157 @@
{ config, pkgs, lib, modulesPath, ... }:
with lib;
let localPackages = pkgs.buildPackages;
in {
options.genode = {
core = {
prefix = mkOption {
type = types.str;
example = "hw-pc-";
};
supportedSystems = mkOption {
type = types.listOf types.str;
example = [ "i686-genode" "x86_64-genode" ];
};
basePackages = mkOption { type = types.listOf types.package; };
};
boot = {
kernel = mkOption {
type = types.path;
default = "${pkgs.genodePackages.bender}/bender";
};
initrd = mkOption {
type = types.str;
default = "${pkgs.genodePackages.bender}/bender";
description = "Path to an image or a command-line arguments";
};
configFile = mkOption {
type = types.path;
description = ''
Dhall boot configuration. See
https://git.sr.ht/~ehmry/dhall-genode/tree/master/Boot/package.dhall
'';
};
image = mkOption {
type = types.path;
description =
"Boot image containing the base component binaries and configuration.";
};
romModules = mkOption {
type = types.attrsOf types.path;
description = "Attr set of initial ROM modules";
};
};
};
config = let
initInputs = unique config.genode.init.inputs;
addManifest = drv:
drv // {
manifest =
localPackages.runCommand "${drv.name}.dhall" { inherit drv; } ''
set -eu
echo -n '[' >> $out
find $drv/ -type f -printf ',{mapKey= "%f",mapValue="%p"}' >> $out
${if builtins.elem "lib" drv.outputs then
''
find ${drv.lib}/ -type f -printf ',{mapKey= "%f",mapValue="%p"}' >> $out''
else
""}
echo -n ']' >> $out
'';
};
mergeManifests = inputs:
localPackages.writeTextFile {
name = "manifest.dhall";
text = with builtins;
let
f = head: input:
if hasAttr "manifest" input then
''
${head}, { mapKey = "${
lib.getName input
}", mapValue = ${input.manifest} }''
else
abort "${input.pname} does not have a manifest";
in (foldl' f "[" inputs) + "]";
};
in {
assertions = [{
assertion = builtins.any (s: s == config.nixpkgs.system)
config.genode.core.supportedSystems;
message = "invalid Genode core for this system";
}];
genode.boot.configFile = let
tarball =
"${config.system.build.tarball}/tarball/${config.system.build.tarball.fileName}.tar";
manifest = mergeManifests (map addManifest
(config.genode.core.basePackages ++ [ config.system.build.tarball ]
++ (with pkgs.genodePackages; [ init cached_fs_rom vfs ])));
in localPackages.runCommand "boot.dhall" { } ''
cat > $out << EOF
${./store-wrapper.dhall}
(${config.genode.init.configFile})
"${config.system.build.tarball.fileName}.tar"
$(stat --format '%s' ${tarball})
${config.system.build.storeManifest} ${manifest}
EOF
'';
system.build.storeManifest = mergeManifests (map addManifest initInputs);
# Create the tarball of the store to live in core ROM
system.build.tarball =
pkgs.callPackage "${modulesPath}/../lib/make-system-tarball.nix" {
contents = [ ];
storeContents = [
{
# assume that the init config will depend
# on every store path needed to boot
object = config.genode.init.configFile;
symlink = "/config.dhall";
}
{
object = pkgs.buildPackages.symlinkJoin {
name = config.system.name + ".rom";
paths = config.genode.init.inputs;
};
symlink = "/rom";
}
];
compressCommand = "cat";
compressionExtension = "";
};
system.build.initXml = pkgs.buildPackages.runCommand "init.xml" {
nativeBuildInputs = with pkgs.buildPackages; [ dhall xorg.lndir ];
DHALL_GENODE = "${pkgs.genodePackages.dhallGenode}/binary.dhall";
BOOT_CONFIG = config.genode.boot.configFile;
} ''
export XDG_CACHE_HOME=$NIX_BUILD_TOP
lndir -silent \
${pkgs.genodePackages.dhallGenode}/.cache \
$XDG_CACHE_HOME
dhall text <<< "(env:DHALL_GENODE).Init.render (env:BOOT_CONFIG).config" > $out
'';
};
}

111
nixos-modules/genode-init.nix

@ -0,0 +1,111 @@
{ config, pkgs, lib, ... }:
with lib;
let
inputs = mkOption {
description = "List of packages to build a ROM store with.";
type = types.listOf types.package;
};
in {
options.genode.init = {
inherit inputs;
configFile = mkOption {
description = ''
Dhall configuration of this init instance after children have been merged.
'';
type = types.path;
};
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 "File_system"
, Genode.Init.ServiceRoute.parent "Rtc"
, Genode.Init.ServiceRoute.parent "Timer"
, Genode.Init.ServiceRoute.parent "IRQ"
, Genode.Init.ServiceRoute.parent "IO_MEM"
, Genode.Init.ServiceRoute.parent "IO_PORT"
]
}
'';
};
children = mkOption {
default = { };
type = with types;
attrsOf (submodule {
options = {
inherit inputs;
configFile = mkOption {
type = types.path;
description = ''
Dhall configuration of child.
See https://git.sr.ht/~ehmry/dhall-genode/tree/master/Init/Child/Type
'';
};
};
});
};
subinits = mkOption {
default = { };
type = with types;
attrsOf (submodule {
options = {
inherit inputs;
configFile = mkOption {
type = types.path;
description = ''
Dhall configuration of child init.
See https://git.sr.ht/~ehmry/dhall-genode/tree/master/Init/Type
'';
};
};
});
};
};
config = {
genode.init.inputs = with builtins;
[ pkgs.genodePackages.report_rom ] ++ concatLists (catAttrs "inputs"
((attrValues config.genode.init.children)
++ (attrValues config.genode.init.subinits)));
# TODO: convert the subinits to children
genode.init.configFile = pkgs.writeText "init.dhall" ''
let Genode = env:DHALL_GENODE
let baseConfig = ${config.genode.init.baseConfig}
in baseConfig with children = baseConfig.children # toMap {${
concatMapStrings (name:
", `${name}` = (${
config.genode.init.children.${name}.configFile
} : Genode.Init.Child.Type)")
(builtins.attrNames config.genode.init.children)
} ${
concatMapStrings (name: ''
, `${name}` =
Genode.Init.toChild
(${
config.genode.init.subinits.${name}.configFile
} : Genode.Init.Type)
Genode.Init.Attributes.default
'') (builtins.attrNames config.genode.init.subinits)
} }
'';
};
}

195
nixos-modules/hardware.nix

@ -0,0 +1,195 @@
{ config, pkgs, lib, ... }:
with lib;
{
options.networking.interfaces = lib.mkOption {
type = with types;
attrsOf (submodule ({ ... }: {
options.genode = {
driver = mkOption {
type = types.enum [ "ipxe" "virtio" ];
default = "ipxe";
};
stack = mkOption {
type = types.enum [ "lwip" "lxip" ];
default = "lwip";
};
};
}));
};
config.genode.init.children = let
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 ];
}.${interface.genode.driver};
configFile = 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 ];
}.${interface.genode.stack};
configFile = 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::{
, policies =
[ Init.Config.Policy::{
, service = "File_system"
, label = Init.LabelSelector.suffix "sockets"
, attributes = toMap { root = "/" }
}
]
, 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 ];
configFile = 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 ];
configFile = 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"
]
}
'';
};
};
}

27
nixos-modules/nova.nix

@ -0,0 +1,27 @@
{ config, pkgs, lib, ... }:
with lib;
let
localPackages = pkgs.buildPackages;
utils = import ../lib {
inherit (config.nixpkgs) system localSystem crossSystem;
inherit pkgs;
};
in {
genode.core = {
prefix = "nova-";
supportedSystems = [ "x86_64-genode" ];
basePackages = with pkgs.genodePackages; [ base-nova rtc_drv ];
};
genode.boot = {
initrd =
"'${pkgs.genodePackages.NOVA}/hypervisor-x86_64 arg=iommu novpid serial,${config.genode.boot.image}/image.elf'";
image =
utils.novaImage config.system.name { } config.genode.boot.configFile;
};
}

917
nixos-modules/qemu-vm.nix

File diff suppressed because it is too large Load Diff

166
nixos-modules/store-wrapper.dhall

@ -0,0 +1,166 @@
let Genode =
env:DHALL_GENODE sha256:e90438be23b5100003cf018b783986df67bc6d0e3d35e800677d0d9109ff6aa9
let Prelude = Genode.Prelude
let XML = Prelude.XML
let Init = Genode.Init
let Child = Init.Child
let TextMapType = Prelude.Map.Type Text
let Manifest/Type = TextMapType (TextMapType Text)
let Manifest/toRoutes =
λ(manifest : Manifest/Type) →
Prelude.List.map
(Prelude.Map.Entry Text Text)
Init.ServiceRoute.Type
( λ(entry : Prelude.Map.Entry Text Text) →
{ service =
{ name = "ROM"
, label = Init.LabelSelector.Type.Last entry.mapKey
}
, route =
Init.Route.Type.Child
{ name = "store_rom"
, label = Some entry.mapValue
, diag = Some True
}
}
)
( Prelude.List.concat
(Prelude.Map.Entry Text Text)
(Prelude.Map.values Text (Prelude.Map.Type Text Text) manifest)
)
let parentROMs =
Prelude.List.map
Text
Init.ServiceRoute.Type
( λ(label : Text) →
{ service = { name = "ROM", label = Init.LabelSelector.last label }
, route =
Init.Route.Type.Parent { label = Some label, diag = None Bool }
}
)
let wrapStore
: Init.Type → Manifest/Type → Child.Type
= λ(init : Init.Type) →
λ(manifest : Manifest/Type) →
Init.toChild
init
Init.Attributes::{
, exitPropagate = True
, resources = Init.Resources::{ ram = Genode.units.MiB 4 }
, routes =
[ Init.ServiceRoute.parent "IO_MEM"
, Init.ServiceRoute.parent "IO_PORT"
, Init.ServiceRoute.parent "IRQ"
, Init.ServiceRoute.parent "VM"
, Init.ServiceRoute.child "Timer" "timer"
, Init.ServiceRoute.child "Rtc" "rtc"
]
# parentROMs
[ "ld.lib.so"
, "init"
, "platform_info"
, "core_log"
, "kernel_log"
, "vfs"
, "vfs.lib.so"
, "cached_fs_rom"
]
# Manifest/toRoutes manifest
# [ Init.ServiceRoute.child "ROM" "store_rom" ]
}
in λ(subinit : Init.Type) →
λ(storeName : Text) →
λ(storeSize : Natural) →
λ(storeManifest : Manifest/Type) →
λ(bootManifest : Manifest/Type) →
Genode.Boot::{
, config = Init::{
, children =
let child = Prelude.Map.keyValue Child.Type
in [ child
"timer"
( Child.flat
Child.Attributes::{
, binary = "timer_drv"
, provides = [ "Timer" ]
}
)
, child
"rtc"
( Child.flat
Child.Attributes::{
, binary = "rtc_drv"
, provides = [ "Rtc" ]
, routes = [ Init.ServiceRoute.parent "IO_PORT" ]
}
)
, child
"store_fs"
( Child.flat
Child.Attributes::{
, binary = "vfs"
, config = Init.Config::{
, content =
[ XML.element
{ name = "vfs"
, attributes = XML.emptyAttributes
, content =
[ XML.leaf
{ name = "tar"
, attributes = toMap { name = storeName }
}
]
}
]
, policies =
[ Init.Config.Policy::{
, service = "File_system"
, label = Init.LabelSelector.suffix "nix-store"
, attributes = toMap { root = "/nix/store" }
}
, Init.Config.Policy::{
, service = "File_system"
, label = Init.LabelSelector.prefix "store_rom"
, attributes = toMap { root = "/" }
}
]
}
, provides = [ "File_system" ]
}
)
, child
"store_rom"
( Child.flat
Child.Attributes::{
, binary = "cached_fs_rom"
, provides = [ "ROM" ]
, resources = Init.Resources::{
, ram = storeSize + Genode.units.MiB 1
}
}
)
, child "init" (wrapStore subinit storeManifest)
]
}
, rom =
Genode.BootModules.toRomPaths
( Prelude.List.concat
(Prelude.Map.Entry Text Text)
( Prelude.Map.values
Text
(Prelude.Map.Type Text Text)
bootManifest
)
)
}

159
nixos-modules/systemd-runner.dhall

@ -0,0 +1,159 @@
let Genode = env:DHALL_GENODE
let Prelude = Genode.Prelude
let XML = Prelude.XML
let Init = Genode.Init
let Child = Init.Child
let parentRoutes =
Prelude.List.map Text Init.ServiceRoute.Type Init.ServiceRoute.parent
in λ(params : { coreutils : Text, execStart : Text }) →
Init::{
, verbose = True
, routes = parentRoutes [ "Timer", "Rtc", "File_system" ]
, children = toMap
{ vfs =
Child.flat
Child.Attributes::{
, binary = "vfs"
, exitPropagate = True
, provides = [ "File_system" ]
, resources = Genode.Init.Resources::{
, caps = 256
, ram = Genode.units.MiB 8
}
, config = Init.Config::{
, content =
[ XML.element
{ name = "vfs"
, attributes = XML.emptyAttributes
, content =
let dir =
λ(name : Text) →
λ(content : List XML.Type) →
XML.element
{ name = "dir"
, content
, attributes = toMap { name }
}
let leaf =
λ(name : Text) →
XML.leaf
{ name, attributes = XML.emptyAttributes }
in [ dir
"dev"
[ dir "pipes" [ leaf "pipe" ]
, dir
"sockets"
[ XML.leaf
{ name = "fs"
, attributes = toMap
{ label = "sockets" }
}
]
, leaf "log"
, leaf "null"
, leaf "rtc"
, leaf "zero"
]
, dir
"etc"
[ XML.element
{ name = "inline"
, attributes = toMap
{ name = "ExecStart" }
, content =
[ XML.text params.execStart ]
}
]
, dir
"usr"
[ dir
"bin"
[ XML.leaf
{ name = "symlink"
, attributes = toMap
{ name = "env"
, target =
"${params.coreutils}/bin/env"
}
}
]
]
, dir "tmp" [ leaf "ram" ]
, dir
"nix"
[ dir
"store"
[ XML.leaf
{ name = "fs"
, attributes = toMap
{ label = "nix-store" }
}
]
]
]
}
]
, policies =
[ Init.Config.Policy::{
, service = "File_system"
, label = Init.LabelSelector.prefix "shell"
, attributes = toMap { root = "/", writeable = "yes" }
}
]
}
}
, shell =
Child.flat
Child.Attributes::{
, binary = "bash"
, exitPropagate = True
, resources = Genode.Init.Resources::{
, caps = 256
, ram = Genode.units.MiB 8
}
, config = Genode.Init.Config::{
, content =
[ XML.leaf
{ name = "libc"
, attributes = toMap
{ stdin = "/dev/null"
, stdout = "/dev/log"
, stderr = "/dev/log"
, pipe = "/dev/pipes"
, rtc = "/dev/rtc"
, socket = "/dev/sockets"
}
}
, XML.element
{ name = "vfs"
, attributes = XML.emptyAttributes
, content =
[ XML.leaf
{ name = "fs"
, attributes = XML.emptyAttributes
}
]
}
]
# Prelude.List.map
Text
XML.Type
( λ(x : Text) →
XML.leaf
{ name = "arg"
, attributes = toMap { value = x }
}
)
[ "bash", "/etc/ExecStart" ]
}
}
}
}

33
nixos-modules/systemd.nix

@ -0,0 +1,33 @@
{ config, pkgs, lib, ... }:
with lib; {
options.systemd.services = lib.mkOption {
type = types.attrsOf (types.submodule ({ name, config, ... }: {
options.genode.enable = lib.mkOption {
type = types.bool;
default = false;
description = "Translate this systemd unit to a Genode subsystem.";
};
}));
};
config.services.klogd.enable = false;
# The default is determined by checking the Linux version
# which cannot be evaluated here.
config.genode.init.subinits = mapAttrs' (name: service:
let name' = "services." + name;
in {
name = name';
value = {
inputs = with pkgs; with genodePackages; [ bash libc posix vfs_pipe ];
configFile = pkgs.writeText "${name'}.dhall" ''
${./systemd-runner.dhall} {
, coreutils = "${pkgs.coreutils}"
, execStart = "${toString service.serviceConfig.ExecStart}"
}
'';
};
}) (filterAttrs (name: service: service.genode.enable)
config.systemd.services);
}

23
packages/genodelabs/targets.nix

@ -1,5 +1,7 @@
# This file contains overrides necesarry to build some Make and Depot targets.
# This file contains overrides necessary to build some Make and Depot targets.
# Many targets can be built with the default attributes, and are not listed here.
# However, any package listed here with empty overrides ({ }) will be added to
# the package attributes of this flake.
{ buildPackages, ports }:
with ports;
@ -15,6 +17,8 @@ let
};
in {
acpi_drv = { };
cached_fs_rom = { };
fb_sdl = with buildPackages; {
@ -47,10 +51,20 @@ in {
lx_block.HOST_INC_DIR = [ hostLibcInc ];
nic_bridge = { };
nic_loopback = { };
noux.portInputs = [ libc ];
platform_drv = { };
posix.portInputs = [ libc ];
report_rom = { };
rom_logger = { };
rtc_drv.meta.platforms = [ "x86_64-genode" ];
rump = {
@ -58,6 +72,8 @@ in {
buildInputs = with buildPackages; [ zlib ];
};
sequence = { };
stdcxx.portInputs = [ libc stdcxx ];
# The following are tests are patched to exit at completion
@ -79,12 +95,17 @@ in {
vesa_drv.portInputs = [ libc x86emu ];
vfs.outputs = [ "out" "lib" ];
vfs_audit = {};
vfs_block = { };
vfs_import.patches = [ ./vfs_import.patch ];
vfs_jitterentropy.portInputs = [ jitterentropy libc ];
vfs_lwip.portInputs = [ lwip ];
vfs_pipe = { };
vfs_ttf.portInputs = [ libc stb ];
virtdev_rom = { };
virtio_nic_drv = { };
wifi_drv.portInputs = [ dde_linux libc openssl ];
}

33
packages/genodelabs/test-pci.patch

@ -8,3 +8,36 @@ index c6d9e2012b..050de6136c 100644
log("--- Platform test finished ---");
+ env.parent().exit(0);
}
commit 03a5f469313e9fdc9ee1135ebf0b167e4d3d3266
Author: Emery Hemingway <ehmry@posteo.net>
Date: Wed Oct 21 15:16:34 2020 +0200
test-pci: recognize VirtIO vendor IDs
diff --git a/repos/os/src/test/pci/test.cc b/repos/os/src/test/pci/test.cc
index c6d9e2012b..9cc2a2ac4b 100644
--- a/repos/os/src/test/pci/test.cc
+++ b/repos/os/src/test/pci/test.cc
@@ -19,7 +19,10 @@
using namespace Genode;
-enum { INTEL_VENDOR_ID = 0x8086 };
+enum {
+ INTEL_VENDOR_ID = 0x8086,
+ VIRTIO_VENDOR_ID = 0x1af4,
+};
/**
@@ -45,7 +48,9 @@ static void print_device_info(Platform::Device_capability device_cap)
Hex(fun, Hex::OMIT_PREFIX), " "
"class=", Hex(class_code), " "
"vendor=", Hex(vendor_id), " ",
- (vendor_id == INTEL_VENDOR_ID ? "(Intel)" : "(unknown)"),
+ (vendor_id == INTEL_VENDOR_ID ? "(Intel)" :
+ vendor_id == VIRTIO_VENDOR_ID ? "(VirtIO)" :
+ "(unknown)"),
" device=", Hex(device_id));
for (int resource_id = 0; resource_id < 6; resource_id++) {

333
tests/default.nix

@ -1,324 +1,63 @@
{ self, apps, localPackages, genodepkgs, lib, nixpkgs, legacyPackages }:
{ flake, system, localSystem, crossSystem, pkgs }:
let
callTest = path:
import path {
pkgs = testPkgs;
inherit nixpkgs localPackages legacyPackages;
};
testFiles =
map callTest [ ./log.nix ./posix.nix ./vmm_arm.nix ./vmm_x86.nix ./x86.nix ]
++ (callTest ./solo5);
testPkgs = genodepkgs;
qemu' = localPackages.qemu;
qemuBinary = qemuPkg:
{
aarch64-genode = "${qemuPkg}/bin/qemu-system-aarch64";
x86_64-genode = "${qemuPkg}/bin/qemu-system-x86_64";
}.${genodepkgs.stdenv.hostPlatform.system};
lib = flake.lib.${system};
nixpkgs = flake.legacyPackages.${system};
legacyPackages = flake.legacyPackages.${system};
testingPython = import ./lib/testing-python.nix;
testSpecs = map (p: import p) [
./hello.nix
./log.nix
./solo5/multi.nix
./vmm_x86.nix
./x86.nix
];
cores = [
{
prefix = "hw-pc-";
testingPython = testingPython {
inherit flake system localSystem crossSystem pkgs;
extraConfigurations = [ ../nixos-modules/base-hw-pc.nix ];
};
specs = [ "x86" "hw" ];
platforms = [ "x86_64-genode" ];
basePackages = [ testPkgs.base-hw-pc ]
++ map testPkgs.genodeSources.depot [ "rtc_drv" ];
makeImage =
lib.hwImage "0xffffffc000000000" "0x00200000" testPkgs.base-hw-pc;
startVM = vmName: image: ''
#! ${localPackages.runtimeShell}
exec ${qemuBinary qemu'} \
-name ${vmName} \
-machine q35 \
-m 384 \
-netdev user,id=net0 \
-device virtio-net-pci,netdev=net0 \
-kernel "${testPkgs.bender}/bender" \
-initrd "${image}/image.elf" \
$QEMU_OPTS \
"$@"
'';
}
{
prefix = "hw-virt_qemu-";
specs = [ "aarch64" "hw" ];
platforms = [ "aarch64-genode" ];
basePackages = with testPkgs; [ base-hw-virt_qemu rtc-dummy ];
makeImage = lib.hwImage "0xffffffc000000000" "0x40000000"
testPkgs.base-hw-virt_qemu;
startVM = vmName: image: ''
#! ${localPackages.runtimeShell}
exec ${qemuBinary qemu'} \
-name ${vmName} \
-M virt,virtualization=true,gic_version=3 \
-cpu cortex-a53 \
-smp 4 \
-m 384 \
-kernel "${image}/image.elf" \
$QEMU_OPTS \
"$@"
'';
}
/* {
prefix = "hw-virt_qemu-";
testingPython = testingPython {
inherit flake system localSystem crossSystem pkgs;
extraConfigurations = [ ../nixos-modules/base-hw-virt_qemu.nix ];
};
specs = [ "aarch64" "hw" ];
platforms = [ "aarch64-genode" ];
}
*/
{
prefix = "nova-";
testingPython = testingPython {
inherit flake system localSystem crossSystem pkgs;
extraConfigurations = [ ../nixos-modules/nova.nix ];
};
specs = [ "x86" "nova" ];
platforms = [ "x86_64-genode" ];
basePackages = [ testPkgs.base-nova ]
++ map testPkgs.genodeSources.depot [ "rtc_drv" ];
makeImage = lib.novaImage;
startVM = vmName: image: ''
#! ${localPackages.runtimeShell}
exec ${qemuBinary qemu'} \
-name ${vmName} \
-machine q35 \
-m 384 \
-kernel "${testPkgs.bender}/bender" \
-initrd "${testPkgs.NOVA}/hypervisor-x86_64 arg=iommu novpid serial,${image}/image.elf" \
$QEMU_OPTS \
"$@"
'';
}
];
cores' = builtins.filter (core:
builtins.any (x: x == genodepkgs.stdenv.hostPlatform.system) core.platforms)
builtins.any (x: x == pkgs.stdenv.hostPlatform.system) core.platforms)
cores;
testDriver = with localPackages;
let testDriverScript = ./test-driver/test-driver.py;
in stdenv.mkDerivation {
name = "nixos-test-driver";
nativeBuildInputs = [ makeWrapper ];
buildInputs = [ (python3.withPackages (p: [ p.ptpython ])) ];
checkInputs = with python3Packages; [ pylint mypy ];
dontUnpack = true;
preferLocalBuild = true;
doCheck = true;
checkPhase = ''
mypy --disallow-untyped-defs \
--no-implicit-optional \
--ignore-missing-imports ${testDriverScript}
pylint --errors-only ${testDriverScript}
'';
installPhase = ''
mkdir -p $out/bin
cp ${testDriverScript} $out/bin/nixos-test-driver
chmod u+x $out/bin/nixos-test-driver
# TODO: copy user script part into this file (append)
wrapProgram $out/bin/nixos-test-driver \
--prefix PATH : "${lib.makeBinPath [ qemu' coreutils ]}" \
'';
};
defaultTestScript = ''
start_all()
machine.wait_until_serial_output('child "init" exited with exit value 0')
'';
makeTest = with localPackages;
{ prefix, specs, platforms, basePackages, makeImage, startVM }:
{ name ? "unnamed", testScript ? defaultTestScript,
# Skip linting (mainly intended for faster dev cycles)
skipLint ? false, ... }@t:
let
testDriverName = "genode-test-driver-${name}";
buildVM = vmName:
{ config, inputs, env ? { }, extraPaths ? [ ] }:
let
storeTarball = localPackages.runCommand "store" { } ''
mkdir -p $out
tar cf "$out/store.tar" --absolute-names ${toString inputs} ${
toString extraPaths
}
'';
addManifest = drv:
drv // {
manifest =
nixpkgs.runCommand "${drv.name}.dhall" { inherit drv; } ''
set -eu
echo -n '[' >> $out
find $drv/ -type f -printf ',{mapKey= "%f",mapValue="%p"}' >> $out
${if builtins.elem "lib" drv.outputs then
''
find ${drv.lib}/ -type f -printf ',{mapKey= "%f",mapValue="%p"}' >> $out''
else
""}
echo -n ']' >> $out
'';
};
storeManifest = lib.mergeManifests (map addManifest inputs);
manifest = lib.mergeManifests (map addManifest (basePackages
++ [ testPkgs.sotest-producer storeTarball ]
++ map testPkgs.genodeSources.depot [
"init"
"vfs"
"cached_fs_rom"
]));
config' = "${
./test-wrapper.dhall
} (${config}) $(stat --format '%s' ${storeTarball}/store.tar) ${storeManifest} ${manifest}";
env' = {