diff --git a/flake.nix b/flake.nix index a9116b0..ca0a39b 100644 --- a/flake.nix +++ b/flake.nix @@ -86,11 +86,13 @@ git glibc.dev gnumake + iasl libxml2 qemu tcl which xorriso + yasm ]); runScript = "bash"; extraBuildCommands = let diff --git a/nixos-modules/buildBootDescription.nix b/nixos-modules/buildBootDescription.nix index 4e818dc..2e7707a 100644 --- a/nixos-modules/buildBootDescription.nix +++ b/nixos-modules/buildBootDescription.nix @@ -25,10 +25,12 @@ let f = binary: { name = binary; value = let - f = if lib.hasPrefix "lib" binary && lib.hasSuffix ".so" binary then - drv: toPath "${drv.lib or drv}/lib/${binary}" - else - drv: toPath "${drv}/${binary}"; + 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 "${drv}/${binary}"; in filter pathExists (map f imageInputs); }; in map f binaries; diff --git a/nixos-modules/default.nix b/nixos-modules/default.nix index 5899f5c..6cc5eec 100644 --- a/nixos-modules/default.nix +++ b/nixos-modules/default.nix @@ -1,5 +1,5 @@ -{ self }: +{ self, depot }: { - vbox = import ./vbox.nix { inherit self; }; + vbox = import ./vbox.nix { inherit self depot; }; } diff --git a/nixos-modules/dhall/vbox-host.dhall b/nixos-modules/dhall/vbox-host.dhall index 069e382..4bfa598 100644 --- a/nixos-modules/dhall/vbox-host.dhall +++ b/nixos-modules/dhall/vbox-host.dhall @@ -23,10 +23,13 @@ let Vfs/inline = → λ(body : Text) → XML.element { name = "inline" - , attributes = XML.emptyAttributes + , attributes = toMap { name = name } , content = [ XML.text body ] } +let routeLogRom = + λ(label : Text) → ServiceRoute.parentLabel "ROM" (Some "log") (Some label) + let rootInit = λ ( params : { vdiFilename : Text @@ -39,12 +42,13 @@ let rootInit = '' - + - + + @@ -60,8 +64,15 @@ let rootInit = - - + + + + + + + + + @@ -72,7 +83,8 @@ let rootInit = - + + @@ -163,13 +175,13 @@ let rootInit = - + - + - + @@ -313,9 +325,11 @@ let rootInit = [ XML.text '' - + + - + + '' ] } @@ -329,8 +343,88 @@ let rootInit = Child.flat Child.Attributes::{ , binary = "pointer" + , provides = [ "Report" ] , routes = [ ServiceRoute.child "Nitpicker" "nitpicker" ] } + , nit_fb = + Child.flat + Child.Attributes::{ + , binary = "nit_fb" + , config = Init.Config::{ + , attributes = toMap { xpos = "200", width = "600", height = "600" } + } + , provides = [ "Framebuffer", "Input" ] + , resources = Resources::{ ram = Genode.units.MiB 8 } + , routes = + [ ServiceRoute.childLabel + "Nitpicker" + "nitpicker" + (None Text) + (Some "log") + ] + } + , terminal = + Child.flat + Child.Attributes::{ + , binary = "terminal" + , provides = [ "Terminal" ] + , resources = Resources::{ + , caps = 256 + , ram = Genode.units.MiB 4 + } + , routes = + [ ServiceRoute.child "Framebuffer" "nit_fb" + , ServiceRoute.child "Input" "nit_fb" + ] + , config = Init.Config::{ + , content = + [ Prelude.XML.text + '' + + + + + + + + + '' + ] + } + } + , 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::{ @@ -449,7 +543,8 @@ let rootInit = } , XML.leaf { name = "default-policy" - , attributes = toMap { root = "/" } + , attributes = toMap + { root = "/", writeable = "yes" } } ] } @@ -460,13 +555,33 @@ let rootInit = } , routes = [ ServiceRoute.child "Block" "block_router" ] } + , 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") + ] + } , vbox = Child.flat Child.Attributes::{ , binary = "virtualbox5" , config = Init.Config::{ , attributes = toMap - { vbox_file = "nixos.vbox", vm_name = "nixos" } + { vbox_file = "machine.vbox" + , vm_name = "linux" + , xhci = "yes" + } , content = [ XML.leaf { name = "libc" @@ -487,13 +602,17 @@ let rootInit = , attributes = XML.emptyAttributes } - in [ Vfs/inline "nixos.vbox" vboxConfig + in [ Vfs/inline "machine.vbox" vboxConfig , XML.element { name = "dir" , attributes = toMap { name = "dev" } , content = [ tag "log", tag "rtc" ] } - , tag "fs" + , XML.leaf + { name = "fs" + , attributes = toMap + { writeable = "yes" } + } ] } ] @@ -508,9 +627,28 @@ let rootInit = [ ServiceRoute.parent "VM" , ServiceRoute.child "Nitpicker" "nitpicker" , ServiceRoute.child "File_system" "file_system" + , ServiceRoute.child "Nic" "nic_drv" , ServiceRoute.child "Rtc" "rtc" + , ServiceRoute.childLabel + "Report" + "_report_rom" + (Some "shape") + (Some "shape") + , ServiceRoute.parentLabel + "ROM" + (Some "platform_info") + (Some "platform_info") ] } + , rom_logger = + Child.flat + Child.Attributes::{ + , binary = "rom_logger" + , config = Init.Config::{ + , attributes = toMap { rom = "state" } + } + , reportRoms = [ label "state" ] + } } } diff --git a/nixos-modules/vbox.nix b/nixos-modules/vbox.nix index 5fa50ea..c247c12 100644 --- a/nixos-modules/vbox.nix +++ b/nixos-modules/vbox.nix @@ -1,17 +1,21 @@ -{ self }: +{ self, depot }: let lib' = self.lib.x86_64-linux-x86_64-genode; pkgs' = self.packages.x86_64-linux-x86_64-genode; in { config, lib, pkgs, ... }: let + inherit (pkgs.vmTools) qemu; + buildBootDescription = self.legacyPackages.x86_64-linux.callPackage ./buildBootDescription.nix { lib = lib'; }; + nixosVDI = "${config.system.build.virtualBoxVDI}/nixos.vdi"; + genodeParams = lib'.runDhallCommand "params.dhall" { } '' - vdiUuid=$(${pkgs.virtualbox}/bin/VBoxManage showmediuminfo ${config.system.build.virtualBoxVDI}/nixos.vdi | awk '/^UUID:/ {print $2}') + vdiUuid=$(${pkgs.virtualbox}/bin/VBoxManage showmediuminfo ${nixosVDI} | awk '/^UUID:/ {print $2}') dhall > $out << EOD { vdiFilename = "nixos.vdi" , vdiUuid = "$vdiUuid" @@ -29,19 +33,26 @@ let "ahci_drv" "init" "input_filter" + "ipxe_nic_drv" "libc" "libiconv" + "log_core" + "nit_fb" "nitpicker" "part_block" "platform_drv" "ps2_drv" "report_rom" + "rom_logger" "rtc_drv" "rump" "stdcxx" + "terminal" + "terminal_log" "vbox5" "vesa_drv" "vfs" + "vfs_ttf" ] ++ [ pkgs'.base-nova pkgs'.block_router ]; extraBinaries = [ "ld.lib.so" @@ -55,48 +66,119 @@ let "libstdcxx.so" "libvfs.so" "libvfs_rump.so" + "libvfs_ttf.so" ]; + extraRoms = { + "Inconsolata.ttf" = + "${pkgs.inconsolata}/share/fonts/truetype/inconsolata/Inconsolata-Regular.ttf"; + }; }; firmware = lib'.novaImage "stage0" { } bootDescription; - # add system.build.virtualBoxVDI/nixos.vdi to disk image + grubStandalone = pkgs.runCommand "grub-standalone" { + buildInputs = [ pkgs.grub2_efi ]; + grubModules = [ "multiboot2" "gzio" "normal" "gfxterm" ]; + } '' + cat > grub.cfg << EOF + multiboot2 /bender + module2 /hypervisor.gz hypervisor iommu novpid novga serial logmem + module2 /image.elf.gz image.elf + EOF - genodeDiskImage = with pkgs; - runCommand "genode.disk" { - nativeBuildInputs = [ e2fsprogs gptfdisk lzip vmTools.qemu ]; - } '' - qemu-img create -f raw fs.raw 16M - qemu-img create -f raw zero.raw 1M + gzip -c "${pkgs'.NOVA}/hypervisor-x86_64" > hypervisor.gz + gzip -c "${firmware}" > image.elf.gz - mke2fs fs.raw + mkdir -p $out + grub-mkstandalone -O x86_64-efi -o "$out/bootx64.efi" \ + --install-modules="$grubModules" \ + --modules="$grubModules" \ + "boot/grub/grub.cfg=grub.cfg" \ + "hypervisor.gz=hypervisor.gz" \ + "image.elf.gz=image.elf.gz" \ + ''; - cat zero.raw fs.raw zero.raw > gpt.raw + genodeDiskImage = pkgs.vmTools.runInLinuxVM + (pkgs.runCommand "genode-disk-image" { + preVM = '' + mkdir $out + diskImage=$out/disk.img + bootFlash=$out/bios.bin + ${qemu}/bin/qemu-img create -f qcow2 $diskImage 2G + install -m0644 ${pkgs.OVMF-CSM.fd}/FV/OVMF.fd $bootFlash + ''; + buildInputs = with pkgs; [ e2fsprogs grub2_efi utillinux ]; + QEMU_OPTS = "-pflash $out/bios.bin -nographic"; + } + # Use fixed GUIDs for reproducibility + '' + ${pkgs.gptfdisk}/bin/sgdisk \ + --set-alignment=512 --new=1:0:16M --change-name=1:EFISystem \ + --set-alignment=512 --largest-new=2 --change-name=2:Genode \ + --typecode=1:ef00 \ + --typecode=2:${import ./dhall/partition-type} \ + --attributes=1:set:2 \ + --disk-guid=E7D8E481-623A-4F0F-87E6-A2327CC591C6 \ + --partition-guid=1:B4DC4B9C-8B22-43BB-8D96-7CD4473DABE6 \ + --partition-guid=2:113F1671-8074-4D82-8C25-DC84BA04D2C9 \ + --recompute-chs /dev/vda - sgdisk gpt.raw --new=partnum 1:34:-34 \ - --typecode=1:${import ./dhall/partition-type} \ - --change-name=1:genode + ${pkgs.dosfstools}/bin/mkfs.fat -F16 /dev/vda1 + export MTOOLS_SKIP_CHECK=1 + ${pkgs.mtools}/bin/mlabel -i /dev/vda1 ::boot - mkdir -p $out - lzip -c gpt.raw > "$out/genode-nixos-${config.system.nixos.label}.disk" - ''; + mkdir /boot /genode + + mount /dev/vda1 /boot + install -D ${grubStandalone}/bootx64.efi /boot/efi/boot/bootx64.efi + umount /boot + + mke2fs /dev/vda2 + + mount /dev/vda2 /genode + cp ${nixosVDI} /genode/nixos.vdi + cp "${pkgs'.genodeSources}/tool/boot/bender" /genode/bender + cp "${pkgs'.NOVA}/hypervisor-x86_64" /genode/hypervisor-x86_64 + gzip -c "${firmware}" > /genode/image.elf.gz + umount /genode + ''); in { - system.build.genodeDiskImage = - pkgs.runCommand "nixos-vm" { preferLocalBuild = true; } '' - mkdir -p $out/bin - ln -s ${ - pkgs.writeScript "run-nixos-vm" '' - #! ${pkgs.runtimeShell} - ${pkgs.vmTools.qemu}/bin/qemu-system-x86_64 \ - -machine q35 \ - -cpu phenom \ - -m 512 \ - -serial mon:stdio \ - -kernel "${pkgs'.bender}" \ - -initrd "${pkgs'.NOVA}/hypervisor-x86_64 arg=iommu novpid serial logmem,${firmware}" \ - $@ - '' - } $out/bin/run-genode-vm + system.build = { + genodeGuestScript = pkgs.writeScriptBin "genode-nixos-vm" '' + #! ${pkgs.runtimeShell} + set -e + ${qemu}/bin/qemu-img create -f qcow2 -b \ + ${genodeDiskImage}/disk.img disk.img || exit 1 + install -m0644 ${genodeDiskImage}/bios.bin bios.bin || exit 1 + + ${pkgs.vmTools.qemu}/bin/qemu-system-x86_64 \ + -machine q35 \ + -cpu phenom \ + -m 4096 \ + -serial mon:stdio \ + -pflash bios.bin \ + disk.img \ + $@ ''; + + genodeGuest = pkgs.runCommand "nixos-vm" { preferLocalBuild = true; } '' + mkdir -p $out + + ln -s ${grubStandalone}/bootx64.efi $out/bootx64.efi + ln -s ${nixosVDI} $out/nixo.vdi + + cat > $out/README << EOF + # Installation instructions + + Copy the following UEFI boot image to the appropriate boot media: + + $out/bootx64.efi + + Copy the following disk image to an Ext2 partition with the partition type + ${import ./dhall/partition-type} + + EOF + ''; + }; }