2
0
Fork 0

Initial NixOS module

The module can be tested by the command `nix run .#nixosModule`.
This commit is contained in:
Ehmry - 2020-06-08 17:48:40 +05:30
parent 8134e9bd13
commit a03f7d7d63
13 changed files with 2333 additions and 7 deletions

View File

@ -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};
});
in checks' // {
x86_64-linux = with builtins;
foldl' (x: y: x // y) { } (attrValues checks');
} // {
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 { x86_64-linux = checks'.x86_64-linux-x86_64-genode; };
};
}

View File

@ -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))
}
])
}
''

235
nixos-modules/default.nix Normal file
View File

@ -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" ''
<focus label="focus"/>
'';
};
};
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 <code>List Prelude.XML.Type</code>";
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}";
}

View File

@ -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
''
<vfs>
<dir name="dev">
<log name="stderr" label="stderr"/>
<log name="stdout" label="stdout"/>
<null/>
<pipe/>
<rtc/>
<terminal/>
<zero/>
</dir>
<dir name="usr"><dir name="bin"><symlink name="env" target="${params.coreutils}/bin/env"/></dir></dir>
<dir name="tmp"><ram/></dir>
<dir name="nix"><dir name="store"><fs label="nix/store" writeable="no"/></dir></dir>
</vfs>
<default-policy root="/" writeable="yes"/>
''
]
}
, 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
''
<libc stdin="/dev/terminal" stdout="/dev/terminal" stderr="/dev/terminal" pipe="/dev/pipe" rtc="/dev/rtc"/>
<vfs> <fs/> </vfs>
<env key="TERM" value="screen"/>
<env key="PATH" value="${params.path}" />
<env key="PS1" value="system:$PWD> " />
''
]
# 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"
]
}

View File

@ -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")
]
}

View File

@ -0,0 +1 @@
"24b69406-18a1-428d-908e-d21a1437122c"

View File

@ -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

View File

@ -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
''
<report pci="yes"/>
<policy label_suffix="ps2_drv">
<device name="PS2"/>
</policy>
<policy label_suffix="intel_fb_drv">
<pci class="VGA"/>
<pci bus="0" device="0" function="0"/>
<pci class="ISABRIDGE"/>
</policy>
<policy label_suffix="audio">
<pci class="AUDIO"/>
<pci class="HDAUDIO"/>
</policy>
<policy label="acpica"/>
''
]
# 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

View File

@ -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" ]
}

View File

@ -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 =
''
<VirtualBox xmlns="http://www.virtualbox.org/" version="1.14-freebsd">
<Machine uuid="{37ab43a5-38d8-4491-93f5-5b0b077f5c32}" name="ubuntu_16_04_64" OSType="Ubuntu_64" snapshotFolder="Snapshots" lastStateChange="2018-01-23T18:40:00Z">
<MediaRegistry>
<HardDisks>
<HardDisk uuid="{${params.vdiUuid}}" location="${params.vdiFilename}" format="VDI" type="Normal"/>
</HardDisks>
<DVDImages/>
</MediaRegistry>
<Hardware>
<CPU count="2">
<PAE enabled="true"/>
<LongMode enabled="true"/>
<HardwareVirtExLargePages enabled="false"/>
</CPU>
<Memory RAMSize="${Prelude.Natural.show
params.memorySize}"/>
<HID Pointing="USBTablet"/>
<Display VRAMSize="20"/>
<RemoteDisplay enabled="false"/>
<BIOS>
<IOAPIC enabled="true"/>
</BIOS>
<USB>
<Controllers/>
</USB>
<Network>
<Adapter slot="0" enabled="true" MACAddress="0800271D7901" cable="true" type="82540EM">
<BridgedInterface/>
</Adapter>
</Network>
<UART>
<Port slot="0" enabled="false" IOBase="0x3f8" IRQ="4" hostMode="Disconnected"/>
<Port slot="1" enabled="false" IOBase="0x2f8" IRQ="3" hostMode="Disconnected"/>
</UART>
<LPT>
<Port slot="0" enabled="false" IOBase="0x378" IRQ="7"/>
<Port slot="1" enabled="false" IOBase="0x378" IRQ="7"/>
</LPT>
<AudioAdapter controller="HDA" driver="OSS" enabled="false"/>
<RTC localOrUTC="UTC"/>
<SharedFolders/>
</Hardware>
<StorageControllers>
<StorageController name="SATA" type="AHCI" PortCount="4" useHostIOCache="true" Bootable="true" IDE0MasterEmulationPort="0" IDE0SlaveEmulationPort="1" IDE1MasterEmulationPort="2" IDE1SlaveEmulationPort="3">
<AttachedDevice type="HardDisk" port="0" device="0">
<Image uuid="{${params.vdiUuid}}"/>
</AttachedDevice>
</StorageController>
</StorageControllers>
</Machine>
</VirtualBox>
''
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

View File

@ -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")
]
}

View File

@ -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
''
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
<domain name="default" layer="2" hover="always" />
<domain name="decorator" layer="2" content="client" label="no" hover="always" />
<domain name="desktop" layer="2" content="client" label="no" hover="always" />
<domain name="background" layer="3" content="client" label="no" hover="always" />
<global-key name="KEY_SCREEN" label="wm -> decorator" />
''
]
, 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
''
<report rules="yes"/>
<rules>
<screen name="screen_1"/>
<screen name="screen_2"/>
<screen name="screen_3"/>
<screen name="screen_4"/>
<screen name="screen_5"/>
<screen name="screen_6"/>
<screen name="screen_7"/>
<screen name="screen_8"/>
<screen name="screen_9"/>
<screen name="screen_0"/>
<assign label_prefix="" target="screen_1" xpos="any" ypos="any"/>
</rules>
<press key="KEY_SCREEN">
<press key="KEY_TAB" action="next_window">
<release key="KEY_TAB">
<release key="KEY_SCREEN" action="raise_window"/>
</release>
<release key="KEY_SCREEN" action="raise_window"/>
</press>
<press key="KEY_LEFTSHIFT">
<press key="KEY_TAB" action="prev_window">
<release key="KEY_TAB">
<release key="KEY_SCREEN" action="raise_window"/>
</release>
</press>
</press>
<press key="KEY_ENTER" action="toggle_fullscreen"/>
<press key="KEY_1" action="screen" target="screen_1"/>
<press key="KEY_2" action="screen" target="screen_2"/>
<press key="KEY_3" action="screen" target="screen_3"/>
<press key="KEY_4" action="screen" target="screen_4"/>
<press key="KEY_5" action="screen" target="screen_5"/>
<press key="KEY_6" action="screen" target="screen_6"/>
<press key="KEY_7" action="screen" target="screen_7"/>
<press key="KEY_8" action="screen" target="screen_8"/>
<press key="KEY_9" action="screen" target="screen_9"/>
<press key="KEY_0" action="screen" target="screen_0"/>
</press>
''
]
}
, 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"
]
}

View File

@ -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