From 4235b5ab9b39eae783f02ccc739e8a9a9f1c1882 Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Sat, 11 Jan 2020 15:12:07 +0100 Subject: [PATCH] Nix app for building NOVA ISOs --- apps/nova-iso/default.nix | 69 +++++++++++++++++++ apps/nova-iso/isolinux.cfg | 5 ++ apps/nova-iso/modules.as.dhall | 119 +++++++++++++++++++++++++++++++++ default.nix | 20 +++++- flake.lock | 19 ++++++ flake.nix | 10 ++- 6 files changed, 237 insertions(+), 5 deletions(-) create mode 100644 apps/nova-iso/default.nix create mode 100644 apps/nova-iso/isolinux.cfg create mode 100644 apps/nova-iso/modules.as.dhall diff --git a/apps/nova-iso/default.nix b/apps/nova-iso/default.nix new file mode 100644 index 000000000..0e0d712d7 --- /dev/null +++ b/apps/nova-iso/default.nix @@ -0,0 +1,69 @@ +{ stdenv, nixpkgs, dhallApps, NOVA, base-nova }: + +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 + + CORE_NOVA="${base-nova}/lib/core-nova.o" + + ${dhallApps.dhall.program} text <<< "(${ + ./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${../../repos/base/src/ld/genode.ld} \ + -T${../../repos/base-nova/src/core/core-bss.ld} \ + -z max-page-size=0x1000 \ + -Ttext=0x100000 -gc-sections \ + "$CORE_NOVA" "$TMPDIR/boot_modules.o" \ + -o "$TMPDIR/boot/image.elf" + + pushd "$TMPDIR" + + strip boot/image.elf + + # build ISO image + cp ${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" + + 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 000000000..93cdac198 --- /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-iso/modules.as.dhall b/apps/nova-iso/modules.as.dhall new file mode 100644 index 000000000..5a0ecdfae --- /dev/null +++ b/apps/nova-iso/modules.as.dhall @@ -0,0 +1,119 @@ +let Genode = + env:DHALL_GENODE + ? https://git.sr.ht/~ehmry/dhall-genode/blob/v11.0.0/package.dhall sha256:4336da47b739fe6b9e117436404ca56af0cfec15805abb0baf6f5ba366c7e5ce + +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/default.nix b/default.nix index b51b350e2..690c5b9c2 100644 --- a/default.nix +++ b/default.nix @@ -4,7 +4,7 @@ let ref = "genode"; }); in { localSystem ? "x86_64-linux", crossSystem ? "x86_64-genode" -, nixpkgs ? pinnedNixpkgs, self ? { } }: +, nixpkgs ? pinnedNixpkgs, self ? { }, dhall-haskell ? null }: let nixpkgs' = if builtins.isAttrs nixpkgs then @@ -271,10 +271,26 @@ in rec { inherit stdenvGcc stdenvLlvm tupConfigGcc tupConfigLlvm; + nova-iso = import ./apps/nova-iso { + stdenv = stdenvLlvm; + inherit nixpkgs NOVA base-nova; + dhallApps = dhall-haskell.apps.${localSystem}; + }; }; + apps = { + core-linux = { + type = "app"; + program = "${packages.base-linux}/bin/core-linux"; + }; + nova-iso = { + type = "app"; + program = "${packages.nova-iso}/bin/nova-iso"; + }; + }; + + defaultApp = apps.core-linux; defaultPackage = packages.base-linux; devShell = packages.base; checks = packages; - } diff --git a/flake.lock b/flake.lock index 96f5d1304..044331017 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,24 @@ { "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=", diff --git a/flake.nix b/flake.nix index 47fb745c5..7cccd796d 100644 --- a/flake.nix +++ b/flake.nix @@ -3,15 +3,19 @@ description = "Genode system flake"; - inputs.nixpkgs.uri = - "git+https://gitea.c3d2.de/ehmry/nixpkgs.git?ref=genode"; + inputs = { + nixpkgs.uri = "git+https://gitea.c3d2.de/ehmry/nixpkgs.git?ref=genode"; + dhall-haskell.uri = + "git+https://github.com/dhall-lang/dhall-haskell?ref=flake"; + }; - outputs = { self, nixpkgs }: + outputs = { self, nixpkgs, dhall-haskell }: let mkOutput = { system, localSystem, crossSystem }: import ./default.nix { inherit localSystem crossSystem self; nixpkgs = builtins.getAttr system nixpkgs.legacyPackages; + inherit dhall-haskell; }; localSystems = [ "x86_64-linux" ];