diff --git a/nixos-modules/genode-core.nix b/nixos-modules/genode-core.nix
index ab0fee3..73759a8 100644
--- a/nixos-modules/genode-core.nix
+++ b/nixos-modules/genode-core.nix
@@ -1,38 +1,70 @@
{ config, pkgs, lib, modulesPath, ... }:
with lib;
-let localPackages = pkgs.buildPackages;
+let
+ localPackages = pkgs.buildPackages;
+ coreROMs = mkOption {
+ type = with types; listOf str;
+ default = [ ];
+ description = ''
+ List of label suffixes that when matched against
+ ROM requests shall be forwared to the core.
+ '';
+ example = [ "platform_info" ];
+ };
+ inputs = mkOption {
+ description = "List of packages to build a ROM store with.";
+ default = [ ];
+ type = types.listOf types.package;
+ };
in {
options.genode = {
+
core = {
prefix = mkOption {
type = types.str;
example = "hw-pc-";
+ description = "String prefix signifying the Genode core in use.";
};
supportedSystems = mkOption {
type = types.listOf types.str;
example = [ "i686-genode" "x86_64-genode" ];
+ description = "Hardware supported by this core.";
};
- basePackages = mkOption { type = types.listOf types.package; };
+ basePackages = mkOption {
+ type = types.listOf types.package;
+ description = ''
+ List of packages to make availabe before the Nix store is ready.
+ These are baked into .
+ '';
+ };
+
+ children = mkOption {
+ type = with types;
+ attrsOf (submodule {
+ options = {
+ inherit coreROMs inputs;
+ configFile = mkOption {
+ type = types.path;
+ description = ''
+ Set of children at the lowest init level, these children must not
+ have any dependency on a Nix store.
+ Configuration format is a Dhall configuration of type
+ Genode.Init.Child.Type.
+ See https://git.sr.ht/~ehmry/dhall-genode/tree/master/Init/Child/Type
+ '';
+ };
+ };
+ });
+ };
};
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 = ''
@@ -49,9 +81,59 @@ in {
romModules = mkOption {
type = types.attrsOf types.path;
+ default = { };
description = "Attr set of initial ROM modules";
};
+ storeFsUuid = mkOption {
+ type = types.str;
+ default = import ./store-fs-uuid;
+ description = "Custom partition type of the nix-store file-system.";
+ };
+
+ storePartUuid = mkOption {
+ type = types.str;
+ default = import ./partition-type;
+ description = "Custom partition type of the nix-store file-system.";
+ };
+
+ storeBackend = mkOption {
+ type = types.enum [ "tarball" "usb" ]; # "parent"?
+ default = "tarball";
+ description = ''
+ Backend for the initial /nix/store file-system.
+
+
+
+
+ tarball
+
+
+ An in-memory tarball.
+
+
+
+
+
+ usb
+
+
+ An EXT2 file-system backed by USB storage.
+
+
+
+
+
+ '';
+ };
+
+ storePaths = mkOption {
+ type = with types; listOf package;
+ description = ''
+ Derivations to be included in the Nix store in the generated boot image.
+ '';
+ };
+
};
};
@@ -75,20 +157,17 @@ in {
};
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) + "]";
- };
+ 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) + "]";
romDirectories = filterAttrs (_: value: value != null) (mapAttrs
(name: value:
@@ -108,18 +187,113 @@ in {
message = "invalid Genode core for this system";
}];
+ genode.core.basePackages =
+ lib.optional (config.genode.boot.storeBackend == "usb")
+ pkgs.genodePackages.part_block;
+
+ genode.core.children =
+ # Component to steer the store_fs to a specific partition
+ (if config.genode.boot.storeBackend == "usb" then {
+ part_block.configFile = builtins.toFile "part_block.dhall" ''
+ let Genode = env:DHALL_GENODE
+
+ let Init = Genode.Init
+
+ in Init.Child.flat
+ Init.Child.Attributes::{
+ , binary = "part_block"
+ , resources = Init.Resources::{ ram = Genode.units.MiB 8 }
+ , config = Init.Config::{
+ , attributes = toMap { ignore_mbr = "yes" }
+ , policies =
+ [ Init.Config.Policy::{
+ , service = "Block"
+ , label = Init.LabelSelector.prefix "store_fs"
+ , attributes = toMap
+ { partition = "1"
+ , writeable = "yes"
+ , TODO = "select by partition UUID"
+ }
+ }
+ ]
+ }
+ }
+ '';
+ } else
+ { }) // {
+ store_fs.configFile = let
+
+ storeVfsConfig = {
+ tarball = ''
+ VFS.vfs [ VFS.leafAttrs "tar" (toMap { name = "${config.system.build.tarball.fileName}.tar" }) ]
+ '';
+ usb = ''
+ VFS.vfs [ VFS.leafAttrs "rump" (toMap { fs = "ext2fs", ram="12M" }) ]
+ '';
+ }.${config.genode.boot.storeBackend};
+
+ storeResources = {
+ tarball = "Init.Resources.default";
+ usb = "Init.Resources::{ caps = 256, ram = Genode.units.MiB 16 }";
+ }.${config.genode.boot.storeBackend};
+
+ in builtins.toFile "store_fs.dhall" ''
+ let Genode = env:DHALL_GENODE
+
+ let Init = Genode.Init
+
+ let VFS = Genode.VFS
+
+ in Init.Child.flat
+ Init.Child.Attributes::{
+ , binary = "vfs"
+ , resources = ${storeResources}
+ , config = Init.Config::{
+ , content = [ ${storeVfsConfig} ]
+ , 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 = "/" }
+ }
+ ]
+ }
+ }
+ '';
+ };
+
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
- jitter_sponge
- report_rom
- vfs
- ])));
+
+ storeBackendInputs = {
+ tarball = [ config.system.build.tarball ];
+ usb = [ pkgs.genodePackages.rump ];
+ }.${config.genode.boot.storeBackend};
+
+ coreInputs = with builtins;
+ concatMap (getAttr "inputs") (attrValues config.genode.core.children);
+
+ manifest =
+ # Manifests are Dhall metadata to be attached to every
+ # package to be used for dynamically buildings enviroments
+ # using Dhall expressions. Probably not worth pursuing.
+ pkgs.writeText "manifest.dhall" (mergeManifests (map addManifest
+ (with pkgs.genodePackages;
+ config.genode.core.basePackages ++ storeBackendInputs
+ ++ [ init cached_fs_rom jitter_sponge report_rom vfs ]
+ ++ coreInputs))
+ + lib.optionalString (config.genode.boot.romModules != { }) ''
+ # [ { mapKey = "romModules", mapValue = [ ${
+ toString (mapAttrsToList
+ (k: v: '', { mapKey = "${k}", mapValue = "${v}" }'')
+ config.genode.boot.romModules)
+ }] } ]'');
storeRomPolicies = mapAttrsToList
(name: value: '', { mapKey = "${name}", mapValue = "${value}" }'')
@@ -134,23 +308,38 @@ in {
Genode.Init.LabelSelector.Type.Partial
{ prefix = Some "nixos -> ${name}", suffix = Some "${suffix}" }
}
- , route = Genode.Init.Route.parent (Some "${suffix}")
+ , route = Genode.Init.Route.parentLabel "${suffix}"
}
'') value.coreROMs) config.genode.init.children));
+ extraCoreChildren = "[ ${
+ toString (lib.mapAttrsToList (name: value:
+ '', { mapKey = "${name}", mapValue = ${value.configFile} }'')
+ config.genode.core.children)
+ } ]";
+
in localPackages.runCommand "boot.dhall" { } ''
cat > $out << EOF
let Genode = env:DHALL_GENODE in
+ let VFS = Genode.VFS
+ let XML = Genode.Prelude.XML
+ in
${./store-wrapper.dhall}
- (${config.genode.init.configFile})
- "${config.system.build.tarball.fileName}.tar"
- $(stat --format '%s' ${tarball})
- ([${toString storeRomPolicies} ] : Genode.Prelude.Map.Type Text Text)
- ([${extraRoutes} ] : List Genode.Init.ServiceRoute.Type)
- ${manifest}
+ { extraCoreChildren = ${extraCoreChildren}
+ , subinit = ${config.genode.init.configFile}
+ , storeSize = $(stat --format '%s' ${tarball})
+ , storeRomPolicies = [${
+ toString storeRomPolicies
+ } ] : Genode.Prelude.Map.Type Text Text
+ , routes = [${extraRoutes} ] : List Genode.Init.ServiceRoute.Type
+ , bootManifest = ${manifest}
+ }
EOF
'';
+ genode.boot.storePaths = with builtins;
+ [ config.genode.init.configFile ] ++ (attrValues romDirectories);
+
# Create the tarball of the store to live in core ROM
system.build.tarball =
pkgs.callPackage "${modulesPath}/../lib/make-system-tarball.nix" {
@@ -181,6 +370,25 @@ in {
xmllint --noout $out
'';
+ system.build.bootDriveImage = let
+ espImage = import ./lib/make-esp-fs.nix { inherit config pkgs; };
+ storeFsImage =
+ pkgs.callPackage ./lib/make-ext2-fs.nix { inherit config pkgs; };
+ bootDriveImage = import ./lib/make-bootable-image.nix {
+ inherit config pkgs espImage storeFsImage;
+ };
+ in bootDriveImage;
+
+ # virtualisation.useEFIBoot = config.genode.boot.storeBackend == "usb";
+
+ virtualisation.qemu.options =
+ lib.optionals (config.genode.boot.storeBackend == "usb") [
+ "-bios ${pkgs.buildPackages.OVMF.fd}/FV/OVMF.fd"
+ "-drive id=usbdisk,file=${config.system.build.bootDriveImage},if=none,readonly"
+ "-usb"
+ "-device usb-storage,drive=usbdisk"
+ ];
+
};
}
diff --git a/nixos-modules/hardware.nix b/nixos-modules/hardware.nix
index 4066ac4..9ad92c3 100644
--- a/nixos-modules/hardware.nix
+++ b/nixos-modules/hardware.nix
@@ -30,6 +30,11 @@ with lib;
'';
};
+ hardware.usb.genode.enable = lib.mkEnableOption "USB driver";
+
+ hardware.usb.genode.storage.enable =
+ lib.mkEnableOption "USB mass storage driver";
+
};
config = {
@@ -47,13 +52,18 @@ with lib;
in lib.mapAttrsToList addrCheck config.networking.interfaces
++ lib.mapAttrsToList routeCheck config.networking.interfaces;
+ hardware.usb.genode.storage.enable = config.genode.boot.storeBackend
+ == "usb";
+
+ hardware.usb.genode.enable = config.hardware.usb.genode.storage.enable;
+
hardware.genode.platform.policies = lib.lists.imap0 (i: name:
builtins.toFile (name + ".platform-policy.dhall") ''
let Genode = env:DHALL_GENODE
in Genode.Init.Config.Policy::{
, service = "Platform"
- , label = Genode.Init.LabelSelector.prefix "${name}.driver"
+ , label = Genode.Init.LabelSelector.prefix "nixos -> ${name}.driver"
, content =
[ Genode.Prelude.XML.leaf
{ name = "pci"
@@ -64,12 +74,25 @@ with lib;
}
]
}
- '') (builtins.attrNames config.networking.interfaces);
+ '') (builtins.attrNames config.networking.interfaces)
+ ++ lib.optional config.hardware.usb.genode.enable
+ (builtins.toFile ("usb.platform-policy.dhall") ''
+ let Genode = env:DHALL_GENODE
- genode.core.basePackages = with pkgs.genodePackages; [
- acpi_drv
- platform_drv
- ];
+ in Genode.Init.Config.Policy::{
+ , service = "Platform"
+ , label = Genode.Init.LabelSelector.prefix "usb_drv"
+ , content =
+ [ Genode.Prelude.XML.leaf
+ { name = "pci", attributes = toMap { class = "USB" } }
+ ]
+ }
+ '');
+
+ 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
@@ -108,7 +131,10 @@ with lib;
, caps = 128
, ram = Genode.units.MiB 4
}
- , routes = [ Init.ServiceRoute.parent "IO_MEM" ]
+ , routes = [
+ , Init.ServiceRoute.parent "IO_MEM"
+ , Init.ServiceRoute.parent "Platform"
+ ]
, config = Init.Config::{
, attributes = toMap { verbose = "true" }
, policies = ${policies}
@@ -199,7 +225,9 @@ with lib;
};
}) config.networking.interfaces;
- in nics // (lib.filterAttrs (n: v: v != null) sockets) // {
+ in lib.filterAttrs (n: v: v != null) (nics // sockets);
+
+ genode.core.children = {
acpi_drv = {
coreROMs = [ "acpi_drv" ];
@@ -259,8 +287,52 @@ with lib;
}
'';
};
+ } // (if config.hardware.usb.genode.enable then {
- };
+ usb_drv = {
+ coreROMs = [ "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.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
+ }
+ }
+ '';
+ };
+ } else
+ { });
};
diff --git a/nixos-modules/lib/make-bootable-image.nix b/nixos-modules/lib/make-bootable-image.nix
new file mode 100644
index 0000000..3a12cbf
--- /dev/null
+++ b/nixos-modules/lib/make-bootable-image.nix
@@ -0,0 +1,69 @@
+# Builds a compressed EFI System Partition image
+{ config, pkgs, espImage, storeFsImage }:
+
+pkgs.stdenv.mkDerivation {
+ name = "boot.qcow2";
+
+ nativeBuildInputs = with pkgs.buildPackages; [
+ config.system.build.qemu
+ utillinux
+ zstd
+ ];
+
+ buildCommand = ''
+ img=./temp.raw
+ blockSize=512
+ sectorSize=$(( $blockSize * 1 ))
+ imgBytes=0
+
+ espSectorOffset=2048
+ esbByteOffset=$(( $espSectorOffset * $sectorSize ))
+
+ # Pad the front of the image
+ echo "Pad front of image with " $esbByteOffset " bytes"
+ truncate --size=$esbByteOffset $img
+
+ # Concatentenate the ESP
+ echo "Concatenate ESP ${espImage}"
+ zstdcat ${espImage} >> $img
+
+ imgBytes=$(stat --format=%s $img)
+ echo "Image is $(( $imgBytes >> 20 )) MiB with ESP partition"
+
+ nixSectorOffset=$(( ($imgBytes + $sectorSize - 1) / $sectorSize ))
+ nixByteOffset=$(( $nixSectorOffset * $sectorSize ))
+
+ # Pad the ESP
+ echo "Pad end of ESP with " $(( $nixByteOffset - $imgBytes )) " bytes"
+ truncate --size=$nixByteOffset $img
+
+ # Concatenate the nix partition
+ echo "Concatenate store ${storeFsImage}"
+ zstdcat ${storeFsImage} >> $img
+
+ imgBytes=$(stat --format=%s $img)
+ echo "Image is $(( $imgBytes >> 20 )) MiB with store partition"
+
+ endSectorOffset=$(( ($(stat --format=%s $img) + $sectorSize + 1) / $sectorSize ))
+ endByteOffset=$(( $endSectorOffset * $sectorSize ))
+
+ # Pad the end of the image
+ echo "Pad end of store with $(( $endByteOffset - $imgBytes )) bytes"
+ truncate --size=$endByteOffset $img
+
+ imgBytes=$(stat --format=%s $img)
+ echo "Image is $(( $imgBytes >> 20 )) MiB with final padding"
+
+ efiUuid=C12A7328-F81F-11D2-BA4B-00A0C93EC93B
+
+ # Create the partition table
+ sfdisk $img < embedded.cfg
+ insmod configfile
+ insmod efi_gop
+ insmod efi_uga
+ insmod ext2
+ insmod normal
+ insmod part_gpt
+ insmod search_fs_uuid
+ search.fs_uuid ${config.genode.boot.storeFsUuid} root
+ set prefix=($root)/boot/grub
+ configfile /boot/grub/grub.cfg
+ EOF
+
+ grub-script-check embedded.cfg
+
+ ${grub'}/bin/grub-mkimage \
+ --config=embedded.cfg \
+ --output=$bootdir/boot${targetArch}.efi \
+ --prefix=/boot/grub \
+ --format=${grub'.grubTarget} \
+ $MODULES
+
+ # Make the ESP image twice as large as necessary
+ imageBytes=$(du --summarize --block-size=4096 --total $bootdir | tail -1 | awk '{ print int($1 * 8192) }')
+
+ truncate --size=$imageBytes $img
+ mkfs.vfat -n EFIBOOT --invariant $img
+ mcopy -sv -i $img EFI ::
+ fsck.vfat -nv $img
+
+ zstd --verbose --no-progress ./$img -o $out
+ '';
+}
diff --git a/nixos-modules/lib/make-ext2-fs.nix b/nixos-modules/lib/make-ext2-fs.nix
new file mode 100644
index 0000000..b2dc092
--- /dev/null
+++ b/nixos-modules/lib/make-ext2-fs.nix
@@ -0,0 +1,77 @@
+{ config, pkgs }:
+
+let
+ grub' = pkgs.buildPackages.grub2_efi;
+ sdClosureInfo = pkgs.buildPackages.closureInfo {
+ rootPaths = config.genode.boot.storePaths;
+ };
+in pkgs.stdenv.mkDerivation {
+ name = "ext2-fs.img.zstd";
+
+ nativeBuildInputs = with pkgs.buildPackages; [
+ e2fsprogs.bin
+ grub'
+ libfaketime
+ perl
+ fakeroot
+ zstd
+ ];
+
+ buildCommand = ''
+ img=temp.raw
+
+ # Create nix/store before copying path
+ mkdir -p ./rootImage/boot/grub ./rootImage/nix/store
+
+ cat < ./rootImage/boot/grub/grub.cfg
+ set timeout=3
+ set default=0
+ set gfxpayload=auto
+
+ ${config.boot.loader.grub.extraEntries}
+ EOF
+
+ grub-script-check ./rootImage/boot/grub/grub.cfg
+
+ xargs -I % cp -a --reflink=auto % -t ./rootImage/nix/store/ < ${sdClosureInfo}/store-paths
+ (
+ GLOBIGNORE=".:.."
+ shopt -u dotglob
+
+ for f in ./files/*; do
+ cp -a --reflink=auto -t ./rootImage/ "$f"
+ done
+ )
+
+ # Also include a manifest of the closures in a format suitable for nix-store --load-db
+ cp ${sdClosureInfo}/registration ./rootImage/nix-path-registration
+
+ # Make a crude approximation of the size of the target image.
+ # If the script starts failing, increase the fudge factors here.
+ numInodes=$(find ./rootImage | wc -l)
+ numDataBlocks=$(du -s -c -B 4096 --apparent-size ./rootImage | tail -1 | awk '{ print int($1 * 1.10) }')
+ bytes=$((2 * 4096 * $numInodes + 4096 * $numDataBlocks))
+ echo "Creating an EXT2 image of $bytes bytes (numInodes=$numInodes, numDataBlocks=$numDataBlocks)"
+
+ truncate --size=$bytes $img
+
+ faketime -f "1970-01-01 00:00:01" fakeroot mkfs.ext2 -L NIXOS_GENODE -U ${config.genode.boot.storeFsUuid} -d ./rootImage $img
+
+ export EXT2FS_NO_MTAB_OK=yes
+ # I have ended up with corrupted images sometimes, I suspect that happens when the build machine's disk gets full during the build.
+ if ! fsck.ext2 -n -f $img; then
+ echo "--- Fsck failed for EXT2 image of $bytes bytes (numInodes=$numInodes, numDataBlocks=$numDataBlocks) ---"
+ cat errorlog
+ return 1
+ fi
+
+ echo "Resizing to minimum allowed size"
+ resize2fs -M $img
+
+ # And a final fsck, because of the previous truncating.
+ fsck.ext2 -n -f $img
+
+ # Compress to store
+ zstd --verbose --no-progress ./$img -o $out
+ '';
+}
diff --git a/nixos-modules/nova.nix b/nixos-modules/nova.nix
index da52d0e..0ba09c4 100644
--- a/nixos-modules/nova.nix
+++ b/nixos-modules/nova.nix
@@ -7,6 +7,17 @@ let
inherit (config.nixpkgs) system localSystem crossSystem;
inherit pkgs;
};
+
+ bootDir = pkgs.runCommand "${config.system.name}-bootdir" { } ''
+ mkdir $out
+ gz() {
+ gzip --keep --to-stdout "$1" > "$2"
+ }
+ gz ${pkgs.genodePackages.genodeSources}/tool/boot/bender $out/bender.gz
+ gz ${pkgs.genodePackages.NOVA}/hypervisor-x86_64 $out/hypervisor.gz
+ gz ${config.genode.boot.image}/image.elf $out/image.elf.gz
+ '';
+
in {
genode.core = {
prefix = "nova-";
@@ -15,13 +26,27 @@ in {
};
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;
-
};
+ genode.boot.storePaths =
+ lib.optional (config.genode.boot.storeBackend == "usb") bootDir;
+
+ virtualisation.qemu.options =
+ lib.optionals (!config.virtualisation.useBootLoader) [
+ "-kernel '${pkgs.genodePackages.bender}/share/bender/bender'"
+ "-initrd '${pkgs.genodePackages.NOVA}/hypervisor-x86_64 arg=iommu logmem novpid serial,${config.genode.boot.image}/image.elf'"
+ ];
+
+ boot.loader.grub.extraEntries = ''
+ menuentry 'Genode on NOVA' {
+ insmod multiboot2
+ insmod gzio
+ multiboot2 ${bootDir}/bender.gz serial_fallback
+ module2 ${bootDir}/hypervisor.gz hypervisor iommu logmem novga novpid serial
+ module2 ${bootDir}/image.elf.gz image.elf
+ }
+ '';
+
}
diff --git a/nixos-modules/partition-type b/nixos-modules/partition-type
new file mode 100644
index 0000000..2cca25d
--- /dev/null
+++ b/nixos-modules/partition-type
@@ -0,0 +1 @@
+"24b69406-18a1-428d-908e-d21a1437122c"
diff --git a/nixos-modules/qemu-vm.nix b/nixos-modules/qemu-vm.nix
index 9f91cb0..d0b0feb 100644
--- a/nixos-modules/qemu-vm.nix
+++ b/nixos-modules/qemu-vm.nix
@@ -83,9 +83,9 @@ let
imap1 (idx: drive: drive // { device = driveDeviceName idx; });
efiPrefix = if (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) then
- "${pkgs.OVMF.fd}/FV/OVMF"
+ "${pkgs.buildPackages.OVMF.fd}/FV/OVMF"
else if pkgs.stdenv.isAarch64 then
- "${pkgs.OVMF.fd}/FV/AAVMF"
+ "${pkgs.buildPackages.OVMF.fd}/FV/AAVMF"
else
throw "No EFI firmware available for platform";
efiFirmware = "${efiPrefix}_CODE.fd";
@@ -516,10 +516,6 @@ in {
"-device usb-kbd"
"-device usb-tablet"
])
- (mkIf (!cfg.useBootLoader) [
- "-kernel ${config.genode.boot.kernel}"
- "-initrd ${config.genode.boot.initrd}"
- ])
(mkIf cfg.useEFIBoot [
"-drive if=pflash,format=raw,unit=0,readonly,file=${efiFirmware}"
"-drive if=pflash,format=raw,unit=1,file=$NIX_EFI_VARS"
diff --git a/nixos-modules/store-fs-uuid b/nixos-modules/store-fs-uuid
new file mode 100644
index 0000000..7325548
--- /dev/null
+++ b/nixos-modules/store-fs-uuid
@@ -0,0 +1 @@
+"9668f8dd-d9a0-4398-a55a-0d499d5e5cbb"
diff --git a/nixos-modules/store-wrapper.dhall b/nixos-modules/store-wrapper.dhall
index 15f089a..dbc0db0 100644
--- a/nixos-modules/store-wrapper.dhall
+++ b/nixos-modules/store-wrapper.dhall
@@ -2,195 +2,184 @@ let Genode = env:DHALL_GENODE
let Prelude = Genode.Prelude
+let XML = Prelude.XML
+
let Init = Genode.Init
let Child = Init.Child
let TextMapType = Prelude.Map.Type Text
+let ChildMapType = TextMapType Child.Type
+
let Manifest/Type = TextMapType (TextMapType Text)
-in λ(subinit : Init.Type) →
- λ(storeName : Text) →
- λ(storeSize : Natural) →
- λ(storeRomPolicies : Prelude.Map.Type Text Text) →
- λ(routes : List Init.ServiceRoute.Type) →
- λ(bootManifest : Manifest/Type) →
+in λ ( params
+ : { extraCoreChildren : ChildMapType
+ , subinit : Init.Type
+ , storeSize : Natural
+ , storeRomPolicies : Prelude.Map.Type Text Text
+ , routes : List Init.ServiceRoute.Type
+ , bootManifest : Manifest/Type
+ }
+ ) →
Genode.Boot::{
, config = Init::{
- , routes
+ , routes = params.routes
, 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
- "jitter_sponge"
- ( Child.flat
- Child.Attributes::{
- , binary = "jitter_sponge"
- , provides = [ "Terminal" ]
- , config = Init.Config::{
- , policies =
- [ Init.Config.Policy::{
- , service = "Terminal"
- , label = Init.LabelSelector.suffix "entropy"
- }
- ]
+ in [ child
+ "timer"
+ ( Child.flat
+ Child.Attributes::{
+ , binary = "timer_drv"
+ , provides = [ "Timer" ]
+ , config = Init.Config::{
+ , policies =
+ [ Init.Config.Policy::{
+ , service = "Timer"
+ , label = Init.LabelSelector.none
+ }
+ ]
+ }
}
- }
- )
- , child
- "store_fs"
- ( Child.flat
- Child.Attributes::{
- , binary = "vfs"
- , config = Init.Config::{
- , content =
- let VFS = Genode.VFS
-
- in [ VFS.vfs
- [ VFS.leafAttrs
- "tar"
- (toMap { name = storeName })
- ]
+ )
+ , child
+ "rtc"
+ ( Child.flat
+ Child.Attributes::{
+ , binary = "rtc_drv"
+ , provides = [ "Rtc" ]
+ , routes = [ Init.ServiceRoute.parent "IO_PORT" ]
+ }
+ )
+ , child
+ "jitter_sponge"
+ ( Child.flat
+ Child.Attributes::{
+ , binary = "jitter_sponge"
+ , provides = [ "Terminal" ]
+ , config = Init.Config::{
+ , policies =
+ [ Init.Config.Policy::{
+ , service = "Terminal"
+ , label = Init.LabelSelector.suffix "entropy"
+ }
+ ]
+ }
+ }
+ )
+ , child
+ "store_rom"
+ ( Child.flat
+ Child.Attributes::{
+ , binary = "cached_fs_rom"
+ , provides = [ "ROM" ]
+ , resources = Init.Resources::{
+ , ram = params.storeSize + Genode.units.MiB 1
+ }
+ , config = Init.Config::{
+ , policies =
+ [ Init.Config.Policy::{
+ , service = "ROM"
+ , label =
+ Init.LabelSelector.prefix
+ "nixos -> /nix/store"
+ , diag = Some True
+ }
]
- , 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
- }
- , config = Init.Config::{
- , policies =
- [ Init.Config.Policy::{
- , service = "ROM"
- , label =
- Init.LabelSelector.prefix
- "nixos -> /nix/store"
- }
- ]
- # ( let Entry = Prelude.Map.Entry Text Text
+ # ( let Entry = Prelude.Map.Entry Text Text
- in Prelude.List.concatMap
- Entry
- Init.Config.Policy.Type
- ( λ(e : Entry) →
- [ Init.Config.Policy::{
- , service = "ROM"
- , label =
- Init.LabelSelector.prefix
- "nixos -> ${e.mapKey}"
- , attributes = toMap
- { directory =
- "${e.mapValue}/bin"
- }
- }
- , Init.Config.Policy::{
- , service = "ROM"
- , label =
- Init.LabelSelector.Type.Partial
- { prefix = Some
- "nixos -> ${e.mapKey}"
- , suffix = Some ".lib.so"
+ in Prelude.List.concatMap
+ Entry
+ Init.Config.Policy.Type
+ ( λ(e : Entry) →
+ [ Init.Config.Policy::{
+ , service = "ROM"
+ , diag = Some True
+ , label =
+ Init.LabelSelector.prefix
+ "nixos -> ${e.mapKey}"
+ , attributes = toMap
+ { directory =
+ "${e.mapValue}/bin"
}
- , attributes = toMap
- { directory =
- "${e.mapValue}/lib"
- }
- }
- ]
- )
- storeRomPolicies
- )
- }
- }
- )
- , child
- "nixos"
- ( Init.toChild
- subinit
- Init.Attributes::{
- , exitPropagate = True
- , resources = Init.Resources::{
- , ram = Genode.units.MiB 4
- }
- , routes =
- let parentROMs =
- Prelude.List.concatMap
- Text
- Init.ServiceRoute.Type
- ( λ(suffix : Text) →
- Prelude.List.map
- Text
- Init.ServiceRoute.Type
- ( λ(prefix : Text) →
- { service =
- { name = "ROM"
+ }
+ , Init.Config.Policy::{
+ , service = "ROM"
+ , diag = Some True
, label =
Init.LabelSelector.Type.Partial
- { prefix = Some prefix
- , suffix = Some suffix
+ { prefix = Some
+ "nixos -> ${e.mapKey}"
+ , suffix = Some ".so"
}
+ , attributes = toMap
+ { directory =
+ "${e.mapValue}/lib"
+ }
}
- , route =
- Init.Route.parent
- (Some suffix)
- }
+ ]
)
- ( Prelude.Map.keys
- Text
- Init.Child.Type
- subinit.children
- )
- )
+ params.storeRomPolicies
+ )
+ }
+ }
+ )
+ ]
+ # params.extraCoreChildren
+ # [ child
+ "nixos"
+ ( Init.toChild
+ params.subinit
+ Init.Attributes::{
+ , exitPropagate = True
+ , resources = Init.Resources::{
+ , ram = Genode.units.MiB 4
+ }
+ , routes =
+ let parentROMs =
+ Prelude.List.concatMap
+ Text
+ Init.ServiceRoute.Type
+ ( λ(suffix : Text) →
+ Prelude.List.map
+ Text
+ Init.ServiceRoute.Type
+ ( λ(prefix : Text) →
+ { service =
+ { name = "ROM"
+ , label =
+ Init.LabelSelector.Type.Partial
+ { prefix = Some prefix
+ , suffix = Some suffix
+ }
+ }
+ , route =
+ Init.Route.parent
+ (Some suffix)
+ }
+ )
+ ( Prelude.Map.keys
+ Text
+ Init.Child.Type
+ params.subinit.children
+ )
+ )
- in parentROMs
- [ "ld.lib.so", "vfs.lib.so", "init" ]
- # [ 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"
- ]
- }
- )
- ]
+ in parentROMs
+ [ "ld.lib.so", "vfs.lib.so", "init" ]
+ # [ 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"
+ ]
+ }
+ )
+ ]
}
, rom =
Genode.BootModules.toRomPaths
@@ -199,7 +188,7 @@ in λ(subinit : Init.Type) →
( Prelude.Map.values
Text
(Prelude.Map.Type Text Text)
- bootManifest
+ params.bootManifest
)
)
}
diff --git a/tests/lib/build-vms.nix b/tests/lib/build-vms.nix
index 1e3db3f..fcc32a6 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/hardware.nix
../../nixos-modules/qemu-vm.nix
{
key = "no-manual";