From 48eec79d4621d468470f172ecce2f8997717fcec Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Thu, 16 Jan 2020 18:43:24 +0100 Subject: [PATCH] Move packaging of Genode core repositories here --- apps/default.nix | 24 +++ apps/nova-image/default.nix | 36 +++++ apps/nova-iso/default.nix | 54 +++++++ apps/nova-iso/isolinux.cfg | 5 + apps/nova-modules.as.dhall | 117 +++++++++++++++ flake.lock | 32 ---- flake.nix | 12 +- lib/default.nix | 4 +- nixos/default.nix | 15 +- nixos/test.nix | 5 +- packages/NOVA/default.nix | 46 ++++++ packages/default.nix | 87 +++++------ packages/genode/default.nix | 275 ++++++++++++++++++++++++++++++++++ packages/genode/toolchain.nix | 75 ++++++++++ tests/driver-linux.nix | 2 +- tests/fs_report.nix | 10 +- tests/pci.nix | 8 +- tests/signal.nix | 2 +- tests/solo5/default.nix | 20 +-- 19 files changed, 714 insertions(+), 115 deletions(-) create mode 100644 apps/default.nix create mode 100644 apps/nova-image/default.nix create mode 100644 apps/nova-iso/default.nix create mode 100644 apps/nova-iso/isolinux.cfg create mode 100644 apps/nova-modules.as.dhall create mode 100644 packages/NOVA/default.nix create mode 100644 packages/genode/default.nix create mode 100644 packages/genode/toolchain.nix diff --git a/apps/default.nix b/apps/default.nix new file mode 100644 index 0000000..b3f48d8 --- /dev/null +++ b/apps/default.nix @@ -0,0 +1,24 @@ +{ nixpkgs, packages, dhallApps }: + +rec { + nova-image = let + drv = import ./nova-image { + stdenv = packages.stdenv; + inherit nixpkgs dhallApps packages; + }; + in { + type = "app"; + program = "${drv}/bin/nova-image"; + }; + + nova-iso = let + drv = import ./nova-iso { + stdenv = packages.stdenv; + inherit nixpkgs dhallApps packages nova-image; + }; + in { + type = "app"; + program = "${drv}/bin/nova-iso"; + }; + +} diff --git a/apps/nova-image/default.nix b/apps/nova-image/default.nix new file mode 100644 index 0000000..6398c6d --- /dev/null +++ b/apps/nova-image/default.nix @@ -0,0 +1,36 @@ +{ stdenv, nixpkgs, dhallApps, packages }: + +let inherit (packages.genode) base-nova; +in nixpkgs.writeScriptBin "nova-image" (with nixpkgs.buildPackages; + let inherit (stdenv) cc; + + in '' + #!${runtimeShell} + set -eu + + CC="${cc}/bin/${cc.targetPrefix}cc" + LD="${buildPackages.binutils}/bin/${buildPackages.binutils.targetPrefix}ld" + + TMPDIR="$(${coreutils}/bin/mktemp -p /tmp -d nova-iso.XXXX)" + # trap "rm -rf $TMPDIR" err exit + + CORE_NOVA="${base-nova}/lib/core-nova.o" + + export DHALL_PRELUDE=${packages.dhallPrelude}/package.dhall + export DHALL_GENODE=${packages.dhallGenode}/package.dhall + ${dhallApps.dhall.program} text <<< "(${ + ../nova-modules.as.dhall + }) ($@)" > "$TMPDIR/modules.as" + + # compile the boot modules into one object file + $CC -c -x assembler -o "$TMPDIR/boot_modules.o" "$TMPDIR/modules.as" + + # link final image + $LD -nostdlib \ + -T${base-nova.src}/repos/base/src/ld/genode.ld \ + -T${base-nova.src}/repos/base-nova/src/core/core-bss.ld \ + -z max-page-size=0x1000 \ + -Ttext=0x100000 -gc-sections \ + "$CORE_NOVA" "$TMPDIR/boot_modules.o" \ + -o "image.elf" + '') diff --git a/apps/nova-iso/default.nix b/apps/nova-iso/default.nix new file mode 100644 index 0000000..f6d1298 --- /dev/null +++ b/apps/nova-iso/default.nix @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: CC0-1.0 + +{ stdenv, nixpkgs, dhallApps, packages, nova-image }: + +nixpkgs.writeScriptBin "nova-iso" (with nixpkgs.buildPackages; + let inherit (stdenv) cc; + + in '' + #!${runtimeShell} + set -eu + + CC="${cc}/bin/${cc.targetPrefix}cc" + LD="${buildPackages.binutils}/bin/${buildPackages.binutils.targetPrefix}ld" + SYSLINUX="${syslinux}/share/syslinux" + + TMPDIR="$(${coreutils}/bin/mktemp -p /tmp -d nova-iso.XXXX)" + mkdir -p "$TMPDIR/boot/syslinux" + trap "rm -rf $TMPDIR" err exit + + ${nova-image.program} $@ + mv image.elf "$TMPDIR/boot" + + pushd "$TMPDIR" + + # build ISO image + cp ${packages.NOVA}/hypervisor* boot/hypervisor + cp ${./isolinux.cfg} boot/syslinux/isolinux.cfg + cp \ + $SYSLINUX/isolinux.bin \ + $SYSLINUX/ldlinux.c32 \ + $SYSLINUX/libcom32.c32 \ + $SYSLINUX/mboot.c32 \ + boot/syslinux + chmod +w boot/syslinux/isolinux.bin + + ISO_FILE="''${DIRSTACK[1]}/nova.iso" + + ${cdrkit}/bin/mkisofs -o "$ISO_FILE" \ + -b syslinux/isolinux.bin -c syslinux/boot.cat \ + -no-emul-boot -boot-load-size 4 -boot-info-table \ + -iso-level 2 \ + boot + + popd + + # build test script + QEMU_SCRIPT=boot-qemu.sh + cat > "$QEMU_SCRIPT" << EOF + #!/bin/sh + qemu-system-x86_64 -cdrom nova.iso -machine q35 -serial mon:stdio \$@ + EOF + + chmod +x "$QEMU_SCRIPT" + '') diff --git a/apps/nova-iso/isolinux.cfg b/apps/nova-iso/isolinux.cfg new file mode 100644 index 0000000..93cdac1 --- /dev/null +++ b/apps/nova-iso/isolinux.cfg @@ -0,0 +1,5 @@ +SERIAL +DEFAULT 0 +LABEL 0 + KERNEL mboot.c32 + APPEND /hypervisor iommu novpid serial --- /image.elf diff --git a/apps/nova-modules.as.dhall b/apps/nova-modules.as.dhall new file mode 100644 index 0000000..25fe728 --- /dev/null +++ b/apps/nova-modules.as.dhall @@ -0,0 +1,117 @@ +let Genode = env:DHALL_GENODE + +let Prelude = Genode.Prelude + +let Configuration = + { arch : < x86_32 | x86_64 > + , config : Genode.Init.Type + , rom : Prelude.Map.Type Text Text + } + : Type + +in λ ( boot + : Configuration + ) + → let NaturalIndex = + { index : Natural, value : Text } + + let TextIndex = { index : Text, value : Text } + + let moduleKeys = + let keys = Prelude.Map.keys Text Text boot.rom + + in [ "config" ] # keys + + let moduleValues = + let values = Prelude.Map.values Text Text boot.rom + + let incbin = + Prelude.List.map + Text + Text + (λ(path : Text) → ".incbin ${Text/show path}") + values + + in [ ".ascii ${Text/show (Genode.Init.render boot.config)}" ] + # incbin + + let map = + λ(list : List Text) + → λ(f : TextIndex → Text) + → let indexedNatural = Prelude.List.indexed Text list + + let indexed = + Prelude.List.map + NaturalIndex + TextIndex + ( λ(x : NaturalIndex) + → { index = Prelude.Natural.show (x.index + 1) + , value = x.value + } + ) + indexedNatural + + let texts = Prelude.List.map TextIndex Text f indexed + + in Prelude.Text.concatSep "\n" texts + + let mapNames = map moduleKeys + + let mapValues = map moduleValues + + let addressType = merge { x86_32 = ".long", x86_64 = ".quad" } boot.arch + + in '' + .set MIN_PAGE_SIZE_LOG2, 12 + .set DATA_ACCESS_ALIGNM_LOG2, 3 + .section .data + .p2align DATA_ACCESS_ALIGNM_LOG2 + .global _boot_modules_headers_begin + _boot_modules_headers_begin: + + '' + ++ mapNames + ( λ ( m + : TextIndex + ) + → '' + ${addressType} _boot_module_${m.index}_name + ${addressType} _boot_module_${m.index}_begin + ${addressType} _boot_module_${m.index}_end - _boot_module_${m.index}_begin + '' + ) + ++ '' + .global _boot_modules_headers_end + _boot_modules_headers_end: + + '' + ++ mapNames + ( λ(m : TextIndex) + → '' + .p2align DATA_ACCESS_ALIGNM_LOG2 + _boot_module_${m.index}_name: + .string "${m.value}" + .byte 0 + '' + ) + ++ '' + .section .data.boot_modules_binaries + + .global _boot_modules_binaries_begin + _boot_modules_binaries_begin: + + '' + ++ mapValues + ( λ(m : TextIndex) + → '' + .p2align MIN_PAGE_SIZE_LOG2 + _boot_module_${m.index}_begin: + ${m.value} + _boot_module_${m.index}_end: + '' + ) + ++ '' + .p2align MIN_PAGE_SIZE_LOG2 + .global _boot_modules_binaries_end + _boot_modules_binaries_end: + '' diff --git a/flake.lock b/flake.lock index 637b3ad..e912aac 100644 --- a/flake.lock +++ b/flake.lock @@ -19,38 +19,6 @@ "originalUrl": "git+https://github.com/dhall-lang/dhall-haskell?ref=flake", "url": "git+https://github.com/dhall-lang/dhall-haskell?ref=flake&rev=aea28adf3d10ff1982aa4ddd176d1476251b932f" }, - "genode": { - "inputs": { - "dhall-haskell": { - "inputs": { - "nixpkgs": { - "inputs": {}, - "narHash": "sha256-wJg4DA700SoQbEz61448sR6BgxRa1R92K3vvCV1g+HY=", - "originalUrl": "git+https://github.com/nixos/nixpkgs.git?ref=18.09-beta&rev=1d4de0d552ae9aa66a5b8dee5fb0650a4372d148", - "url": "git+https://github.com/nixos/nixpkgs.git?ref=18.09-beta&rev=1d4de0d552ae9aa66a5b8dee5fb0650a4372d148" - }, - "nixpkgsStaticLinux": { - "inputs": {}, - "narHash": "sha256-famU3pJZ4vkElV9qc71HmyRVSvcrAhfMZ0UJKpmmKP8=", - "originalUrl": "git+https://github.com/nh2/nixpkgs.git?ref=static-haskell-nix-stack-dhall-working", - "url": "git+https://github.com/nh2/nixpkgs.git?ref=static-haskell-nix-stack-dhall-working&rev=925aac04f4ca58aceb83beef18cb7dae0715421b" - } - }, - "narHash": "sha256-KJl9ZLcMcEsLSPcwcWoc0Ac74/6HKC9LkVMeLwhyhlg=", - "originalUrl": "git+https://github.com/dhall-lang/dhall-haskell?ref=flake", - "url": "git+https://github.com/dhall-lang/dhall-haskell?ref=flake&rev=aea28adf3d10ff1982aa4ddd176d1476251b932f" - }, - "nixpkgs": { - "inputs": {}, - "narHash": "sha256-EqxCk6ORqq4fkewWttpvks0VycBec9X9spAZ+Pq/CEI=", - "originalUrl": "github:ehmry/nixpkgs", - "url": "github:ehmry/nixpkgs/cf50f3b8bdc28832249afab6bca68acad832e011" - } - }, - "narHash": "sha256-nQ42ujMS0QcOk0xCGzdsjZNQS2z3RuxthIRE8na5YL0=", - "originalUrl": "git+https://gitea.c3d2.de/ehmry/genode.git", - "url": "git+https://gitea.c3d2.de/ehmry/genode.git?ref=master&rev=8c8606b375fb913864b0e51892da51eccf97df5f" - }, "genode-depot": { "inputs": { "nixpkgs": { diff --git a/flake.nix b/flake.nix index 9240684..0e162de 100644 --- a/flake.nix +++ b/flake.nix @@ -7,11 +7,10 @@ dhall-haskell.uri = "git+https://github.com/dhall-lang/dhall-haskell?ref=flake"; genode-depot.uri = "git+https://gitea.c3d2.de/ehmry/genode-depot.git"; - genode.uri = "git+https://gitea.c3d2.de/ehmry/genode.git"; nixpkgs.uri = "github:ehmry/nixpkgs"; }; - outputs = { self, dhall-haskell, genode-depot, genode, nixpkgs }: + outputs = { self, dhall-haskell, genode-depot, nixpkgs }: let mkOutput = { system, localSystem, crossSystem }: let thisSystem = builtins.getAttr system; @@ -20,17 +19,22 @@ packages = import ./packages { inherit system nixpkgs; depot = thisSystem genode-depot.packages; - genode = thisSystem genode.packages; dhallApps = dhall-haskell.apps.${localSystem}; }; legacyPackages = thisSystem nixpkgs.legacyPackages; # pass thru Nixpkgs - defaultPackage = packages.base-linux; + defaultPackage = packages.genode.base-linux; devShell = packages.stdenv; + apps = import ./apps { + nixpkgs = legacyPackages; + dhallApps = dhall-haskell.apps.${localSystem}; + inherit packages; + }; + lib = (nixpkgs.lib) // (import ./lib { inherit system localSystem crossSystem; inherit nixpkgs dhall-haskell genode-depot; diff --git a/lib/default.nix b/lib/default.nix index 68afd91..ae76c01 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -46,9 +46,9 @@ in { let inherit (hostPkgs) cdrkit syslinux; - coreNovaObj = "${testPkgs.base-nova}/lib/core-nova.o"; + coreNovaObj = "${testPkgs.genode.base-nova}/lib/core-nova.o"; - rom' = (with testPkgs; { + rom' = (with testPkgs.genode; { init = "${os}/bin/init"; "ld.lib.so" = "${depot.base-nova}/lib/ld.lib.so"; timer = "${base-nova}/bin/nova_timer_drv"; diff --git a/nixos/default.nix b/nixos/default.nix index 7245d90..10924e1 100644 --- a/nixos/default.nix +++ b/nixos/default.nix @@ -12,13 +12,6 @@ description = "Name of the Genode subsystem."; }; - depot = mkOption { - type = with types; attrsOf package; - description = '' - Attribute set of Genode depot binaries. - ''; - }; - pkgs = mkOption { type = with types; attrsOf package; description = '' @@ -38,7 +31,7 @@ rom = mkOption { type = with types; attrs; example = literalExample { - nic_drv = "${depot.ipxe_nic_drv}/bin/ipxe_nic_drv"; + nic_drv = "${genode-depot.ipxe_nic_drv}/bin/ipxe_nic_drv"; }; }; }; @@ -66,11 +59,11 @@ wantedBy = [ "multi-user.target" ]; preStart = let - rom' = with cfg.pkgs; + rom' = with cfg.pkgs.genode; { core = "${base-linux}/bin/core-linux"; init = "${os}/bin/init"; - "ld.lib.so" = "${cfg.depot.base-linux}/lib/ld.lib.so"; + "ld.lib.so" = "${base-linux}/bin/ld-linux.lib.so"; timer = "${base-linux}/bin/linux_timer_drv"; config = builtins.toFile "${name}.config.xml" cfg.config; } // cfg.rom; @@ -81,7 +74,7 @@ DynamicUser = true; RuntimeDirectory = "genode/" + name; WorkingDirectory = "/run/genode/" + name; - ExecStart = "${cfg.pkgs.base-linux}/bin/core-linux"; + ExecStart = "${cfg.pkgs.genode.base-linux}/bin/core-linux"; }; }; in lib.mapAttrs toService config.genode; diff --git a/nixos/test.nix b/nixos/test.nix index f986099..f0782fd 100644 --- a/nixos/test.nix +++ b/nixos/test.nix @@ -17,7 +17,7 @@ import "${nixpkgs}/nixos/tests/make-test.nix" ( in { imports = [ "${genodepkgs}/nixos" ]; genode = { - signal-test = { + signal-test = rec { config = '' @@ -40,11 +40,10 @@ import "${nixpkgs}/nixos/tests/make-test.nix" ( ''; - depot = flakePackages depot; pkgs = flakePackages genodepkgs; rom = { "test-signal" = - "${config.genode.signal-test.pkgs.os}/bin/test-signal"; + "${pkgs.genode.os}/bin/test-signal"; }; }; }; diff --git a/packages/NOVA/default.nix b/packages/NOVA/default.nix new file mode 100644 index 0000000..bbed279 --- /dev/null +++ b/packages/NOVA/default.nix @@ -0,0 +1,46 @@ +# SPDX-FileCopyrightText: Emery Hemingway +# +# SPDX-License-Identifier: LicenseRef-Hippocratic-1.1 + +{ stdenv, buildPackages, fetchFromGitHub }: + +let + ARCH = if stdenv.isx86_32 then + "x86_32" + else if stdenv.isx86_64 then + "x86_64" + else + null; +in if ARCH == null then + null +else + + buildPackages.stdenv.mkDerivation rec { + # Borrow the build host compiler, + pname = "NOVA"; + version = "r10"; + inherit ARCH; + + src = fetchFromGitHub { + owner = "alex-ab"; + repo = "NOVA"; + rev = "68c2fb1671e75d811a4787e35b0d0c6cc85815c0"; + sha256 = "06zxz8hvzqgp8vrh6kv65j0z1m3xfm2ac8ppkv6ql0rivm1rv07s"; + }; + + enableParallelBuilding = true; + + makeFlags = [ "--directory build" ]; + + preInstall = "export INS_DIR=$out"; + + meta = with stdenv.lib; + src.meta // { + description = + "The NOVA OS Virtualization Architecture is a project aimed at constructing a secure virtualization environment with a small trusted computing base."; + homepage = "http://hypervisor.org/"; + license = licenses.gpl2; + maintainers = [ maintainers.ehmry ]; + }; + + } diff --git a/packages/default.nix b/packages/default.nix index 9f591d3..d2e6bee 100644 --- a/packages/default.nix +++ b/packages/default.nix @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: LicenseRef-Hippocratic-1.1 -{ system, nixpkgs, depot, genode, dhallApps }: +{ system, nixpkgs, depot, dhallApps }: let legacyPackages = builtins.getAttr system nixpkgs.legacyPackages; @@ -11,54 +11,57 @@ let dhallPackages = legacyPackages.dhallPackages // (callPackage ./dhall { }); - genode' = with builtins; - let - - mkDhallManifest = drv: - legacyPackages.runCommand "${drv.name}.dhall" { - inherit drv; - dhall = dhallApps.dhall.program; - } '' - echo '{' >> manifest.tmp - if [ -d $drv/bin ]; then - echo ', bin = {' >> manifest.tmp - find $drv/bin/ -type f -printf '%f "%p"\n' \ - | awk '{print ", "gensub(/\..*/, "", 1, $1)" = { mapKey = \""$1"\", mapValue = "$2" }" }'>> manifest.tmp - echo '}' >> manifest.tmp - fi - if [ -d $drv/lib ]; then - echo ', lib = {' >> manifest.tmp - find $drv/lib/ -type f -name '*.lib.so' -printf '%f "%p"\n' \ - | awk '{print ", "gensub(/\..*/, "", 1, $1)" = { mapKey = \""$1"\", mapValue = "$2" }" }'>> manifest.tmp - echo '}' >> manifest.tmp - fi - if [ -d $drv/tar ]; then - echo ', tar = {' >> manifest.tmp - find $drv/tar/ -type f -name '*.tar' -printf '%f "%p"\n' \ - | awk '{print ""gensub(/\..*/, "", 1, $1)" = { mapKey = \""$1"\", mapValue = "$2" }" }'>> manifest.tmp - echo '}' >> manifest.tmp - fi - echo '}' >> manifest.tmp - $dhall < manifest.tmp > $out - ''; - genodeRepoNames = attrNames genode; - f = name: - let drv = getAttr name genode; - in { - inherit name; - value = drv // { manifest = mkDhallManifest drv; }; - }; - list = map f genodeRepoNames; - attrs = listToAttrs list; - in attrs; + mkDhallManifest = drv: + legacyPackages.runCommand "${drv.name}.dhall" { + inherit drv; + dhall = dhallApps.dhall.program; + } '' + echo '{' >> manifest.tmp + if [ -d $drv/bin ]; then + echo ', bin = {' >> manifest.tmp + find $drv/bin/ -type f -printf '%f "%p"\n' \ + | awk '{print ", "gensub(/\..*/, "", 1, $1)" = { mapKey = \""$1"\", mapValue = "$2" }" }'>> manifest.tmp + echo '}' >> manifest.tmp + fi + if [ -d $drv/lib ]; then + echo ', lib = {' >> manifest.tmp + find $drv/lib/ -type f -name '*.lib.so' -printf '%f "%p"\n' \ + | awk '{print ", "gensub(/\..*/, "", 1, $1)" = { mapKey = \""$1"\", mapValue = "$2" }" }'>> manifest.tmp + echo '}' >> manifest.tmp + fi + if [ -d $drv/tar ]; then + echo ', tar = {' >> manifest.tmp + find $drv/tar/ -type f -name '*.tar' -printf '%f "%p"\n' \ + | awk '{print ""gensub(/\..*/, "", 1, $1)" = { mapKey = \""$1"\", mapValue = "$2" }" }'>> manifest.tmp + echo '}' >> manifest.tmp + fi + echo '}' >> manifest.tmp + $dhall < manifest.tmp > $out + ''; in rec { + inherit (legacyPackages) stdenv; + bender = legacyPackages.buildPackages.callPackage ./bender { }; + dhallGenode = dhallPackages.genode; + dhallPrelude = dhallPackages.prelude; + + genode = import ./genode { + nixpkgs = legacyPackages; + inherit mkDhallManifest; + }; + + NOVA = legacyPackages.callPackage ./NOVA { }; + libc = callPackage ./libc { inherit depot; }; + nic_bus = callPackage ./nic_bus { inherit (genode) base os; }; + solo5 = callPackage ./solo5 { inherit (genode) base os; }; + stdcxx = callPackage ./stdcxx { }; -} // genode' + +} diff --git a/packages/genode/default.nix b/packages/genode/default.nix new file mode 100644 index 0000000..1e8f698 --- /dev/null +++ b/packages/genode/default.nix @@ -0,0 +1,275 @@ +# SPDX-License-Identifier: CC0-1.0 + +{ nixpkgs, mkDhallManifest }: + +let + + inherit (nixpkgs) buildPackages llvmPackages; + + sourceForgeToolchain = nixpkgs.buildPackages.callPackage ./toolchain.nix { }; + + stdenvLlvm = let inherit (nixpkgs) stdenv; + in assert stdenv.cc.isClang; stdenv; + + stdenvGcc = let + env = nixpkgs.stdenvAdapters.overrideCC nixpkgs.stdenv sourceForgeToolchain; + in assert env.cc.isGNU; env; + + inherit (stdenvLlvm) lib targetPlatform; + specs = with targetPlatform; + [ ] + + ++ lib.optional is32bit "32bit" + + ++ lib.optional is64bit "64bit" + + ++ lib.optional isAarch32 "arm" + + ++ lib.optional isAarch64 "arm_64" + + ++ lib.optional isRiscV "riscv" + + ++ lib.optional isx86 "x86" + + ++ lib.optional isx86_32 "x86_32" + + ++ lib.optional isx86_64 "x86_64"; + + toTupConfig = env: attrs: + let + tupArch = with env.targetPlatform; + + if isAarch32 then + "arm" + else + + if isAarch64 then + "arm64" + else + + if isx86_32 then + "i386" + else + + if isx86_64 then + "x86_64" + else + + abort "unhandled targetPlatform"; + + attrs' = with env; { TUP_ARCH = tupArch; } // attrs; + + in with builtins; + env.mkDerivation { + name = "tup.config"; + nativeBuildInputs = with nixpkgs.buildPackages; [ + binutils + pkgconfig + which + ]; + text = let + op = config: name: '' + ${config}CONFIG_${name}=${getAttr name attrs} + ''; + in foldl' op "" (attrNames attrs); + passAsFile = [ "text" ]; + preferLocalBuild = true; + buildCommand = let + subst = let + vars = [ "AR" "NM" ]; + f = other: var: + other + '' + echo CONFIG_${var}=`which ''$${var}` >> $out + ''; + in foldl' f "" vars; + utils = let + vars = [ "pkg-config" "objcopy" ]; + f = other: var: + other + '' + echo CONFIG_${var}=`which ${var}` >> $out + ''; + in foldl' f "" vars; + in '' + cp $textPath $out + ${subst} + ${utils} + ''; + }; + + tupConfigGcc = let + f = env: + let prefix = bin: env.cc.targetPrefix + bin; + in { + CC = prefix "gcc"; + CXX = prefix "g++"; + LD = prefix "ld"; + OBJCOPY = prefix "objcopy"; + RANLIB = prefix "ranlib"; + READELF = prefix "readelf"; + STRIP = prefix "strip"; + PKGCONFIG = "${nixpkgs.buildPackages.pkgconfig}/bin/pkg-config"; + + IS_GCC = ""; + LINUX_HEADERS = buildPackages.glibc.dev; + }; + in toTupConfig stdenvGcc (f stdenvGcc); + + tupConfigLlvm = let + f = env: + let prefix = bin: "${env.cc}/bin/${env.cc.targetPrefix}${bin}"; + in { + CC = prefix "cc"; + CXX = prefix "c++"; + LD = prefix "ld"; + OBJCOPY = prefix "objcopy"; + OBJDUMP = prefix "objdump"; + RANLIB = prefix "ranlib"; + READELF = prefix "readelf"; + STRIP = prefix "strip"; + PKGCONFIG = "${nixpkgs.buildPackages.pkgconfig}/bin/pkg-config"; + + IS_LLVM = ""; + LIBCXXABI = llvmPackages.libcxxabi; + LIBCXX = llvmPackages.libcxx; + LIBUNWIND_BAREMETAL = + llvmPackages.libunwind.override { isBaremetal = true; }; + LIBUNWIND = llvmPackages.libunwind; + LINUX_HEADERS = buildPackages.glibc.dev; + }; + in toTupConfig stdenvLlvm (f stdenvLlvm); + + src = nixpkgs.fetchgit { + url = "https://git.sr.ht/~ehmry/genode"; + rev = "42f93ce3da14663575f7f24d299315688facd545"; + sha256 = "1rjjmq4qx9vsm0cbnr9h5n2gr8zbw1dpnhqjlyfvs44andzps5qd"; + }; + + buildRepo = { env, repo, repoInputs }: + env.mkDerivation { + pname = repo; + version = "19.11"; + inherit repo specs src; + + nativeBuildInputs = repoInputs; + # This is wrong, why does pkg-config not collect buildInputs? + + propagatedNativeBuildInputs = repoInputs; + + depsBuildBuild = with buildPackages; [ llvm pkgconfig tup ]; + + tupConfig = if env.cc.isGNU then + tupConfigGcc + else if env.cc.isClang then + tupConfigLlvm + else + throw "no Tup config for this stdenv"; + + configurePhase = '' + # Configure Tup + set -v + install -m666 $tupConfig tup.config + echo CONFIG_NIX_OUTPUTS_OUT=$out >> tup.config + echo CONFIG_NIX_OUTPUTS_DEV=$out >> tup.config + + # Disable other repos + for R in repos/*; do + [ "$R" != "repos/$repo" ] && find $R -name Tupfile -delete + done + + # Scan repository and generate script + tup init + tup generate buildPhase.sh + + # Redirect artifacts to Nix store + mkdir -p $out/lib $out/include + ln -s $out out + ln -s $out dev + ''; + + buildPhase = '' + test -d repos/$repo/src/ld && cp -rv repos/$repo/src/ld $out/ + pushd . + set -v + source buildPhase.sh + set +v + popd + ''; + + installPhase = '' + # Populate the "dev" headers + if [ -d "repos/$repo/include" ]; then + for DIR in repos/$repo/include; do + for SPEC in $specs; do + if [ -d $DIR/spec/$SPEC ]; then + cp -r $DIR/spec/$SPEC/* $out/include + rm -r $DIR/spec/$SPEC + fi + done + rm -rf $DIR/spec + cp -r $DIR $out/ + done + fi + + touch $out/.genode + for pc in $out/lib/pkgconfig/*.pc; do + sed -e "s|^Libs: |Libs: -L$out/lib |" -i $pc + done + ''; + + meta = with env.lib; { + description = + "The Genode operation system framework (${repo} repository)."; + homepage = "https://genode.org/"; + license = licenses.agpl3; + maintainers = [ maintainers.ehmry ]; + }; + + }; + + buildRepo' = { ... }@args: + let drv = buildRepo ({ env = stdenvGcc; } // args); + in { manifest = mkDhallManifest drv; } // drv; + + drvs = rec { + + base = buildRepo' { + repo = "base"; + repoInputs = [ ]; + }; + + base-linux = buildRepo' { + repo = "base-linux"; + repoInputs = [ base ]; + }; + + base-nova = buildRepo' { + repo = "base-nova"; + repoInputs = [ base ]; + }; + + os = buildRepo' { + repo = "os"; + repoInputs = [ base ]; + }; + + gems = buildRepo' { + repo = "gems"; + repoInputs = [ base os ]; + }; + + inherit stdenvGcc stdenvLlvm tupConfigGcc tupConfigLlvm; + + }; + + manifest = with builtins; + let + repoDrvs = filter (drv: typeOf drv == "set" && hasAttr "repo" drv && hasAttr "manifest" drv) + (attrValues drvs); + records = map (drv: "${drv.repo}=${drv.manifest}") repoDrvs; + text = "{" + builtins.concatStringsSep "," records + "}"; + in nixpkgs.writeTextFile { + name = "genode.manifest.dhall"; + inherit text; + }; + +in drvs // manifest diff --git a/packages/genode/toolchain.nix b/packages/genode/toolchain.nix new file mode 100644 index 0000000..ed5f5cc --- /dev/null +++ b/packages/genode/toolchain.nix @@ -0,0 +1,75 @@ +# Shameless plagiarism of Blitz's toolchain expression: +# https://github.com/blitz/genode-nix + +# +# WARNING: these binaries are from sourceforge and +# have not been publicly verified by Genode Labs. +# + +{ stdenv, fetchurl, ncurses5, expat, makeWrapper, wrapCC }: + +let + cc = stdenv.mkDerivation rec { + pname = "genode-toolchain"; + version = "19.05"; + + src = fetchurl ({ + x86_64-linux = { + url = + "mirror://sourceforge/project/genode/${pname}/${version}/${pname}-${version}-x86_64.tar.xz"; + sha256 = "036czy21zk7fvz1y1p67q3d5hgg8rb8grwabgrvzgdsqcv2ls6l9"; + }; + }.${stdenv.buildPlatform.system} or (throw + "cannot install Genode toolchain on this platform")); + + preferLocalBuild = true; + + nativeBuildInputs = [ makeWrapper ]; + + phases = [ "unpackPhase" "fixupPhase" ]; + + dontStrip = true; + dontPatchELF = true; + + libPath = stdenv.lib.makeLibraryPath [ "$out" stdenv.cc.cc expat ncurses5 ]; + + unpackPhase = '' + mkdir $out + tar xf $src --strip-components=5 -C $out + ''; + + preFixup = '' + for p in $(find "$out" -type f -executable); do + if isELF "$p"; then + echo "Patchelfing $p" + patchelf "$p" + patchelf --set-interpreter $(cat ${stdenv.cc}/nix-support/dynamic-linker) "$p" || true + patchelf --set-rpath ${libPath} "$p" || true + fi + done + pushd $out/bin + for BIN in $out/bin/genode-aarch64-*; do + makeWrapper ''${BIN} aarch64-unknown-genode-''${BIN#$out/bin/genode-aarch64-} + done + for BIN in $out/bin/genode-arm-*; do + makeWrapper ''${BIN} arm-unknown-genode-''${BIN#$out/bin/genode-arm-} + done + for BIN in $out/bin/genode-riscv-*; do + makeWrapper ''${BIN} riscv-unknown-genode-''${BIN#$out/bin/genode-riscv-} + done + for BIN in $out/bin/genode-x86-*; do + makeWrapper ''${BIN} i686-unknown-genode-''${BIN#$out/bin/genode-x86-} + makeWrapper ''${BIN} x86_64-unknown-genode-''${BIN#$out/bin/genode-x86-} + done + popd + ''; + } // { + isGNU = true; + targetPrefix = "genode-x86-"; + }; + + wrapped = wrapCC cc; + + wrapped' = wrapped.overrideAttrs (attrs: { inherit (cc) targetPrefix; }); + +in wrapped' diff --git a/tests/driver-linux.nix b/tests/driver-linux.nix index d0f7f67..ec41352 100644 --- a/tests/driver-linux.nix +++ b/tests/driver-linux.nix @@ -39,7 +39,7 @@ let mkTest = { name ? "unamed", testScript, testConfig, bootModules, ... }@t: with testPkgs; let - bootModules' = { + bootModules' = with testPkgs.genode; { inherit testConfig; config = ./driver-config.xml; core = "${base-linux}/bin/core-linux"; diff --git a/tests/fs_report.nix b/tests/fs_report.nix index d1a31ba..04ae4a5 100644 --- a/tests/fs_report.nix +++ b/tests/fs_report.nix @@ -8,11 +8,11 @@ testEnv.mkTest { testConfig = ./fs_report.xml; bootModules = { - fs_report = "${os}/bin/fs_report"; - fs_rom = "${os}/bin/fs_rom"; - ram_fs = "${os}/bin/ram_fs"; - test-fs_report = "${os}/bin/test-fs_report"; - "vfs.lib.so" = "${os}/lib/vfs.lib.so"; + fs_report = "${genode.os}/bin/fs_report"; + fs_rom = "${genode.os}/bin/fs_rom"; + ram_fs = "${genode.os}/bin/ram_fs"; + test-fs_report = "${genode.os}/bin/test-fs_report"; + "vfs.lib.so" = "${genode.os}/lib/vfs.lib.so"; }; testScript = '' diff --git a/tests/pci.nix b/tests/pci.nix index 19afc6e..05af77b 100644 --- a/tests/pci.nix +++ b/tests/pci.nix @@ -8,10 +8,10 @@ testEnv.mkTest { testConfig = testEnv.lib.renderDhallInit ./pci.dhall "{=}"; bootModules = { - acpi_drv = "${os}/bin/acpi_drv"; - platform_drv = "${os}/bin/platform_drv"; - report_rom = "${os}/bin/report_rom"; - test-pci = "${os}/bin/test-pci"; + acpi_drv = "${genode.os}/bin/acpi_drv"; + platform_drv = "${genode.os}/bin/platform_drv"; + report_rom = "${genode.os}/bin/report_rom"; + test-pci = "${genode.os}/bin/test-pci"; }; testScript = '' diff --git a/tests/signal.nix b/tests/signal.nix index 12fa1dc..6b36faf 100644 --- a/tests/signal.nix +++ b/tests/signal.nix @@ -7,7 +7,7 @@ testEnv.mkTest rec { testConfig = testEnv.lib.renderDhallInit ./signal.dhall "{=}"; - bootModules.test-signal = "${os}/bin/test-signal"; + bootModules.test-signal = "${genode.os}/bin/test-signal"; testScript = "run_genode_until {--- Signalling test finished ---} 120"; } diff --git a/tests/solo5/default.nix b/tests/solo5/default.nix index bd50484..85f3eea 100644 --- a/tests/solo5/default.nix +++ b/tests/solo5/default.nix @@ -28,7 +28,7 @@ let name = "blk"; bootModules = { test = "${solo5.tests}/bin/solo5-test_blk"; - ram_block = "${os}/bin/ram_block"; + ram_block = "${genode.os}/bin/ram_block"; }; testConfig = testEnv.lib.renderDhallInit ./blk.dhall "{=}"; } @@ -69,7 +69,7 @@ let name = "mft_maxdevices"; bootModules = { test = "${solo5.tests}/bin/solo5-test_mft_maxdevices"; - rom_block = "${os}/bin/rom_block"; + rom_block = "${genode.os}/bin/rom_block"; }; testConfig = testEnv.lib.renderDhallInit ./mft_maxdevices.dhall "{=}"; } @@ -79,9 +79,9 @@ let name = "net"; bootModules = { test = "${solo5.tests}/bin/solo5-test_net"; - nic_bridge = "${os}/bin/nic_bridge"; - nic_loopback = "${os}/bin/nic_loopback"; - ping = "${os}/bin/ping"; + nic_bridge = "${genode.os}/bin/nic_bridge"; + nic_loopback = "${genode.os}/bin/nic_loopback"; + ping = "${genode.os}/bin/ping"; }; testConfig = testEnv.lib.renderDhallInit ./net.dhall "{=}"; testScript = '' @@ -93,10 +93,10 @@ let name = "net_2if"; bootModules = { test = "${solo5.tests}/bin/solo5-test_net_2if"; - sequence = "${os}/bin/sequence"; - nic_bridge = "${os}/bin/nic_bridge"; - nic_loopback = "${os}/bin/nic_loopback"; - ping = "${os}/bin/ping"; + sequence = "${genode.os}/bin/sequence"; + nic_bridge = "${genode.os}/bin/nic_bridge"; + nic_loopback = "${genode.os}/bin/nic_loopback"; + ping = "${genode.os}/bin/ping"; }; testConfig = testEnv.lib.renderDhallInit ./net_2if.dhall "{=}"; testScript = '' @@ -151,7 +151,7 @@ let name = "time"; bootModules = { test = "${solo5.tests}/bin/solo5-test_time"; - rtc_drv = "${os}/bin/rtc_drv"; + rtc_drv = "${genode.os}/bin/rtc_drv"; }; testConfig = testEnv.lib.renderDhallInit ./time.dhall "{=}"; }