# SPDX-License-Identifier: CC0-1.0 { system, localSystem, crossSystem, genodepkgs, nixpkgs, dhall-haskell , genode-depot }: let thisSystem = builtins.getAttr system; hostPkgs = import nixpkgs { system = localSystem; overlays = [ (self: super: { inherit (builtins.getAttr localSystem dhall-haskell.packages) dhall; }) ]; }; testPkgs = thisSystem genodepkgs.packages; depot = thisSystem genode-depot.packages; in { dhallText = name: source: hostPkgs.runCommand name { inherit name source; preferLocalBuild = true; buildInputs = [ hostPkgs.dhall ]; DHALL_PRELUDE = "${testPkgs.dhallPackages.prelude}/package.dhall"; DHALL_GENODE = "${testPkgs.dhallPackages.genode}/package.dhall"; } '' export XDG_CACHE_HOME=$NIX_BUILD_TOP dhall text < $source > $out ''; renderDhallInit = path: args: hostPkgs.runCommand "init.xml" { preferLocalBuild = true; buildInputs = with hostPkgs; [ dhall libxml2 ]; initConfig = path; initArgs = args; DHALL_PRELUDE = "${testPkgs.dhallPrelude}/package.dhall"; DHALL_GENODE = "${testPkgs.dhallGenode}/package.dhall"; } '' export XDG_CACHE_HOME=$NIX_BUILD_TOP dhall text \ <<< 'let Prelude = env:DHALL_GENODE in Prelude.Init.render (env:initConfig env:initArgs)' \ > $out xmllint --noout $out ''; buildNovaIso = { name, rom }: let inherit (hostPkgs) cdrkit syslinux; coreNovaObj = "${testPkgs.genode.base-nova}/lib/core-nova.o"; 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"; }) // rom; addressType = ".quad"; # TODO: 32bit?! map' = with nixpkgs.lib; l: f: concatStrings (imap0 (i: v: (f (toString i) v)) l); mapNames = map' (builtins.attrNames rom'); mapValues = map' (builtins.attrValues rom'); modulesAsm = '' .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 (i: _: '' ${addressType} _boot_module_${i}_name ${addressType} _boot_module_${i}_begin ${addressType} _boot_module_${i}_end - _boot_module_${i}_begin '')) + '' .global _boot_modules_headers_end _boot_modules_headers_end: '' + (mapNames (i: name: '' .p2align DATA_ACCESS_ALIGNM_LOG2 _boot_module_${i}_name: .string "${name}" .byte 0 '')) + '' .section .data.boot_modules_binaries .global _boot_modules_binaries_begin _boot_modules_binaries_begin: '' + (mapValues (i: path: '' .p2align MIN_PAGE_SIZE_LOG2 _boot_module_${i}_begin: .incbin "${path}" _boot_module_${i}_end: '')) + '' .p2align MIN_PAGE_SIZE_LOG2 .global _boot_modules_binaries_end _boot_modules_binaries_end: ''; syslinuxDir = "${syslinux}/share/syslinux"; in hostPkgs.stdenv.mkDerivation { name = name + "-iso"; passthru = rom; passAsFile = [ "modulesAsm" ]; inherit modulesAsm; preferLocalBuild = true; dontUnpack = true; buildInputs = [ testPkgs.stdenv.cc hostPkgs.cdrkit hostPkgs.syslinux ]; buildPhase = '' mkdir -p boot/syslinux # compile the boot modules into one object file $CC -c -x assembler -o boot_modules.o $modulesAsmPath # link final image $LD -nostdlib \ -T${./genode.ld} \ -T${./nova-bss.ld} \ -z max-page-size=0x1000 \ -Ttext=0x100000 -gc-sections \ ${coreNovaObj} boot_modules.o \ -o boot/image.elf strip boot/image.elf # build ISO image cp ${testPkgs.NOVA}/hypervisor* boot/hypervisor cp ${./nova-isolinux.cfg} boot/syslinux/isolinux.cfg cp \ ${syslinuxDir}/isolinux.bin \ ${syslinuxDir}/ldlinux.c32 \ ${syslinuxDir}/libcom32.c32 \ ${syslinuxDir}/mboot.c32 \ boot/syslinux chmod +w boot/syslinux/isolinux.bin mkisofs -o iso \ -b syslinux/isolinux.bin -c syslinux/boot.cat \ -no-emul-boot -boot-load-size 4 -boot-info-table \ -iso-level 2 \ boot isohybrid iso # build test script cat > boot-qemu << EOF #!/bin/sh ${hostPkgs.qemu_test}/bin/qemu-system-x86_64 -cdrom $out/iso -machine q35 \$@ EOF ''; installPhase = '' install -Dm444 iso $out/iso install -Dm555 boot-qemu $out/bin/boot-qemu ''; }; }